summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjulian laplace <julescarbon@gmail.com>2023-05-08 23:49:29 +0200
committerjulian laplace <julescarbon@gmail.com>2023-05-08 23:49:29 +0200
commitb9dc2f677e7c3021aeeea6b1ab609a9b40806b48 (patch)
treec49c179515b2dce0784205e1d707f99d9ba6d0ee
parentcee4e2e53e1d7df114960daa78e7fd7b38e165b9 (diff)
v1 of relabi generator
-rw-r--r--.babelrc25
-rw-r--r--.gitignore1
-rw-r--r--dist/main.js2
-rw-r--r--index.html26
-rw-r--r--package.json12
-rw-r--r--src/index.js1
-rw-r--r--src/index.jsx16
-rw-r--r--src/lib/kalimba.js49
-rw-r--r--src/lib/output.js8
-rw-r--r--src/lib/startAudioContext.js180
-rw-r--r--src/lib/util.js63
-rw-r--r--src/relabi/index.js121
-rw-r--r--webpack.config.js22
-rw-r--r--yarn.lock1685
14 files changed, 2199 insertions, 12 deletions
diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..afa37c3
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,25 @@
+{
+ "presets": [
+ "@babel/preset-react",
+ [
+ "@babel/preset-env",
+ {
+ "targets": {
+ "browsers": "last 2 versions"
+ },
+ "modules": false,
+ "loose": false
+ }
+ ]
+ ],
+ "plugins": [
+ "transform-class-properties"
+ ],
+ "env": {
+ "test": {
+ "plugins": [
+ "transform-es2015-modules-commonjs"
+ ]
+ }
+ }
+}
diff --git a/.gitignore b/.gitignore
index a56a7ef..019f5f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
node_modules
+samples
diff --git a/dist/main.js b/dist/main.js
index ad86b2e..8f0641a 100644
--- a/dist/main.js
+++ b/dist/main.js
@@ -1 +1 @@
-console.log("hello"); \ No newline at end of file
+(()=>{var __webpack_modules__={382:function(__unused_webpack_module,exports,__webpack_require__){eval("(function (global, factory) {\n true ? factory(exports, __webpack_require__(424), __webpack_require__(690), __webpack_require__(728)) :\n 0;\n})(this, (function (exports, _slicedToArray, _classCallCheck, _createClass) { 'use strict';\n\n var createExtendedExponentialRampToValueAutomationEvent = function createExtendedExponentialRampToValueAutomationEvent(value, endTime, insertTime) {\n return {\n endTime: endTime,\n insertTime: insertTime,\n type: 'exponentialRampToValue',\n value: value\n };\n };\n\n var createExtendedLinearRampToValueAutomationEvent = function createExtendedLinearRampToValueAutomationEvent(value, endTime, insertTime) {\n return {\n endTime: endTime,\n insertTime: insertTime,\n type: 'linearRampToValue',\n value: value\n };\n };\n\n var createSetValueAutomationEvent = function createSetValueAutomationEvent(value, startTime) {\n return {\n startTime: startTime,\n type: 'setValue',\n value: value\n };\n };\n\n var createSetValueCurveAutomationEvent = function createSetValueCurveAutomationEvent(values, startTime, duration) {\n return {\n duration: duration,\n startTime: startTime,\n type: 'setValueCurve',\n values: values\n };\n };\n\n var getTargetValueAtTime = function getTargetValueAtTime(time, valueAtStartTime, _ref) {\n var startTime = _ref.startTime,\n target = _ref.target,\n timeConstant = _ref.timeConstant;\n return target + (valueAtStartTime - target) * Math.exp((startTime - time) / timeConstant);\n };\n\n var isExponentialRampToValueAutomationEvent = function isExponentialRampToValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'exponentialRampToValue';\n };\n\n var isLinearRampToValueAutomationEvent = function isLinearRampToValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'linearRampToValue';\n };\n\n var isAnyRampToValueAutomationEvent = function isAnyRampToValueAutomationEvent(automationEvent) {\n return isExponentialRampToValueAutomationEvent(automationEvent) || isLinearRampToValueAutomationEvent(automationEvent);\n };\n\n var isSetValueAutomationEvent = function isSetValueAutomationEvent(automationEvent) {\n return automationEvent.type === 'setValue';\n };\n\n var isSetValueCurveAutomationEvent = function isSetValueCurveAutomationEvent(automationEvent) {\n return automationEvent.type === 'setValueCurve';\n };\n\n var getValueOfAutomationEventAtIndexAtTime = function getValueOfAutomationEventAtIndexAtTime(automationEvents, index, time, defaultValue) {\n var automationEvent = automationEvents[index];\n return automationEvent === undefined ? defaultValue : isAnyRampToValueAutomationEvent(automationEvent) || isSetValueAutomationEvent(automationEvent) ? automationEvent.value : isSetValueCurveAutomationEvent(automationEvent) ? automationEvent.values[automationEvent.values.length - 1] : getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(automationEvents, index - 1, automationEvent.startTime, defaultValue), automationEvent);\n };\n\n var getEndTimeAndValueOfPreviousAutomationEvent = function getEndTimeAndValueOfPreviousAutomationEvent(automationEvents, index, currentAutomationEvent, nextAutomationEvent, defaultValue) {\n return currentAutomationEvent === undefined ? [nextAutomationEvent.insertTime, defaultValue] : isAnyRampToValueAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.endTime, currentAutomationEvent.value] : isSetValueAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.startTime, currentAutomationEvent.value] : isSetValueCurveAutomationEvent(currentAutomationEvent) ? [currentAutomationEvent.startTime + currentAutomationEvent.duration, currentAutomationEvent.values[currentAutomationEvent.values.length - 1]] : [currentAutomationEvent.startTime, getValueOfAutomationEventAtIndexAtTime(automationEvents, index - 1, currentAutomationEvent.startTime, defaultValue)];\n };\n\n var isCancelAndHoldAutomationEvent = function isCancelAndHoldAutomationEvent(automationEvent) {\n return automationEvent.type === 'cancelAndHold';\n };\n\n var isCancelScheduledValuesAutomationEvent = function isCancelScheduledValuesAutomationEvent(automationEvent) {\n return automationEvent.type === 'cancelScheduledValues';\n };\n\n var getEventTime = function getEventTime(automationEvent) {\n if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) {\n return automationEvent.cancelTime;\n }\n if (isExponentialRampToValueAutomationEvent(automationEvent) || isLinearRampToValueAutomationEvent(automationEvent)) {\n return automationEvent.endTime;\n }\n return automationEvent.startTime;\n };\n\n var getExponentialRampValueAtTime = function getExponentialRampValueAtTime(time, startTime, valueAtStartTime, _ref) {\n var endTime = _ref.endTime,\n value = _ref.value;\n if (valueAtStartTime === value) {\n return value;\n }\n if (0 < valueAtStartTime && 0 < value || valueAtStartTime < 0 && value < 0) {\n return valueAtStartTime * Math.pow(value / valueAtStartTime, (time - startTime) / (endTime - startTime));\n }\n return 0;\n };\n\n var getLinearRampValueAtTime = function getLinearRampValueAtTime(time, startTime, valueAtStartTime, _ref) {\n var endTime = _ref.endTime,\n value = _ref.value;\n return valueAtStartTime + (time - startTime) / (endTime - startTime) * (value - valueAtStartTime);\n };\n\n var interpolateValue = function interpolateValue(values, theoreticIndex) {\n var lowerIndex = Math.floor(theoreticIndex);\n var upperIndex = Math.ceil(theoreticIndex);\n if (lowerIndex === upperIndex) {\n return values[lowerIndex];\n }\n return (1 - (theoreticIndex - lowerIndex)) * values[lowerIndex] + (1 - (upperIndex - theoreticIndex)) * values[upperIndex];\n };\n\n var getValueCurveValueAtTime = function getValueCurveValueAtTime(time, _ref) {\n var duration = _ref.duration,\n startTime = _ref.startTime,\n values = _ref.values;\n var theoreticIndex = (time - startTime) / duration * (values.length - 1);\n return interpolateValue(values, theoreticIndex);\n };\n\n var isSetTargetAutomationEvent = function isSetTargetAutomationEvent(automationEvent) {\n return automationEvent.type === 'setTarget';\n };\n\n var AutomationEventList = /*#__PURE__*/function (_Symbol$iterator) {\n function AutomationEventList(defaultValue) {\n _classCallCheck(this, AutomationEventList);\n this._automationEvents = [];\n this._currenTime = 0;\n this._defaultValue = defaultValue;\n }\n _createClass(AutomationEventList, [{\n key: _Symbol$iterator,\n value: function value() {\n return this._automationEvents[Symbol.iterator]();\n }\n }, {\n key: \"add\",\n value: function add(automationEvent) {\n var eventTime = getEventTime(automationEvent);\n if (isCancelAndHoldAutomationEvent(automationEvent) || isCancelScheduledValuesAutomationEvent(automationEvent)) {\n var index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n if (isCancelScheduledValuesAutomationEvent(automationEvent) && isSetValueCurveAutomationEvent(currentAutomationEvent)) {\n return currentAutomationEvent.startTime + currentAutomationEvent.duration >= eventTime;\n }\n return getEventTime(currentAutomationEvent) >= eventTime;\n });\n var removedAutomationEvent = this._automationEvents[index];\n if (index !== -1) {\n this._automationEvents = this._automationEvents.slice(0, index);\n }\n if (isCancelAndHoldAutomationEvent(automationEvent)) {\n var lastAutomationEvent = this._automationEvents[this._automationEvents.length - 1];\n if (removedAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(removedAutomationEvent)) {\n if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) {\n throw new Error('The internal list is malformed.');\n }\n var startTime = lastAutomationEvent === undefined ? removedAutomationEvent.insertTime : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.startTime + lastAutomationEvent.duration : getEventTime(lastAutomationEvent);\n var startValue = lastAutomationEvent === undefined ? this._defaultValue : isSetValueCurveAutomationEvent(lastAutomationEvent) ? lastAutomationEvent.values[lastAutomationEvent.values.length - 1] : lastAutomationEvent.value;\n var value = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? getExponentialRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent) : getLinearRampValueAtTime(eventTime, startTime, startValue, removedAutomationEvent);\n var truncatedAutomationEvent = isExponentialRampToValueAutomationEvent(removedAutomationEvent) ? createExtendedExponentialRampToValueAutomationEvent(value, eventTime, this._currenTime) : createExtendedLinearRampToValueAutomationEvent(value, eventTime, this._currenTime);\n this._automationEvents.push(truncatedAutomationEvent);\n }\n if (lastAutomationEvent !== undefined && isSetTargetAutomationEvent(lastAutomationEvent)) {\n this._automationEvents.push(createSetValueAutomationEvent(this.getValue(eventTime), eventTime));\n }\n if (lastAutomationEvent !== undefined && isSetValueCurveAutomationEvent(lastAutomationEvent) && lastAutomationEvent.startTime + lastAutomationEvent.duration > eventTime) {\n var duration = eventTime - lastAutomationEvent.startTime;\n var ratio = (lastAutomationEvent.values.length - 1) / lastAutomationEvent.duration;\n var length = Math.max(2, 1 + Math.ceil(duration * ratio));\n var fraction = duration / (length - 1) * ratio;\n var values = lastAutomationEvent.values.slice(0, length);\n if (fraction < 1) {\n for (var i = 1; i < length; i += 1) {\n var factor = fraction * i % 1;\n values[i] = lastAutomationEvent.values[i - 1] * (1 - factor) + lastAutomationEvent.values[i] * factor;\n }\n }\n this._automationEvents[this._automationEvents.length - 1] = createSetValueCurveAutomationEvent(values, lastAutomationEvent.startTime, duration);\n }\n }\n } else {\n var _index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n return getEventTime(currentAutomationEvent) > eventTime;\n });\n var previousAutomationEvent = _index === -1 ? this._automationEvents[this._automationEvents.length - 1] : this._automationEvents[_index - 1];\n if (previousAutomationEvent !== undefined && isSetValueCurveAutomationEvent(previousAutomationEvent) && getEventTime(previousAutomationEvent) + previousAutomationEvent.duration > eventTime) {\n return false;\n }\n var persistentAutomationEvent = isExponentialRampToValueAutomationEvent(automationEvent) ? createExtendedExponentialRampToValueAutomationEvent(automationEvent.value, automationEvent.endTime, this._currenTime) : isLinearRampToValueAutomationEvent(automationEvent) ? createExtendedLinearRampToValueAutomationEvent(automationEvent.value, eventTime, this._currenTime) : automationEvent;\n if (_index === -1) {\n this._automationEvents.push(persistentAutomationEvent);\n } else {\n if (isSetValueCurveAutomationEvent(automationEvent) && eventTime + automationEvent.duration > getEventTime(this._automationEvents[_index])) {\n return false;\n }\n this._automationEvents.splice(_index, 0, persistentAutomationEvent);\n }\n }\n return true;\n }\n }, {\n key: \"flush\",\n value: function flush(time) {\n var index = this._automationEvents.findIndex(function (currentAutomationEvent) {\n return getEventTime(currentAutomationEvent) > time;\n });\n if (index > 1) {\n var remainingAutomationEvents = this._automationEvents.slice(index - 1);\n var firstRemainingAutomationEvent = remainingAutomationEvents[0];\n if (isSetTargetAutomationEvent(firstRemainingAutomationEvent)) {\n remainingAutomationEvents.unshift(createSetValueAutomationEvent(getValueOfAutomationEventAtIndexAtTime(this._automationEvents, index - 2, firstRemainingAutomationEvent.startTime, this._defaultValue), firstRemainingAutomationEvent.startTime));\n }\n this._automationEvents = remainingAutomationEvents;\n }\n }\n }, {\n key: \"getValue\",\n value: function getValue(time) {\n if (this._automationEvents.length === 0) {\n return this._defaultValue;\n }\n var indexOfNextEvent = this._automationEvents.findIndex(function (automationEvent) {\n return getEventTime(automationEvent) > time;\n });\n var nextAutomationEvent = this._automationEvents[indexOfNextEvent];\n var indexOfCurrentEvent = (indexOfNextEvent === -1 ? this._automationEvents.length : indexOfNextEvent) - 1;\n var currentAutomationEvent = this._automationEvents[indexOfCurrentEvent];\n if (currentAutomationEvent !== undefined && isSetTargetAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || nextAutomationEvent.insertTime > time)) {\n return getTargetValueAtTime(time, getValueOfAutomationEventAtIndexAtTime(this._automationEvents, indexOfCurrentEvent - 1, currentAutomationEvent.startTime, this._defaultValue), currentAutomationEvent);\n }\n if (currentAutomationEvent !== undefined && isSetValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) {\n return currentAutomationEvent.value;\n }\n if (currentAutomationEvent !== undefined && isSetValueCurveAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent) || currentAutomationEvent.startTime + currentAutomationEvent.duration > time)) {\n if (time < currentAutomationEvent.startTime + currentAutomationEvent.duration) {\n return getValueCurveValueAtTime(time, currentAutomationEvent);\n }\n return currentAutomationEvent.values[currentAutomationEvent.values.length - 1];\n }\n if (currentAutomationEvent !== undefined && isAnyRampToValueAutomationEvent(currentAutomationEvent) && (nextAutomationEvent === undefined || !isAnyRampToValueAutomationEvent(nextAutomationEvent))) {\n return currentAutomationEvent.value;\n }\n if (nextAutomationEvent !== undefined && isExponentialRampToValueAutomationEvent(nextAutomationEvent)) {\n var _getEndTimeAndValueOf = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue),\n _getEndTimeAndValueOf2 = _slicedToArray(_getEndTimeAndValueOf, 2),\n startTime = _getEndTimeAndValueOf2[0],\n value = _getEndTimeAndValueOf2[1];\n return getExponentialRampValueAtTime(time, startTime, value, nextAutomationEvent);\n }\n if (nextAutomationEvent !== undefined && isLinearRampToValueAutomationEvent(nextAutomationEvent)) {\n var _getEndTimeAndValueOf3 = getEndTimeAndValueOfPreviousAutomationEvent(this._automationEvents, indexOfCurrentEvent, currentAutomationEvent, nextAutomationEvent, this._defaultValue),\n _getEndTimeAndValueOf4 = _slicedToArray(_getEndTimeAndValueOf3, 2),\n _startTime = _getEndTimeAndValueOf4[0],\n _value = _getEndTimeAndValueOf4[1];\n return getLinearRampValueAtTime(time, _startTime, _value, nextAutomationEvent);\n }\n return this._defaultValue;\n }\n }]);\n return AutomationEventList;\n }(Symbol.iterator);\n\n var createCancelAndHoldAutomationEvent = function createCancelAndHoldAutomationEvent(cancelTime) {\n return {\n cancelTime: cancelTime,\n type: 'cancelAndHold'\n };\n };\n\n var createCancelScheduledValuesAutomationEvent = function createCancelScheduledValuesAutomationEvent(cancelTime) {\n return {\n cancelTime: cancelTime,\n type: 'cancelScheduledValues'\n };\n };\n\n var createExponentialRampToValueAutomationEvent = function createExponentialRampToValueAutomationEvent(value, endTime) {\n return {\n endTime: endTime,\n type: 'exponentialRampToValue',\n value: value\n };\n };\n\n var createLinearRampToValueAutomationEvent = function createLinearRampToValueAutomationEvent(value, endTime) {\n return {\n endTime: endTime,\n type: 'linearRampToValue',\n value: value\n };\n };\n\n var createSetTargetAutomationEvent = function createSetTargetAutomationEvent(target, startTime, timeConstant) {\n return {\n startTime: startTime,\n target: target,\n timeConstant: timeConstant,\n type: 'setTarget'\n };\n };\n\n exports.AutomationEventList = AutomationEventList;\n exports.createCancelAndHoldAutomationEvent = createCancelAndHoldAutomationEvent;\n exports.createCancelScheduledValuesAutomationEvent = createCancelScheduledValuesAutomationEvent;\n exports.createExponentialRampToValueAutomationEvent = createExponentialRampToValueAutomationEvent;\n exports.createLinearRampToValueAutomationEvent = createLinearRampToValueAutomationEvent;\n exports.createSetTargetAutomationEvent = createSetTargetAutomationEvent;\n exports.createSetValueAutomationEvent = createSetValueAutomationEvent;\n exports.createSetValueCurveAutomationEvent = createSetValueCurveAutomationEvent;\n\n}));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzgyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0EsSUFBSSxLQUE0RCxvQkFBb0IsbUJBQU8sQ0FBQyxHQUFzQyxHQUFHLG1CQUFPLENBQUMsR0FBdUMsR0FBRyxtQkFBTyxDQUFDLEdBQW9DO0FBQ25PLElBQUksQ0FDcUw7QUFDekwsQ0FBQyw2RUFBNkU7O0FBRTlFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFlBQVk7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9hdXRvbWF0aW9uLWV2ZW50cy9idWlsZC9lczUvYnVuZGxlLmpzPzA0ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMsIHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvc2xpY2VkVG9BcnJheScpLCByZXF1aXJlKCdAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrJyksIHJlcXVpcmUoJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3MnKSkgOlxuICAgIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnLCAnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5JywgJ0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2snLCAnQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcyddLCBmYWN0b3J5KSA6XG4gICAgKGdsb2JhbCA9IHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbFRoaXMgOiBnbG9iYWwgfHwgc2VsZiwgZmFjdG9yeShnbG9iYWwuYXV0b21hdGlvbkV2ZW50cyA9IHt9LCBnbG9iYWwuX3NsaWNlZFRvQXJyYXksIGdsb2JhbC5fY2xhc3NDYWxsQ2hlY2ssIGdsb2JhbC5fY3JlYXRlQ2xhc3MpKTtcbn0pKHRoaXMsIChmdW5jdGlvbiAoZXhwb3J0cywgX3NsaWNlZFRvQXJyYXksIF9jbGFzc0NhbGxDaGVjaywgX2NyZWF0ZUNsYXNzKSB7ICd1c2Ugc3RyaWN0JztcblxuICAgIHZhciBjcmVhdGVFeHRlbmRlZEV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVFeHRlbmRlZEV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUsIGluc2VydFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgIGluc2VydFRpbWU6IGluc2VydFRpbWUsXG4gICAgICAgIHR5cGU6ICdleHBvbmVudGlhbFJhbXBUb1ZhbHVlJyxcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICB9O1xuICAgIH07XG5cbiAgICB2YXIgY3JlYXRlRXh0ZW5kZWRMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGNyZWF0ZUV4dGVuZGVkTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUsIGluc2VydFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgIGluc2VydFRpbWU6IGluc2VydFRpbWUsXG4gICAgICAgIHR5cGU6ICdsaW5lYXJSYW1wVG9WYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIHN0YXJ0VGltZSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnRUaW1lOiBzdGFydFRpbWUsXG4gICAgICAgIHR5cGU6ICdzZXRWYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZHVyYXRpb246IGR1cmF0aW9uLFxuICAgICAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICAgICAgdHlwZTogJ3NldFZhbHVlQ3VydmUnLFxuICAgICAgICB2YWx1ZXM6IHZhbHVlc1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGdldFRhcmdldFZhbHVlQXRUaW1lID0gZnVuY3Rpb24gZ2V0VGFyZ2V0VmFsdWVBdFRpbWUodGltZSwgdmFsdWVBdFN0YXJ0VGltZSwgX3JlZikge1xuICAgICAgdmFyIHN0YXJ0VGltZSA9IF9yZWYuc3RhcnRUaW1lLFxuICAgICAgICB0YXJnZXQgPSBfcmVmLnRhcmdldCxcbiAgICAgICAgdGltZUNvbnN0YW50ID0gX3JlZi50aW1lQ29uc3RhbnQ7XG4gICAgICByZXR1cm4gdGFyZ2V0ICsgKHZhbHVlQXRTdGFydFRpbWUgLSB0YXJnZXQpICogTWF0aC5leHAoKHN0YXJ0VGltZSAtIHRpbWUpIC8gdGltZUNvbnN0YW50KTtcbiAgICB9O1xuXG4gICAgdmFyIGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWUnO1xuICAgIH07XG5cbiAgICB2YXIgaXNMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdsaW5lYXJSYW1wVG9WYWx1ZSc7XG4gICAgfTtcblxuICAgIHZhciBpc0FueVJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBpc0V4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSB8fCBpc0xpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCk7XG4gICAgfTtcblxuICAgIHZhciBpc1NldFZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gaXNTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJztcbiAgICB9O1xuXG4gICAgdmFyIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlQ3VydmUnO1xuICAgIH07XG5cbiAgICB2YXIgZ2V0VmFsdWVPZkF1dG9tYXRpb25FdmVudEF0SW5kZXhBdFRpbWUgPSBmdW5jdGlvbiBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZShhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCwgdGltZSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICB2YXIgYXV0b21hdGlvbkV2ZW50ID0gYXV0b21hdGlvbkV2ZW50c1tpbmRleF07XG4gICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50ID09PSB1bmRlZmluZWQgPyBkZWZhdWx0VmFsdWUgOiBpc0FueVJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgfHwgaXNTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpID8gYXV0b21hdGlvbkV2ZW50LnZhbHVlIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgPyBhdXRvbWF0aW9uRXZlbnQudmFsdWVzW2F1dG9tYXRpb25FdmVudC52YWx1ZXMubGVuZ3RoIC0gMV0gOiBnZXRUYXJnZXRWYWx1ZUF0VGltZSh0aW1lLCBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZShhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCAtIDEsIGF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIGRlZmF1bHRWYWx1ZSksIGF1dG9tYXRpb25FdmVudCk7XG4gICAgfTtcblxuICAgIHZhciBnZXRFbmRUaW1lQW5kVmFsdWVPZlByZXZpb3VzQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gZ2V0RW5kVGltZUFuZFZhbHVlT2ZQcmV2aW91c0F1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCwgY3VycmVudEF1dG9tYXRpb25FdmVudCwgbmV4dEF1dG9tYXRpb25FdmVudCwgZGVmYXVsdFZhbHVlKSB7XG4gICAgICByZXR1cm4gY3VycmVudEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkID8gW25leHRBdXRvbWF0aW9uRXZlbnQuaW5zZXJ0VGltZSwgZGVmYXVsdFZhbHVlXSA6IGlzQW55UmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgPyBbY3VycmVudEF1dG9tYXRpb25FdmVudC5lbmRUaW1lLCBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnZhbHVlXSA6IGlzU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgPyBbY3VycmVudEF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQudmFsdWVdIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpID8gW2N1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgY3VycmVudEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbiwgY3VycmVudEF1dG9tYXRpb25FdmVudC52YWx1ZXNbY3VycmVudEF1dG9tYXRpb25FdmVudC52YWx1ZXMubGVuZ3RoIC0gMV1dIDogW2N1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lLCBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZShhdXRvbWF0aW9uRXZlbnRzLCBpbmRleCAtIDEsIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lLCBkZWZhdWx0VmFsdWUpXTtcbiAgICB9O1xuXG4gICAgdmFyIGlzQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGlzQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2NhbmNlbEFuZEhvbGQnO1xuICAgIH07XG5cbiAgICB2YXIgaXNDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBpc0NhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2NhbmNlbFNjaGVkdWxlZFZhbHVlcyc7XG4gICAgfTtcblxuICAgIHZhciBnZXRFdmVudFRpbWUgPSBmdW5jdGlvbiBnZXRFdmVudFRpbWUoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICBpZiAoaXNDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgfHwgaXNDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50LmNhbmNlbFRpbWU7XG4gICAgICB9XG4gICAgICBpZiAoaXNFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgfHwgaXNMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpKSB7XG4gICAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQuZW5kVGltZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lO1xuICAgIH07XG5cbiAgICB2YXIgZ2V0RXhwb25lbnRpYWxSYW1wVmFsdWVBdFRpbWUgPSBmdW5jdGlvbiBnZXRFeHBvbmVudGlhbFJhbXBWYWx1ZUF0VGltZSh0aW1lLCBzdGFydFRpbWUsIHZhbHVlQXRTdGFydFRpbWUsIF9yZWYpIHtcbiAgICAgIHZhciBlbmRUaW1lID0gX3JlZi5lbmRUaW1lLFxuICAgICAgICB2YWx1ZSA9IF9yZWYudmFsdWU7XG4gICAgICBpZiAodmFsdWVBdFN0YXJ0VGltZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfVxuICAgICAgaWYgKDAgPCB2YWx1ZUF0U3RhcnRUaW1lICYmIDAgPCB2YWx1ZSB8fCB2YWx1ZUF0U3RhcnRUaW1lIDwgMCAmJiB2YWx1ZSA8IDApIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlQXRTdGFydFRpbWUgKiBNYXRoLnBvdyh2YWx1ZSAvIHZhbHVlQXRTdGFydFRpbWUsICh0aW1lIC0gc3RhcnRUaW1lKSAvIChlbmRUaW1lIC0gc3RhcnRUaW1lKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9O1xuXG4gICAgdmFyIGdldExpbmVhclJhbXBWYWx1ZUF0VGltZSA9IGZ1bmN0aW9uIGdldExpbmVhclJhbXBWYWx1ZUF0VGltZSh0aW1lLCBzdGFydFRpbWUsIHZhbHVlQXRTdGFydFRpbWUsIF9yZWYpIHtcbiAgICAgIHZhciBlbmRUaW1lID0gX3JlZi5lbmRUaW1lLFxuICAgICAgICB2YWx1ZSA9IF9yZWYudmFsdWU7XG4gICAgICByZXR1cm4gdmFsdWVBdFN0YXJ0VGltZSArICh0aW1lIC0gc3RhcnRUaW1lKSAvIChlbmRUaW1lIC0gc3RhcnRUaW1lKSAqICh2YWx1ZSAtIHZhbHVlQXRTdGFydFRpbWUpO1xuICAgIH07XG5cbiAgICB2YXIgaW50ZXJwb2xhdGVWYWx1ZSA9IGZ1bmN0aW9uIGludGVycG9sYXRlVmFsdWUodmFsdWVzLCB0aGVvcmV0aWNJbmRleCkge1xuICAgICAgdmFyIGxvd2VySW5kZXggPSBNYXRoLmZsb29yKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgIHZhciB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgIGlmIChsb3dlckluZGV4ID09PSB1cHBlckluZGV4KSB7XG4gICAgICAgIHJldHVybiB2YWx1ZXNbbG93ZXJJbmRleF07XG4gICAgICB9XG4gICAgICByZXR1cm4gKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZXNbbG93ZXJJbmRleF0gKyAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIHZhbHVlc1t1cHBlckluZGV4XTtcbiAgICB9O1xuXG4gICAgdmFyIGdldFZhbHVlQ3VydmVWYWx1ZUF0VGltZSA9IGZ1bmN0aW9uIGdldFZhbHVlQ3VydmVWYWx1ZUF0VGltZSh0aW1lLCBfcmVmKSB7XG4gICAgICB2YXIgZHVyYXRpb24gPSBfcmVmLmR1cmF0aW9uLFxuICAgICAgICBzdGFydFRpbWUgPSBfcmVmLnN0YXJ0VGltZSxcbiAgICAgICAgdmFsdWVzID0gX3JlZi52YWx1ZXM7XG4gICAgICB2YXIgdGhlb3JldGljSW5kZXggPSAodGltZSAtIHN0YXJ0VGltZSkgLyBkdXJhdGlvbiAqICh2YWx1ZXMubGVuZ3RoIC0gMSk7XG4gICAgICByZXR1cm4gaW50ZXJwb2xhdGVWYWx1ZSh2YWx1ZXMsIHRoZW9yZXRpY0luZGV4KTtcbiAgICB9O1xuXG4gICAgdmFyIGlzU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gaXNTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICByZXR1cm4gYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRUYXJnZXQnO1xuICAgIH07XG5cbiAgICB2YXIgQXV0b21hdGlvbkV2ZW50TGlzdCA9IC8qI19fUFVSRV9fKi9mdW5jdGlvbiAoX1N5bWJvbCRpdGVyYXRvcikge1xuICAgICAgZnVuY3Rpb24gQXV0b21hdGlvbkV2ZW50TGlzdChkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEF1dG9tYXRpb25FdmVudExpc3QpO1xuICAgICAgICB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzID0gW107XG4gICAgICAgIHRoaXMuX2N1cnJlblRpbWUgPSAwO1xuICAgICAgICB0aGlzLl9kZWZhdWx0VmFsdWUgPSBkZWZhdWx0VmFsdWU7XG4gICAgICB9XG4gICAgICBfY3JlYXRlQ2xhc3MoQXV0b21hdGlvbkV2ZW50TGlzdCwgW3tcbiAgICAgICAga2V5OiBfU3ltYm9sJGl0ZXJhdG9yLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdmFsdWUoKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2F1dG9tYXRpb25FdmVudHNbU3ltYm9sLml0ZXJhdG9yXSgpO1xuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGtleTogXCJhZGRcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGFkZChhdXRvbWF0aW9uRXZlbnQpIHtcbiAgICAgICAgICB2YXIgZXZlbnRUaW1lID0gZ2V0RXZlbnRUaW1lKGF1dG9tYXRpb25FdmVudCk7XG4gICAgICAgICAgaWYgKGlzQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpIHx8IGlzQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkpIHtcbiAgICAgICAgICAgIHZhciBpbmRleCA9IHRoaXMuX2F1dG9tYXRpb25FdmVudHMuZmluZEluZGV4KGZ1bmN0aW9uIChjdXJyZW50QXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICAgICAgICAgIGlmIChpc0NhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChhdXRvbWF0aW9uRXZlbnQpICYmIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChjdXJyZW50QXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnN0YXJ0VGltZSArIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuZHVyYXRpb24gPj0gZXZlbnRUaW1lO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBnZXRFdmVudFRpbWUoY3VycmVudEF1dG9tYXRpb25FdmVudCkgPj0gZXZlbnRUaW1lO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcmVtb3ZlZEF1dG9tYXRpb25FdmVudCA9IHRoaXMuX2F1dG9tYXRpb25FdmVudHNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzID0gdGhpcy5fYXV0b21hdGlvbkV2ZW50cy5zbGljZSgwLCBpbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkpIHtcbiAgICAgICAgICAgICAgdmFyIGxhc3RBdXRvbWF0aW9uRXZlbnQgPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzW3RoaXMuX2F1dG9tYXRpb25FdmVudHMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgIGlmIChyZW1vdmVkQXV0b21hdGlvbkV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChyZW1vdmVkQXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGlmIChsYXN0QXV0b21hdGlvbkV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaXNTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQobGFzdEF1dG9tYXRpb25FdmVudCkpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGludGVybmFsIGxpc3QgaXMgbWFsZm9ybWVkLicpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgc3RhcnRUaW1lID0gbGFzdEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkID8gcmVtb3ZlZEF1dG9tYXRpb25FdmVudC5pbnNlcnRUaW1lIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGxhc3RBdXRvbWF0aW9uRXZlbnQpID8gbGFzdEF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUgKyBsYXN0QXV0b21hdGlvbkV2ZW50LmR1cmF0aW9uIDogZ2V0RXZlbnRUaW1lKGxhc3RBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgICAgICAgIHZhciBzdGFydFZhbHVlID0gbGFzdEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkID8gdGhpcy5fZGVmYXVsdFZhbHVlIDogaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGxhc3RBdXRvbWF0aW9uRXZlbnQpID8gbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXNbbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXMubGVuZ3RoIC0gMV0gOiBsYXN0QXV0b21hdGlvbkV2ZW50LnZhbHVlO1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChyZW1vdmVkQXV0b21hdGlvbkV2ZW50KSA/IGdldEV4cG9uZW50aWFsUmFtcFZhbHVlQXRUaW1lKGV2ZW50VGltZSwgc3RhcnRUaW1lLCBzdGFydFZhbHVlLCByZW1vdmVkQXV0b21hdGlvbkV2ZW50KSA6IGdldExpbmVhclJhbXBWYWx1ZUF0VGltZShldmVudFRpbWUsIHN0YXJ0VGltZSwgc3RhcnRWYWx1ZSwgcmVtb3ZlZEF1dG9tYXRpb25FdmVudCk7XG4gICAgICAgICAgICAgICAgdmFyIHRydW5jYXRlZEF1dG9tYXRpb25FdmVudCA9IGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChyZW1vdmVkQXV0b21hdGlvbkV2ZW50KSA/IGNyZWF0ZUV4dGVuZGVkRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZXZlbnRUaW1lLCB0aGlzLl9jdXJyZW5UaW1lKSA6IGNyZWF0ZUV4dGVuZGVkTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGV2ZW50VGltZSwgdGhpcy5fY3VycmVuVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXV0b21hdGlvbkV2ZW50cy5wdXNoKHRydW5jYXRlZEF1dG9tYXRpb25FdmVudCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGxhc3RBdXRvbWF0aW9uRXZlbnQgIT09IHVuZGVmaW5lZCAmJiBpc1NldFRhcmdldEF1dG9tYXRpb25FdmVudChsYXN0QXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1dG9tYXRpb25FdmVudHMucHVzaChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCh0aGlzLmdldFZhbHVlKGV2ZW50VGltZSksIGV2ZW50VGltZSkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChsYXN0QXV0b21hdGlvbkV2ZW50ICE9PSB1bmRlZmluZWQgJiYgaXNTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGxhc3RBdXRvbWF0aW9uRXZlbnQpICYmIGxhc3RBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgbGFzdEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbiA+IGV2ZW50VGltZSkge1xuICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbiA9IGV2ZW50VGltZSAtIGxhc3RBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lO1xuICAgICAgICAgICAgICAgIHZhciByYXRpbyA9IChsYXN0QXV0b21hdGlvbkV2ZW50LnZhbHVlcy5sZW5ndGggLSAxKSAvIGxhc3RBdXRvbWF0aW9uRXZlbnQuZHVyYXRpb247XG4gICAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IE1hdGgubWF4KDIsIDEgKyBNYXRoLmNlaWwoZHVyYXRpb24gKiByYXRpbykpO1xuICAgICAgICAgICAgICAgIHZhciBmcmFjdGlvbiA9IGR1cmF0aW9uIC8gKGxlbmd0aCAtIDEpICogcmF0aW87XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IGxhc3RBdXRvbWF0aW9uRXZlbnQudmFsdWVzLnNsaWNlKDAsIGxlbmd0aCk7XG4gICAgICAgICAgICAgICAgaWYgKGZyYWN0aW9uIDwgMSkge1xuICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgZmFjdG9yID0gZnJhY3Rpb24gKiBpICUgMTtcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2ldID0gbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXNbaSAtIDFdICogKDEgLSBmYWN0b3IpICsgbGFzdEF1dG9tYXRpb25FdmVudC52YWx1ZXNbaV0gKiBmYWN0b3I7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2F1dG9tYXRpb25FdmVudHNbdGhpcy5fYXV0b21hdGlvbkV2ZW50cy5sZW5ndGggLSAxXSA9IGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQodmFsdWVzLCBsYXN0QXV0b21hdGlvbkV2ZW50LnN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBfaW5kZXggPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmZpbmRJbmRleChmdW5jdGlvbiAoY3VycmVudEF1dG9tYXRpb25FdmVudCkge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0RXZlbnRUaW1lKGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpID4gZXZlbnRUaW1lO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcHJldmlvdXNBdXRvbWF0aW9uRXZlbnQgPSBfaW5kZXggPT09IC0xID8gdGhpcy5fYXV0b21hdGlvbkV2ZW50c1t0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmxlbmd0aCAtIDFdIDogdGhpcy5fYXV0b21hdGlvbkV2ZW50c1tfaW5kZXggLSAxXTtcbiAgICAgICAgICAgIGlmIChwcmV2aW91c0F1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChwcmV2aW91c0F1dG9tYXRpb25FdmVudCkgJiYgZ2V0RXZlbnRUaW1lKHByZXZpb3VzQXV0b21hdGlvbkV2ZW50KSArIHByZXZpb3VzQXV0b21hdGlvbkV2ZW50LmR1cmF0aW9uID4gZXZlbnRUaW1lKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwZXJzaXN0ZW50QXV0b21hdGlvbkV2ZW50ID0gaXNFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgPyBjcmVhdGVFeHRlbmRlZEV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50LnZhbHVlLCBhdXRvbWF0aW9uRXZlbnQuZW5kVGltZSwgdGhpcy5fY3VycmVuVGltZSkgOiBpc0xpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudCkgPyBjcmVhdGVFeHRlbmRlZExpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KGF1dG9tYXRpb25FdmVudC52YWx1ZSwgZXZlbnRUaW1lLCB0aGlzLl9jdXJyZW5UaW1lKSA6IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgIGlmIChfaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICAgIHRoaXMuX2F1dG9tYXRpb25FdmVudHMucHVzaChwZXJzaXN0ZW50QXV0b21hdGlvbkV2ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChpc1NldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoYXV0b21hdGlvbkV2ZW50KSAmJiBldmVudFRpbWUgKyBhdXRvbWF0aW9uRXZlbnQuZHVyYXRpb24gPiBnZXRFdmVudFRpbWUodGhpcy5fYXV0b21hdGlvbkV2ZW50c1tfaW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLnNwbGljZShfaW5kZXgsIDAsIHBlcnNpc3RlbnRBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSwge1xuICAgICAgICBrZXk6IFwiZmx1c2hcIixcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGZsdXNoKHRpbWUpIHtcbiAgICAgICAgICB2YXIgaW5kZXggPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmZpbmRJbmRleChmdW5jdGlvbiAoY3VycmVudEF1dG9tYXRpb25FdmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGdldEV2ZW50VGltZShjdXJyZW50QXV0b21hdGlvbkV2ZW50KSA+IHRpbWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gMSkge1xuICAgICAgICAgICAgdmFyIHJlbWFpbmluZ0F1dG9tYXRpb25FdmVudHMgPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLnNsaWNlKGluZGV4IC0gMSk7XG4gICAgICAgICAgICB2YXIgZmlyc3RSZW1haW5pbmdBdXRvbWF0aW9uRXZlbnQgPSByZW1haW5pbmdBdXRvbWF0aW9uRXZlbnRzWzBdO1xuICAgICAgICAgICAgaWYgKGlzU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50KGZpcnN0UmVtYWluaW5nQXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgICByZW1haW5pbmdBdXRvbWF0aW9uRXZlbnRzLnVuc2hpZnQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoZ2V0VmFsdWVPZkF1dG9tYXRpb25FdmVudEF0SW5kZXhBdFRpbWUodGhpcy5fYXV0b21hdGlvbkV2ZW50cywgaW5kZXggLSAyLCBmaXJzdFJlbWFpbmluZ0F1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIHRoaXMuX2RlZmF1bHRWYWx1ZSksIGZpcnN0UmVtYWluaW5nQXV0b21hdGlvbkV2ZW50LnN0YXJ0VGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYXV0b21hdGlvbkV2ZW50cyA9IHJlbWFpbmluZ0F1dG9tYXRpb25FdmVudHM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIGtleTogXCJnZXRWYWx1ZVwiLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gZ2V0VmFsdWUodGltZSkge1xuICAgICAgICAgIGlmICh0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIGluZGV4T2ZOZXh0RXZlbnQgPSB0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLmZpbmRJbmRleChmdW5jdGlvbiAoYXV0b21hdGlvbkV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0RXZlbnRUaW1lKGF1dG9tYXRpb25FdmVudCkgPiB0aW1lO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHZhciBuZXh0QXV0b21hdGlvbkV2ZW50ID0gdGhpcy5fYXV0b21hdGlvbkV2ZW50c1tpbmRleE9mTmV4dEV2ZW50XTtcbiAgICAgICAgICB2YXIgaW5kZXhPZkN1cnJlbnRFdmVudCA9IChpbmRleE9mTmV4dEV2ZW50ID09PSAtMSA/IHRoaXMuX2F1dG9tYXRpb25FdmVudHMubGVuZ3RoIDogaW5kZXhPZk5leHRFdmVudCkgLSAxO1xuICAgICAgICAgIHZhciBjdXJyZW50QXV0b21hdGlvbkV2ZW50ID0gdGhpcy5fYXV0b21hdGlvbkV2ZW50c1tpbmRleE9mQ3VycmVudEV2ZW50XTtcbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50KGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpICYmIChuZXh0QXV0b21hdGlvbkV2ZW50ID09PSB1bmRlZmluZWQgfHwgIWlzQW55UmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQobmV4dEF1dG9tYXRpb25FdmVudCkgfHwgbmV4dEF1dG9tYXRpb25FdmVudC5pbnNlcnRUaW1lID4gdGltZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRUYXJnZXRWYWx1ZUF0VGltZSh0aW1lLCBnZXRWYWx1ZU9mQXV0b21hdGlvbkV2ZW50QXRJbmRleEF0VGltZSh0aGlzLl9hdXRvbWF0aW9uRXZlbnRzLCBpbmRleE9mQ3VycmVudEV2ZW50IC0gMSwgY3VycmVudEF1dG9tYXRpb25FdmVudC5zdGFydFRpbWUsIHRoaXMuX2RlZmF1bHRWYWx1ZSksIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgJiYgKG5leHRBdXRvbWF0aW9uRXZlbnQgPT09IHVuZGVmaW5lZCB8fCAhaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChuZXh0QXV0b21hdGlvbkV2ZW50KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChjdXJyZW50QXV0b21hdGlvbkV2ZW50KSAmJiAobmV4dEF1dG9tYXRpb25FdmVudCA9PT0gdW5kZWZpbmVkIHx8ICFpc0FueVJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KG5leHRBdXRvbWF0aW9uRXZlbnQpIHx8IGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgY3VycmVudEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbiA+IHRpbWUpKSB7XG4gICAgICAgICAgICBpZiAodGltZSA8IGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQuc3RhcnRUaW1lICsgY3VycmVudEF1dG9tYXRpb25FdmVudC5kdXJhdGlvbikge1xuICAgICAgICAgICAgICByZXR1cm4gZ2V0VmFsdWVDdXJ2ZVZhbHVlQXRUaW1lKHRpbWUsIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRBdXRvbWF0aW9uRXZlbnQudmFsdWVzW2N1cnJlbnRBdXRvbWF0aW9uRXZlbnQudmFsdWVzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoY3VycmVudEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzQW55UmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQoY3VycmVudEF1dG9tYXRpb25FdmVudCkgJiYgKG5leHRBdXRvbWF0aW9uRXZlbnQgPT09IHVuZGVmaW5lZCB8fCAhaXNBbnlSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChuZXh0QXV0b21hdGlvbkV2ZW50KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50QXV0b21hdGlvbkV2ZW50LnZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAobmV4dEF1dG9tYXRpb25FdmVudCAhPT0gdW5kZWZpbmVkICYmIGlzRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudChuZXh0QXV0b21hdGlvbkV2ZW50KSkge1xuICAgICAgICAgICAgdmFyIF9nZXRFbmRUaW1lQW5kVmFsdWVPZiA9IGdldEVuZFRpbWVBbmRWYWx1ZU9mUHJldmlvdXNBdXRvbWF0aW9uRXZlbnQodGhpcy5fYXV0b21hdGlvbkV2ZW50cywgaW5kZXhPZkN1cnJlbnRFdmVudCwgY3VycmVudEF1dG9tYXRpb25FdmVudCwgbmV4dEF1dG9tYXRpb25FdmVudCwgdGhpcy5fZGVmYXVsdFZhbHVlKSxcbiAgICAgICAgICAgICAgX2dldEVuZFRpbWVBbmRWYWx1ZU9mMiA9IF9zbGljZWRUb0FycmF5KF9nZXRFbmRUaW1lQW5kVmFsdWVPZiwgMiksXG4gICAgICAgICAgICAgIHN0YXJ0VGltZSA9IF9nZXRFbmRUaW1lQW5kVmFsdWVPZjJbMF0sXG4gICAgICAgICAgICAgIHZhbHVlID0gX2dldEVuZFRpbWVBbmRWYWx1ZU9mMlsxXTtcbiAgICAgICAgICAgIHJldHVybiBnZXRFeHBvbmVudGlhbFJhbXBWYWx1ZUF0VGltZSh0aW1lLCBzdGFydFRpbWUsIHZhbHVlLCBuZXh0QXV0b21hdGlvbkV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG5leHRBdXRvbWF0aW9uRXZlbnQgIT09IHVuZGVmaW5lZCAmJiBpc0xpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KG5leHRBdXRvbWF0aW9uRXZlbnQpKSB7XG4gICAgICAgICAgICB2YXIgX2dldEVuZFRpbWVBbmRWYWx1ZU9mMyA9IGdldEVuZFRpbWVBbmRWYWx1ZU9mUHJldmlvdXNBdXRvbWF0aW9uRXZlbnQodGhpcy5fYXV0b21hdGlvbkV2ZW50cywgaW5kZXhPZkN1cnJlbnRFdmVudCwgY3VycmVudEF1dG9tYXRpb25FdmVudCwgbmV4dEF1dG9tYXRpb25FdmVudCwgdGhpcy5fZGVmYXVsdFZhbHVlKSxcbiAgICAgICAgICAgICAgX2dldEVuZFRpbWVBbmRWYWx1ZU9mNCA9IF9zbGljZWRUb0FycmF5KF9nZXRFbmRUaW1lQW5kVmFsdWVPZjMsIDIpLFxuICAgICAgICAgICAgICBfc3RhcnRUaW1lID0gX2dldEVuZFRpbWVBbmRWYWx1ZU9mNFswXSxcbiAgICAgICAgICAgICAgX3ZhbHVlID0gX2dldEVuZFRpbWVBbmRWYWx1ZU9mNFsxXTtcbiAgICAgICAgICAgIHJldHVybiBnZXRMaW5lYXJSYW1wVmFsdWVBdFRpbWUodGltZSwgX3N0YXJ0VGltZSwgX3ZhbHVlLCBuZXh0QXV0b21hdGlvbkV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgfV0pO1xuICAgICAgcmV0dXJuIEF1dG9tYXRpb25FdmVudExpc3Q7XG4gICAgfShTeW1ib2wuaXRlcmF0b3IpO1xuXG4gICAgdmFyIGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNhbmNlbFRpbWU6IGNhbmNlbFRpbWUsXG4gICAgICAgIHR5cGU6ICdjYW5jZWxBbmRIb2xkJ1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjYW5jZWxUaW1lOiBjYW5jZWxUaW1lLFxuICAgICAgICB0eXBlOiAnY2FuY2VsU2NoZWR1bGVkVmFsdWVzJ1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQgPSBmdW5jdGlvbiBjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbmRUaW1lOiBlbmRUaW1lLFxuICAgICAgICB0eXBlOiAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50ID0gZnVuY3Rpb24gY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVuZFRpbWU6IGVuZFRpbWUsXG4gICAgICAgIHR5cGU6ICdsaW5lYXJSYW1wVG9WYWx1ZScsXG4gICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgfTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCA9IGZ1bmN0aW9uIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGFydFRpbWU6IHN0YXJ0VGltZSxcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgICAgIHRpbWVDb25zdGFudDogdGltZUNvbnN0YW50LFxuICAgICAgICB0eXBlOiAnc2V0VGFyZ2V0J1xuICAgICAgfTtcbiAgICB9O1xuXG4gICAgZXhwb3J0cy5BdXRvbWF0aW9uRXZlbnRMaXN0ID0gQXV0b21hdGlvbkV2ZW50TGlzdDtcbiAgICBleHBvcnRzLmNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQgPSBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50ID0gY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQ7XG4gICAgZXhwb3J0cy5jcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCA9IGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50ID0gY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50O1xuICAgIGV4cG9ydHMuY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQgPSBjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudDtcbiAgICBleHBvcnRzLmNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgPSBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50O1xuXG59KSk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///382\n")},209:(__unused_webpack_module,__unused_webpack___webpack_exports__,__webpack_require__)=>{"use strict";eval('\n// EXTERNAL MODULE: ./node_modules/react/index.js\nvar react = __webpack_require__(294);\n// EXTERNAL MODULE: ./node_modules/react-dom/client.js\nvar client = __webpack_require__(745);\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/version.js\nconst version = "14.7.77";\n//# sourceMappingURL=version.js.map\n// EXTERNAL MODULE: ./node_modules/automation-events/build/es5/bundle.js\nvar bundle = __webpack_require__(382);\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/abort-error.js\nconst createAbortError = () => new DOMException(\'\', \'AbortError\');\n//# sourceMappingURL=abort-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-active-input-connection-to-audio-node.js\nconst createAddActiveInputConnectionToAudioNode = (insertElementInSet) => {\n return (activeInputs, source, [output, input, eventListener], ignoreDuplicates) => {\n insertElementInSet(activeInputs[input], [source, output, eventListener], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output, ignoreDuplicates);\n };\n};\n//# sourceMappingURL=add-active-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-node-connections.js\nconst createAddAudioNodeConnections = (audioNodeConnectionsStore) => {\n return (audioNode, audioNodeRenderer, nativeAudioNode) => {\n const activeInputs = [];\n for (let i = 0; i < nativeAudioNode.numberOfInputs; i += 1) {\n activeInputs.push(new Set());\n }\n audioNodeConnectionsStore.set(audioNode, {\n activeInputs,\n outputs: new Set(),\n passiveInputs: new WeakMap(),\n renderer: audioNodeRenderer\n });\n };\n};\n//# sourceMappingURL=add-audio-node-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-param-connections.js\nconst createAddAudioParamConnections = (audioParamConnectionsStore) => {\n return (audioParam, audioParamRenderer) => {\n audioParamConnectionsStore.set(audioParam, { activeInputs: new Set(), passiveInputs: new WeakMap(), renderer: audioParamRenderer });\n };\n};\n//# sourceMappingURL=add-audio-param-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/globals.js\nconst ACTIVE_AUDIO_NODE_STORE = new WeakSet();\nconst AUDIO_NODE_CONNECTIONS_STORE = new WeakMap();\nconst AUDIO_NODE_STORE = new WeakMap();\nconst AUDIO_PARAM_CONNECTIONS_STORE = new WeakMap();\nconst AUDIO_PARAM_STORE = new WeakMap();\nconst CONTEXT_STORE = new WeakMap();\nconst EVENT_LISTENERS = new WeakMap();\nconst CYCLE_COUNTERS = new WeakMap();\n// This clunky name is borrowed from the spec. :-)\nconst NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS = new WeakMap();\nconst NODE_TO_PROCESSOR_MAPS = new WeakMap();\n//# sourceMappingURL=globals.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-constructible.js\nconst handler = {\n construct() {\n return handler;\n }\n};\nconst isConstructible = (constructible) => {\n try {\n const proxy = new Proxy(constructible, handler);\n new proxy(); // tslint:disable-line:no-unused-expression\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=is-constructible.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/split-import-statements.js\n/*\n * This massive regex tries to cover all the following cases.\n *\n * import \'./path\';\n * import defaultImport from \'./path\';\n * import { namedImport } from \'./path\';\n * import { namedImport as renamendImport } from \'./path\';\n * import * as namespaceImport from \'./path\';\n * import defaultImport, { namedImport } from \'./path\';\n * import defaultImport, { namedImport as renamendImport } from \'./path\';\n * import defaultImport, * as namespaceImport from \'./path\';\n */\nconst IMPORT_STATEMENT_REGEX = /^import(?:(?:[\\s]+[\\w]+|(?:[\\s]+[\\w]+[\\s]*,)?[\\s]*\\{[\\s]*[\\w]+(?:[\\s]+as[\\s]+[\\w]+)?(?:[\\s]*,[\\s]*[\\w]+(?:[\\s]+as[\\s]+[\\w]+)?)*[\\s]*}|(?:[\\s]+[\\w]+[\\s]*,)?[\\s]*\\*[\\s]+as[\\s]+[\\w]+)[\\s]+from)?(?:[\\s]*)("([^"\\\\]|\\\\.)+"|\'([^\'\\\\]|\\\\.)+\')(?:[\\s]*);?/; // tslint:disable-line:max-line-length\nconst splitImportStatements = (source, url) => {\n const importStatements = [];\n let sourceWithoutImportStatements = source.replace(/^[\\s]+/, \'\');\n let result = sourceWithoutImportStatements.match(IMPORT_STATEMENT_REGEX);\n while (result !== null) {\n const unresolvedUrl = result[1].slice(1, -1);\n const importStatementWithResolvedUrl = result[0]\n .replace(/([\\s]+)?;?$/, \'\')\n .replace(unresolvedUrl, new URL(unresolvedUrl, url).toString());\n importStatements.push(importStatementWithResolvedUrl);\n sourceWithoutImportStatements = sourceWithoutImportStatements.slice(result[0].length).replace(/^[\\s]+/, \'\');\n result = sourceWithoutImportStatements.match(IMPORT_STATEMENT_REGEX);\n }\n return [importStatements.join(\';\'), sourceWithoutImportStatements];\n};\n//# sourceMappingURL=split-import-statements.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-audio-worklet-module.js\n\n\n\nconst verifyParameterDescriptors = (parameterDescriptors) => {\n if (parameterDescriptors !== undefined && !Array.isArray(parameterDescriptors)) {\n throw new TypeError(\'The parameterDescriptors property of given value for processorCtor is not an array.\');\n }\n};\nconst verifyProcessorCtor = (processorCtor) => {\n if (!isConstructible(processorCtor)) {\n throw new TypeError(\'The given value for processorCtor should be a constructor.\');\n }\n if (processorCtor.prototype === null || typeof processorCtor.prototype !== \'object\') {\n throw new TypeError(\'The given value for processorCtor should have a prototype.\');\n }\n};\nconst createAddAudioWorkletModule = (cacheTestResult, createNotSupportedError, evaluateSource, exposeCurrentFrameAndCurrentTime, fetchSource, getNativeContext, getOrCreateBackupOfflineAudioContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, ongoingRequests, resolvedRequests, testAudioWorkletProcessorPostMessageSupport, window) => {\n let index = 0;\n return (context, moduleURL, options = { credentials: \'omit\' }) => {\n const resolvedRequestsOfContext = resolvedRequests.get(context);\n if (resolvedRequestsOfContext !== undefined && resolvedRequestsOfContext.has(moduleURL)) {\n return Promise.resolve();\n }\n const ongoingRequestsOfContext = ongoingRequests.get(context);\n if (ongoingRequestsOfContext !== undefined) {\n const promiseOfOngoingRequest = ongoingRequestsOfContext.get(moduleURL);\n if (promiseOfOngoingRequest !== undefined) {\n return promiseOfOngoingRequest;\n }\n }\n const nativeContext = getNativeContext(context);\n // Bug #59: Safari does not implement the audioWorklet property.\n const promise = nativeContext.audioWorklet === undefined\n ? fetchSource(moduleURL)\n .then(([source, absoluteUrl]) => {\n const [importStatements, sourceWithoutImportStatements] = splitImportStatements(source, absoluteUrl);\n /*\n * This is the unminified version of the code used below:\n *\n * ```js\n * ${ importStatements };\n * ((a, b) => {\n * (a[b] = a[b] || [ ]).push(\n * (AudioWorkletProcessor, global, registerProcessor, sampleRate, self, window) => {\n * ${ sourceWithoutImportStatements }\n * }\n * );\n * })(window, \'_AWGS\');\n * ```\n */\n // tslint:disable-next-line:max-line-length\n const wrappedSource = `${importStatements};((a,b)=>{(a[b]=a[b]||[]).push((AudioWorkletProcessor,global,registerProcessor,sampleRate,self,window)=>{${sourceWithoutImportStatements}\n})})(window,\'_AWGS\')`;\n // @todo Evaluating the given source code is a possible security problem.\n return evaluateSource(wrappedSource);\n })\n .then(() => {\n const evaluateAudioWorkletGlobalScope = window._AWGS.pop();\n if (evaluateAudioWorkletGlobalScope === undefined) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n throw new SyntaxError();\n }\n exposeCurrentFrameAndCurrentTime(nativeContext.currentTime, nativeContext.sampleRate, () => evaluateAudioWorkletGlobalScope(class AudioWorkletProcessor {\n }, undefined, (name, processorCtor) => {\n if (name.trim() === \'\') {\n throw createNotSupportedError();\n }\n const nodeNameToProcessorConstructorMap = NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.get(nativeContext);\n if (nodeNameToProcessorConstructorMap !== undefined) {\n if (nodeNameToProcessorConstructorMap.has(name)) {\n throw createNotSupportedError();\n }\n verifyProcessorCtor(processorCtor);\n verifyParameterDescriptors(processorCtor.parameterDescriptors);\n nodeNameToProcessorConstructorMap.set(name, processorCtor);\n }\n else {\n verifyProcessorCtor(processorCtor);\n verifyParameterDescriptors(processorCtor.parameterDescriptors);\n NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.set(nativeContext, new Map([[name, processorCtor]]));\n }\n }, nativeContext.sampleRate, undefined, undefined));\n })\n : Promise.all([\n fetchSource(moduleURL),\n Promise.resolve(cacheTestResult(testAudioWorkletProcessorPostMessageSupport, testAudioWorkletProcessorPostMessageSupport))\n ]).then(([[source, absoluteUrl], isSupportingPostMessage]) => {\n const currentIndex = index + 1;\n index = currentIndex;\n const [importStatements, sourceWithoutImportStatements] = splitImportStatements(source, absoluteUrl);\n /*\n * Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\n *\n * This is the unminified version of the code used below.\n *\n * ```js\n * class extends AudioWorkletProcessor {\n *\n * __buffers = new WeakSet();\n *\n * constructor () {\n * super();\n *\n * this.port.postMessage = ((postMessage) => {\n * return (message, transferables) => {\n * const filteredTransferables = (transferables)\n * ? transferables.filter((transferable) => !this.__buffers.has(transferable))\n * : transferables;\n *\n * return postMessage.call(this.port, message, filteredTransferables);\n * };\n * })(this.port.postMessage);\n * }\n * }\n * ```\n */\n const patchedAudioWorkletProcessor = isSupportingPostMessage\n ? \'AudioWorkletProcessor\'\n : \'class extends AudioWorkletProcessor {__b=new WeakSet();constructor(){super();(p=>p.postMessage=(q=>(m,t)=>q.call(p,m,t?t.filter(u=>!this.__b.has(u)):t))(p.postMessage))(this.port)}}\';\n /*\n * Bug #170: Chrome and Edge do call process() with an array with empty channelData for each input if no input is connected.\n *\n * Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\n *\n * Bug #190: Safari doesn\'t throw an error when loading an unparsable module.\n *\n * This is the unminified version of the code used below:\n *\n * ```js\n * `${ importStatements };\n * ((AudioWorkletProcessor, registerProcessor) => {${ sourceWithoutImportStatements }\n * })(\n * ${ patchedAudioWorkletProcessor },\n * (name, processorCtor) => registerProcessor(name, class extends processorCtor {\n *\n * __collectBuffers = (array) => {\n * array.forEach((element) => this.__buffers.add(element.buffer));\n * };\n *\n * process (inputs, outputs, parameters) {\n * inputs.forEach(this.__collectBuffers);\n * outputs.forEach(this.__collectBuffers);\n * this.__collectBuffers(Object.values(parameters));\n *\n * return super.process(\n * (inputs.map((input) => input.some((channelData) => channelData.length === 0)) ? [ ] : input),\n * outputs,\n * parameters\n * );\n * }\n *\n * })\n * );\n *\n * registerProcessor(`__sac${currentIndex}`, class extends AudioWorkletProcessor{\n *\n * process () {\n * return false;\n * }\n *\n * })`\n * ```\n */\n const memberDefinition = isSupportingPostMessage ? \'\' : \'__c = (a) => a.forEach(e=>this.__b.add(e.buffer));\';\n const bufferRegistration = isSupportingPostMessage\n ? \'\'\n : \'i.forEach(this.__c);o.forEach(this.__c);this.__c(Object.values(p));\';\n const wrappedSource = `${importStatements};((AudioWorkletProcessor,registerProcessor)=>{${sourceWithoutImportStatements}\n})(${patchedAudioWorkletProcessor},(n,p)=>registerProcessor(n,class extends p{${memberDefinition}process(i,o,p){${bufferRegistration}return super.process(i.map(j=>j.some(k=>k.length===0)?[]:j),o,p)}}));registerProcessor(\'__sac${currentIndex}\',class extends AudioWorkletProcessor{process(){return !1}})`;\n const blob = new Blob([wrappedSource], { type: \'application/javascript; charset=utf-8\' });\n const url = URL.createObjectURL(blob);\n return nativeContext.audioWorklet\n .addModule(url, options)\n .then(() => {\n if (isNativeOfflineAudioContext(nativeContext)) {\n return nativeContext;\n }\n // Bug #186: Chrome and Edge do not allow to create an AudioWorkletNode on a closed AudioContext.\n const backupOfflineAudioContext = getOrCreateBackupOfflineAudioContext(nativeContext);\n return backupOfflineAudioContext.audioWorklet.addModule(url, options).then(() => backupOfflineAudioContext);\n })\n .then((nativeContextOrBackupOfflineAudioContext) => {\n if (nativeAudioWorkletNodeConstructor === null) {\n throw new SyntaxError();\n }\n try {\n // Bug #190: Safari doesn\'t throw an error when loading an unparsable module.\n new nativeAudioWorkletNodeConstructor(nativeContextOrBackupOfflineAudioContext, `__sac${currentIndex}`); // tslint:disable-line:no-unused-expression\n }\n catch {\n throw new SyntaxError();\n }\n })\n .finally(() => URL.revokeObjectURL(url));\n });\n if (ongoingRequestsOfContext === undefined) {\n ongoingRequests.set(context, new Map([[moduleURL, promise]]));\n }\n else {\n ongoingRequestsOfContext.set(moduleURL, promise);\n }\n promise\n .then(() => {\n const updatedResolvedRequestsOfContext = resolvedRequests.get(context);\n if (updatedResolvedRequestsOfContext === undefined) {\n resolvedRequests.set(context, new Set([moduleURL]));\n }\n else {\n updatedResolvedRequestsOfContext.add(moduleURL);\n }\n })\n .finally(() => {\n const updatedOngoingRequestsOfContext = ongoingRequests.get(context);\n if (updatedOngoingRequestsOfContext !== undefined) {\n updatedOngoingRequestsOfContext.delete(moduleURL);\n }\n });\n return promise;\n };\n};\n//# sourceMappingURL=add-audio-worklet-module.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-value-for-key.js\nconst getValueForKey = (map, key) => {\n const value = map.get(key);\n if (value === undefined) {\n throw new Error(\'A value with the given key could not be found.\');\n }\n return value;\n};\n//# sourceMappingURL=get-value-for-key.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/pick-element-from-set.js\nconst pickElementFromSet = (set, predicate) => {\n const matchingElements = Array.from(set).filter(predicate);\n if (matchingElements.length > 1) {\n throw Error(\'More than one element was found.\');\n }\n if (matchingElements.length === 0) {\n throw Error(\'No element was found.\');\n }\n const [matchingElement] = matchingElements;\n set.delete(matchingElement);\n return matchingElement;\n};\n//# sourceMappingURL=pick-element-from-set.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-passive-input-connection-to-audio-node.js\n\n\nconst deletePassiveInputConnectionToAudioNode = (passiveInputs, source, output, input) => {\n const passiveInputConnections = getValueForKey(passiveInputs, source);\n const matchingConnection = pickElementFromSet(passiveInputConnections, (passiveInputConnection) => passiveInputConnection[0] === output && passiveInputConnection[1] === input);\n if (passiveInputConnections.size === 0) {\n passiveInputs.delete(source);\n }\n return matchingConnection;\n};\n//# sourceMappingURL=delete-passive-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-event-listeners-of-audio-node.js\n\n\nconst getEventListenersOfAudioNode = (audioNode) => {\n return getValueForKey(EVENT_LISTENERS, audioNode);\n};\n//# sourceMappingURL=get-event-listeners-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-active.js\n\n\nconst setInternalStateToActive = (audioNode) => {\n if (ACTIVE_AUDIO_NODE_STORE.has(audioNode)) {\n throw new Error(\'The AudioNode is already stored.\');\n }\n ACTIVE_AUDIO_NODE_STORE.add(audioNode);\n getEventListenersOfAudioNode(audioNode).forEach((eventListener) => eventListener(true));\n};\n//# sourceMappingURL=set-internal-state-to-active.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-worklet-node.js\nconst isAudioWorkletNode = (audioNode) => {\n return \'port\' in audioNode;\n};\n//# sourceMappingURL=audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-passive.js\n\n\nconst setInternalStateToPassive = (audioNode) => {\n if (!ACTIVE_AUDIO_NODE_STORE.has(audioNode)) {\n throw new Error(\'The AudioNode is not stored.\');\n }\n ACTIVE_AUDIO_NODE_STORE["delete"](audioNode);\n getEventListenersOfAudioNode(audioNode).forEach((eventListener) => eventListener(false));\n};\n//# sourceMappingURL=set-internal-state-to-passive.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-internal-state-to-passive-when-necessary.js\n\n\n// Set the internalState of the audioNode to \'passive\' if it is not an AudioWorkletNode and if it has no \'active\' input connections.\nconst setInternalStateToPassiveWhenNecessary = (audioNode, activeInputs) => {\n if (!isAudioWorkletNode(audioNode) && activeInputs.every((connections) => connections.size === 0)) {\n setInternalStateToPassive(audioNode);\n }\n};\n//# sourceMappingURL=set-internal-state-to-passive-when-necessary.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-connection-to-audio-node.js\n\n\n\nconst createAddConnectionToAudioNode = (addActiveInputConnectionToAudioNode, addPassiveInputConnectionToAudioNode, connectNativeAudioNodeToNativeAudioNode, deleteActiveInputConnectionToAudioNode, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getAudioNodeTailTime, getEventListenersOfAudioNode, getNativeAudioNode, insertElementInSet, isActiveAudioNode, isPartOfACycle, isPassiveAudioNode) => {\n const tailTimeTimeoutIds = new WeakMap();\n return (source, destination, output, input, isOffline) => {\n const { activeInputs, passiveInputs } = getAudioNodeConnections(destination);\n const { outputs } = getAudioNodeConnections(source);\n const eventListeners = getEventListenersOfAudioNode(source);\n const eventListener = (isActive) => {\n const nativeDestinationAudioNode = getNativeAudioNode(destination);\n const nativeSourceAudioNode = getNativeAudioNode(source);\n if (isActive) {\n const partialConnection = deletePassiveInputConnectionToAudioNode(passiveInputs, source, output, input);\n addActiveInputConnectionToAudioNode(activeInputs, source, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n connectNativeAudioNodeToNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output, input);\n }\n if (isPassiveAudioNode(destination)) {\n setInternalStateToActive(destination);\n }\n }\n else {\n const partialConnection = deleteActiveInputConnectionToAudioNode(activeInputs, source, output, input);\n addPassiveInputConnectionToAudioNode(passiveInputs, input, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n disconnectNativeAudioNodeFromNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output, input);\n }\n const tailTime = getAudioNodeTailTime(destination);\n if (tailTime === 0) {\n if (isActiveAudioNode(destination)) {\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n }\n else {\n const tailTimeTimeoutId = tailTimeTimeoutIds.get(destination);\n if (tailTimeTimeoutId !== undefined) {\n clearTimeout(tailTimeTimeoutId);\n }\n tailTimeTimeoutIds.set(destination, setTimeout(() => {\n if (isActiveAudioNode(destination)) {\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n }, tailTime * 1000));\n }\n }\n };\n if (insertElementInSet(outputs, [destination, output, input], (outputConnection) => outputConnection[0] === destination && outputConnection[1] === output && outputConnection[2] === input, true)) {\n eventListeners.add(eventListener);\n if (isActiveAudioNode(source)) {\n addActiveInputConnectionToAudioNode(activeInputs, source, [output, input, eventListener], true);\n }\n else {\n addPassiveInputConnectionToAudioNode(passiveInputs, input, [source, output, eventListener], true);\n }\n return true;\n }\n return false;\n };\n};\n//# sourceMappingURL=add-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-passive-input-connection-to-audio-node.js\nconst createAddPassiveInputConnectionToAudioNode = (insertElementInSet) => {\n return (passiveInputs, input, [source, output, eventListener], ignoreDuplicates) => {\n const passiveInputConnections = passiveInputs.get(source);\n if (passiveInputConnections === undefined) {\n passiveInputs.set(source, new Set([[output, input, eventListener]]));\n }\n else {\n insertElementInSet(passiveInputConnections, [output, input, eventListener], (passiveInputConnection) => passiveInputConnection[0] === output && passiveInputConnection[1] === input, ignoreDuplicates);\n }\n };\n};\n//# sourceMappingURL=add-passive-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-silent-connection.js\nconst createAddSilentConnection = (createNativeGainNode) => {\n return (nativeContext, nativeAudioScheduledSourceNode) => {\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeAudioScheduledSourceNode.connect(nativeGainNode).connect(nativeContext.destination);\n const disconnect = () => {\n nativeAudioScheduledSourceNode.removeEventListener(\'ended\', disconnect);\n nativeAudioScheduledSourceNode.disconnect(nativeGainNode);\n nativeGainNode.disconnect();\n };\n nativeAudioScheduledSourceNode.addEventListener(\'ended\', disconnect);\n };\n};\n//# sourceMappingURL=add-silent-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/add-unrendered-audio-worklet-node.js\nconst createAddUnrenderedAudioWorkletNode = (getUnrenderedAudioWorkletNodes) => {\n return (nativeContext, audioWorkletNode) => {\n getUnrenderedAudioWorkletNodes(nativeContext).add(audioWorkletNode);\n };\n};\n//# sourceMappingURL=add-unrendered-audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/analyser-node-constructor.js\nconst DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n fftSize: 2048,\n maxDecibels: -30,\n minDecibels: -100,\n smoothingTimeConstant: 0.8\n};\nconst createAnalyserNodeConstructor = (audionNodeConstructor, createAnalyserNodeRenderer, createIndexSizeError, createNativeAnalyserNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class AnalyserNode extends audionNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...DEFAULT_OPTIONS, ...options };\n const nativeAnalyserNode = createNativeAnalyserNode(nativeContext, mergedOptions);\n const analyserNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createAnalyserNodeRenderer() : null));\n super(context, false, nativeAnalyserNode, analyserNodeRenderer);\n this._nativeAnalyserNode = nativeAnalyserNode;\n }\n get fftSize() {\n return this._nativeAnalyserNode.fftSize;\n }\n set fftSize(value) {\n this._nativeAnalyserNode.fftSize = value;\n }\n get frequencyBinCount() {\n return this._nativeAnalyserNode.frequencyBinCount;\n }\n get maxDecibels() {\n return this._nativeAnalyserNode.maxDecibels;\n }\n set maxDecibels(value) {\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n const maxDecibels = this._nativeAnalyserNode.maxDecibels;\n this._nativeAnalyserNode.maxDecibels = value;\n if (!(value > this._nativeAnalyserNode.minDecibels)) {\n this._nativeAnalyserNode.maxDecibels = maxDecibels;\n throw createIndexSizeError();\n }\n }\n get minDecibels() {\n return this._nativeAnalyserNode.minDecibels;\n }\n set minDecibels(value) {\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n const minDecibels = this._nativeAnalyserNode.minDecibels;\n this._nativeAnalyserNode.minDecibels = value;\n if (!(this._nativeAnalyserNode.maxDecibels > value)) {\n this._nativeAnalyserNode.minDecibels = minDecibels;\n throw createIndexSizeError();\n }\n }\n get smoothingTimeConstant() {\n return this._nativeAnalyserNode.smoothingTimeConstant;\n }\n set smoothingTimeConstant(value) {\n this._nativeAnalyserNode.smoothingTimeConstant = value;\n }\n getByteFrequencyData(array) {\n this._nativeAnalyserNode.getByteFrequencyData(array);\n }\n getByteTimeDomainData(array) {\n this._nativeAnalyserNode.getByteTimeDomainData(array);\n }\n getFloatFrequencyData(array) {\n this._nativeAnalyserNode.getFloatFrequencyData(array);\n }\n getFloatTimeDomainData(array) {\n this._nativeAnalyserNode.getFloatTimeDomainData(array);\n }\n };\n};\n//# sourceMappingURL=analyser-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-owned-by-context.js\nconst isOwnedByContext = (nativeAudioNode, nativeContext) => {\n return nativeAudioNode.context === nativeContext;\n};\n//# sourceMappingURL=is-owned-by-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/analyser-node-renderer-factory.js\n\nconst createAnalyserNodeRendererFactory = (createNativeAnalyserNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAnalyserNodes = new WeakMap();\n const createAnalyserNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAnalyserNode = getNativeAudioNode(proxy);\n // If the initially used nativeAnalyserNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAnalyserNodeIsOwnedByContext = isOwnedByContext(nativeAnalyserNode, nativeOfflineAudioContext);\n if (!nativeAnalyserNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAnalyserNode.channelCount,\n channelCountMode: nativeAnalyserNode.channelCountMode,\n channelInterpretation: nativeAnalyserNode.channelInterpretation,\n fftSize: nativeAnalyserNode.fftSize,\n maxDecibels: nativeAnalyserNode.maxDecibels,\n minDecibels: nativeAnalyserNode.minDecibels,\n smoothingTimeConstant: nativeAnalyserNode.smoothingTimeConstant\n };\n nativeAnalyserNode = createNativeAnalyserNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAnalyserNodes.set(nativeOfflineAudioContext, nativeAnalyserNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAnalyserNode);\n return nativeAnalyserNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAnalyserNode = renderedNativeAnalyserNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAnalyserNode !== undefined) {\n return Promise.resolve(renderedNativeAnalyserNode);\n }\n return createAnalyserNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=analyser-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-copy-channel-methods-out-of-bounds-support.js\nconst testAudioBufferCopyChannelMethodsOutOfBoundsSupport = (nativeAudioBuffer) => {\n try {\n nativeAudioBuffer.copyToChannel(new Float32Array(1), 0, -1);\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-copy-channel-methods-out-of-bounds-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/index-size-error.js\nconst createIndexSizeError = () => new DOMException(\'\', \'IndexSizeError\');\n//# sourceMappingURL=index-size-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-get-channel-data-method.js\n\nconst wrapAudioBufferGetChannelDataMethod = (audioBuffer) => {\n audioBuffer.getChannelData = ((getChannelData) => {\n return (channel) => {\n try {\n return getChannelData.call(audioBuffer, channel);\n }\n catch (err) {\n if (err.code === 12) {\n throw createIndexSizeError();\n }\n throw err;\n }\n };\n })(audioBuffer.getChannelData);\n};\n//# sourceMappingURL=wrap-audio-buffer-get-channel-data-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-constructor.js\n\n\nconst audio_buffer_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createAudioBufferConstructor = (audioBufferStore, cacheTestResult, createNotSupportedError, nativeAudioBufferConstructor, nativeOfflineAudioContextConstructor, testNativeAudioBufferConstructorSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n let nativeOfflineAudioContext = null;\n return class AudioBuffer {\n constructor(options) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const { length, numberOfChannels, sampleRate } = { ...audio_buffer_constructor_DEFAULT_OPTIONS, ...options };\n if (nativeOfflineAudioContext === null) {\n nativeOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n }\n /*\n * Bug #99: Firefox does not throw a NotSupportedError when the numberOfChannels is zero. But it only does it when using the\n * factory function. But since Firefox also supports the constructor everything should be fine.\n */\n const audioBuffer = nativeAudioBufferConstructor !== null &&\n cacheTestResult(testNativeAudioBufferConstructorSupport, testNativeAudioBufferConstructorSupport)\n ? new nativeAudioBufferConstructor({ length, numberOfChannels, sampleRate })\n : nativeOfflineAudioContext.createBuffer(numberOfChannels, length, sampleRate);\n // Bug #99: Safari does not throw an error when the numberOfChannels is zero.\n if (audioBuffer.numberOfChannels === 0) {\n throw createNotSupportedError();\n }\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n }\n else if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n /*\n * This does violate all good pratices but it is necessary to allow this AudioBuffer to be used with native\n * (Offline)AudioContexts.\n */\n return audioBuffer;\n }\n static [Symbol.hasInstance](instance) {\n return ((instance !== null && typeof instance === \'object\' && Object.getPrototypeOf(instance) === AudioBuffer.prototype) ||\n audioBufferStore.has(instance));\n }\n };\n};\n//# sourceMappingURL=audio-buffer-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/constants.js\nconst MOST_NEGATIVE_SINGLE_FLOAT = -3.4028234663852886e38;\nconst MOST_POSITIVE_SINGLE_FLOAT = -MOST_NEGATIVE_SINGLE_FLOAT;\n//# sourceMappingURL=constants.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-active-audio-node.js\n\nconst isActiveAudioNode = (audioNode) => ACTIVE_AUDIO_NODE_STORE.has(audioNode);\n//# sourceMappingURL=is-active-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-source-node-constructor.js\n\n\n\n\nconst audio_buffer_source_node_constructor_DEFAULT_OPTIONS = {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n // Bug #149: Safari does not yet support the detune AudioParam.\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n};\nconst createAudioBufferSourceNodeConstructor = (audioNodeConstructor, createAudioBufferSourceNodeRenderer, createAudioParam, createInvalidStateError, createNativeAudioBufferSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class AudioBufferSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...audio_buffer_source_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const audioBufferSourceNodeRenderer = ((isOffline ? createAudioBufferSourceNodeRenderer() : null));\n super(context, false, nativeAudioBufferSourceNode, audioBufferSourceNodeRenderer);\n this._audioBufferSourceNodeRenderer = audioBufferSourceNodeRenderer;\n this._isBufferNullified = false;\n this._isBufferSet = mergedOptions.buffer !== null;\n this._nativeAudioBufferSourceNode = nativeAudioBufferSourceNode;\n this._onended = null;\n // Bug #73: Safari does not export the correct values for maxValue and minValue.\n this._playbackRate = createAudioParam(this, isOffline, nativeAudioBufferSourceNode.playbackRate, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n }\n get buffer() {\n if (this._isBufferNullified) {\n return null;\n }\n return this._nativeAudioBufferSourceNode.buffer;\n }\n set buffer(value) {\n this._nativeAudioBufferSourceNode.buffer = value;\n // Bug #72: Only Chrome & Edge do not allow to reassign the buffer yet.\n if (value !== null) {\n if (this._isBufferSet) {\n throw createInvalidStateError();\n }\n this._isBufferSet = true;\n }\n }\n get loop() {\n return this._nativeAudioBufferSourceNode.loop;\n }\n set loop(value) {\n this._nativeAudioBufferSourceNode.loop = value;\n }\n get loopEnd() {\n return this._nativeAudioBufferSourceNode.loopEnd;\n }\n set loopEnd(value) {\n this._nativeAudioBufferSourceNode.loopEnd = value;\n }\n get loopStart() {\n return this._nativeAudioBufferSourceNode.loopStart;\n }\n set loopStart(value) {\n this._nativeAudioBufferSourceNode.loopStart = value;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeAudioBufferSourceNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeAudioBufferSourceNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n get playbackRate() {\n return this._playbackRate;\n }\n start(when = 0, offset = 0, duration) {\n this._nativeAudioBufferSourceNode.start(when, offset, duration);\n if (this._audioBufferSourceNodeRenderer !== null) {\n this._audioBufferSourceNodeRenderer.start = duration === undefined ? [when, offset] : [when, offset, duration];\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeAudioBufferSourceNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeAudioBufferSourceNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeAudioBufferSourceNode.stop(when);\n if (this._audioBufferSourceNodeRenderer !== null) {\n this._audioBufferSourceNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=audio-buffer-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-buffer-source-node-renderer-factory.js\n\nconst createAudioBufferSourceNodeRendererFactory = (connectAudioParam, createNativeAudioBufferSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioBufferSourceNodes = new WeakMap();\n let start = null;\n let stop = null;\n const createAudioBufferSourceNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioBufferSourceNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeAudioBufferSourceNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeAudioBufferSourceNodeIsOwnedByContext = isOwnedByContext(nativeAudioBufferSourceNode, nativeOfflineAudioContext);\n if (!nativeAudioBufferSourceNodeIsOwnedByContext) {\n const options = {\n buffer: nativeAudioBufferSourceNode.buffer,\n channelCount: nativeAudioBufferSourceNode.channelCount,\n channelCountMode: nativeAudioBufferSourceNode.channelCountMode,\n channelInterpretation: nativeAudioBufferSourceNode.channelInterpretation,\n // Bug #149: Safari does not yet support the detune AudioParam.\n loop: nativeAudioBufferSourceNode.loop,\n loopEnd: nativeAudioBufferSourceNode.loopEnd,\n loopStart: nativeAudioBufferSourceNode.loopStart,\n playbackRate: nativeAudioBufferSourceNode.playbackRate.value\n };\n nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeAudioBufferSourceNode.start(...start);\n }\n if (stop !== null) {\n nativeAudioBufferSourceNode.stop(stop);\n }\n }\n renderedNativeAudioBufferSourceNodes.set(nativeOfflineAudioContext, nativeAudioBufferSourceNode);\n if (!nativeAudioBufferSourceNodeIsOwnedByContext) {\n // Bug #149: Safari does not yet support the detune AudioParam.\n await renderAutomation(nativeOfflineAudioContext, proxy.playbackRate, nativeAudioBufferSourceNode.playbackRate);\n }\n else {\n // Bug #149: Safari does not yet support the detune AudioParam.\n await connectAudioParam(nativeOfflineAudioContext, proxy.playbackRate, nativeAudioBufferSourceNode.playbackRate);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioBufferSourceNode);\n return nativeAudioBufferSourceNode;\n };\n return {\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioBufferSourceNode = renderedNativeAudioBufferSourceNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioBufferSourceNode !== undefined) {\n return Promise.resolve(renderedNativeAudioBufferSourceNode);\n }\n return createAudioBufferSourceNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=audio-buffer-source-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-buffer-source-node.js\nconst isAudioBufferSourceNode = (audioNode) => {\n return \'playbackRate\' in audioNode;\n};\n//# sourceMappingURL=audio-buffer-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/biquad-filter-node.js\nconst isBiquadFilterNode = (audioNode) => {\n return \'frequency\' in audioNode && \'gain\' in audioNode;\n};\n//# sourceMappingURL=biquad-filter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/constant-source-node.js\nconst isConstantSourceNode = (audioNode) => {\n return \'offset\' in audioNode;\n};\n//# sourceMappingURL=constant-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/gain-node.js\nconst isGainNode = (audioNode) => {\n return !(\'frequency\' in audioNode) && \'gain\' in audioNode;\n};\n//# sourceMappingURL=gain-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/oscillator-node.js\nconst isOscillatorNode = (audioNode) => {\n return \'detune\' in audioNode && \'frequency\' in audioNode;\n};\n//# sourceMappingURL=oscillator-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/stereo-panner-node.js\nconst isStereoPannerNode = (audioNode) => {\n return \'pan\' in audioNode;\n};\n//# sourceMappingURL=stereo-panner-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-node-connections.js\n\n\nconst getAudioNodeConnections = (audioNode) => {\n return getValueForKey(AUDIO_NODE_CONNECTIONS_STORE, audioNode);\n};\n//# sourceMappingURL=get-audio-node-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-param-connections.js\n\n\nconst getAudioParamConnections = (audioParam) => {\n return getValueForKey(AUDIO_PARAM_CONNECTIONS_STORE, audioParam);\n};\n//# sourceMappingURL=get-audio-param-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/deactivate-active-audio-node-input-connections.js\n\n\n\n\n\n\n\n\n\n\n\nconst deactivateActiveAudioNodeInputConnections = (audioNode, trace) => {\n const { activeInputs } = getAudioNodeConnections(audioNode);\n activeInputs.forEach((connections) => connections.forEach(([source]) => {\n if (!trace.includes(audioNode)) {\n deactivateActiveAudioNodeInputConnections(source, [...trace, audioNode]);\n }\n }));\n const audioParams = isAudioBufferSourceNode(audioNode)\n ? [\n // Bug #149: Safari does not yet support the detune AudioParam.\n audioNode.playbackRate\n ]\n : isAudioWorkletNode(audioNode)\n ? Array.from(audioNode.parameters.values())\n : isBiquadFilterNode(audioNode)\n ? [audioNode.Q, audioNode.detune, audioNode.frequency, audioNode.gain]\n : isConstantSourceNode(audioNode)\n ? [audioNode.offset]\n : isGainNode(audioNode)\n ? [audioNode.gain]\n : isOscillatorNode(audioNode)\n ? [audioNode.detune, audioNode.frequency]\n : isStereoPannerNode(audioNode)\n ? [audioNode.pan]\n : [];\n for (const audioParam of audioParams) {\n const audioParamConnections = getAudioParamConnections(audioParam);\n if (audioParamConnections !== undefined) {\n audioParamConnections.activeInputs.forEach(([source]) => deactivateActiveAudioNodeInputConnections(source, trace));\n }\n }\n if (isActiveAudioNode(audioNode)) {\n setInternalStateToPassive(audioNode);\n }\n};\n//# sourceMappingURL=deactivate-active-audio-node-input-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/deactivate-audio-graph.js\n\nconst deactivateAudioGraph = (context) => {\n deactivateActiveAudioNodeInputConnections(context.destination, []);\n};\n//# sourceMappingURL=deactivate-audio-graph.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-valid-latency-hint.js\nconst isValidLatencyHint = (latencyHint) => {\n return (latencyHint === undefined ||\n typeof latencyHint === \'number\' ||\n (typeof latencyHint === \'string\' && (latencyHint === \'balanced\' || latencyHint === \'interactive\' || latencyHint === \'playback\')));\n};\n//# sourceMappingURL=is-valid-latency-hint.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-context-constructor.js\n\n\nconst createAudioContextConstructor = (baseAudioContextConstructor, createInvalidStateError, createNotSupportedError, createUnknownError, mediaElementAudioSourceNodeConstructor, mediaStreamAudioDestinationNodeConstructor, mediaStreamAudioSourceNodeConstructor, mediaStreamTrackAudioSourceNodeConstructor, nativeAudioContextConstructor) => {\n return class AudioContext extends baseAudioContextConstructor {\n constructor(options = {}) {\n if (nativeAudioContextConstructor === null) {\n throw new Error(\'Missing the native AudioContext constructor.\');\n }\n let nativeAudioContext;\n try {\n nativeAudioContext = new nativeAudioContextConstructor(options);\n }\n catch (err) {\n // Bug #192 Safari does throw a SyntaxError if the sampleRate is not supported.\n if (err.code === 12 && err.message === \'sampleRate is not in range\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n // Bug #131 Safari returns null when there are four other AudioContexts running already.\n if (nativeAudioContext === null) {\n throw createUnknownError();\n }\n // Bug #51 Only Chrome and Edge throw an error if the given latencyHint is invalid.\n if (!isValidLatencyHint(options.latencyHint)) {\n throw new TypeError(`The provided value \'${options.latencyHint}\' is not a valid enum value of type AudioContextLatencyCategory.`);\n }\n // Bug #150 Safari does not support setting the sampleRate.\n if (options.sampleRate !== undefined && nativeAudioContext.sampleRate !== options.sampleRate) {\n throw createNotSupportedError();\n }\n super(nativeAudioContext, 2);\n const { latencyHint } = options;\n const { sampleRate } = nativeAudioContext;\n // @todo The values for \'balanced\', \'interactive\' and \'playback\' are just copied from Chrome\'s implementation.\n this._baseLatency =\n typeof nativeAudioContext.baseLatency === \'number\'\n ? nativeAudioContext.baseLatency\n : latencyHint === \'balanced\'\n ? 512 / sampleRate\n : latencyHint === \'interactive\' || latencyHint === undefined\n ? 256 / sampleRate\n : latencyHint === \'playback\'\n ? 1024 / sampleRate\n : /*\n * @todo The min (256) and max (16384) values are taken from the allowed bufferSize values of a\n * ScriptProcessorNode.\n */\n (Math.max(2, Math.min(128, Math.round((latencyHint * sampleRate) / 128))) * 128) / sampleRate;\n this._nativeAudioContext = nativeAudioContext;\n // Bug #188: Safari will set the context\'s state to \'interrupted\' in case the user switches tabs.\n if (nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n this._nativeGainNode = nativeAudioContext.createGain();\n this._nativeOscillatorNode = nativeAudioContext.createOscillator();\n this._nativeGainNode.gain.value = 1e-37;\n this._nativeOscillatorNode.connect(this._nativeGainNode).connect(nativeAudioContext.destination);\n this._nativeOscillatorNode.start();\n }\n else {\n this._nativeGainNode = null;\n this._nativeOscillatorNode = null;\n }\n this._state = null;\n /*\n * Bug #34: Chrome and Edge pretend to be running right away, but fire an onstatechange event when the state actually changes\n * to \'running\'.\n */\n if (nativeAudioContext.state === \'running\') {\n this._state = \'suspended\';\n const revokeState = () => {\n if (this._state === \'suspended\') {\n this._state = null;\n }\n nativeAudioContext.removeEventListener(\'statechange\', revokeState);\n };\n nativeAudioContext.addEventListener(\'statechange\', revokeState);\n }\n }\n get baseLatency() {\n return this._baseLatency;\n }\n get state() {\n return this._state !== null ? this._state : this._nativeAudioContext.state;\n }\n close() {\n // Bug #35: Firefox does not throw an error if the AudioContext was closed before.\n if (this.state === \'closed\') {\n return this._nativeAudioContext.close().then(() => {\n throw createInvalidStateError();\n });\n }\n // Bug #34: If the state was set to suspended before it should be revoked now.\n if (this._state === \'suspended\') {\n this._state = null;\n }\n return this._nativeAudioContext.close().then(() => {\n if (this._nativeGainNode !== null && this._nativeOscillatorNode !== null) {\n this._nativeOscillatorNode.stop();\n this._nativeGainNode.disconnect();\n this._nativeOscillatorNode.disconnect();\n }\n deactivateAudioGraph(this);\n });\n }\n createMediaElementSource(mediaElement) {\n return new mediaElementAudioSourceNodeConstructor(this, { mediaElement });\n }\n createMediaStreamDestination() {\n return new mediaStreamAudioDestinationNodeConstructor(this);\n }\n createMediaStreamSource(mediaStream) {\n return new mediaStreamAudioSourceNodeConstructor(this, { mediaStream });\n }\n createMediaStreamTrackSource(mediaStreamTrack) {\n return new mediaStreamTrackAudioSourceNodeConstructor(this, { mediaStreamTrack });\n }\n resume() {\n if (this._state === \'suspended\') {\n return new Promise((resolve, reject) => {\n const resolvePromise = () => {\n this._nativeAudioContext.removeEventListener(\'statechange\', resolvePromise);\n if (this._nativeAudioContext.state === \'running\') {\n resolve();\n }\n else {\n this.resume().then(resolve, reject);\n }\n };\n this._nativeAudioContext.addEventListener(\'statechange\', resolvePromise);\n });\n }\n return this._nativeAudioContext.resume().catch((err) => {\n // Bug #55: Chrome and Edge do throw an InvalidAccessError instead of an InvalidStateError.\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined || err.code === 15) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n suspend() {\n return this._nativeAudioContext.suspend().catch((err) => {\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-destination-node-constructor.js\nconst createAudioDestinationNodeConstructor = (audioNodeConstructor, createAudioDestinationNodeRenderer, createIndexSizeError, createInvalidStateError, createNativeAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext, renderInputsOfAudioNode) => {\n return class AudioDestinationNode extends audioNodeConstructor {\n constructor(context, channelCount) {\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const nativeAudioDestinationNode = createNativeAudioDestinationNode(nativeContext, channelCount, isOffline);\n const audioDestinationNodeRenderer = ((isOffline ? createAudioDestinationNodeRenderer(renderInputsOfAudioNode) : null));\n super(context, false, nativeAudioDestinationNode, audioDestinationNodeRenderer);\n this._isNodeOfNativeOfflineAudioContext = isOffline;\n this._nativeAudioDestinationNode = nativeAudioDestinationNode;\n }\n get channelCount() {\n return this._nativeAudioDestinationNode.channelCount;\n }\n set channelCount(value) {\n // Bug #52: Chrome, Edge & Safari do not throw an exception at all.\n // Bug #54: Firefox does throw an IndexSizeError.\n if (this._isNodeOfNativeOfflineAudioContext) {\n throw createInvalidStateError();\n }\n // Bug #47: The AudioDestinationNode in Safari does not initialize the maxChannelCount property correctly.\n if (value > this._nativeAudioDestinationNode.maxChannelCount) {\n throw createIndexSizeError();\n }\n this._nativeAudioDestinationNode.channelCount = value;\n }\n get channelCountMode() {\n return this._nativeAudioDestinationNode.channelCountMode;\n }\n set channelCountMode(value) {\n // Bug #53: No browser does throw an exception yet.\n if (this._isNodeOfNativeOfflineAudioContext) {\n throw createInvalidStateError();\n }\n this._nativeAudioDestinationNode.channelCountMode = value;\n }\n get maxChannelCount() {\n return this._nativeAudioDestinationNode.maxChannelCount;\n }\n };\n};\n//# sourceMappingURL=audio-destination-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-destination-node-renderer-factory.js\nconst createAudioDestinationNodeRenderer = (renderInputsOfAudioNode) => {\n const renderedNativeAudioDestinationNodes = new WeakMap();\n const createAudioDestinationNode = async (proxy, nativeOfflineAudioContext) => {\n const nativeAudioDestinationNode = nativeOfflineAudioContext.destination;\n renderedNativeAudioDestinationNodes.set(nativeOfflineAudioContext, nativeAudioDestinationNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioDestinationNode);\n return nativeAudioDestinationNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioDestinationNode = renderedNativeAudioDestinationNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioDestinationNode !== undefined) {\n return Promise.resolve(renderedNativeAudioDestinationNode);\n }\n return createAudioDestinationNode(proxy, nativeOfflineAudioContext);\n }\n };\n};\n//# sourceMappingURL=audio-destination-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-listener-factory.js\n\nconst createAudioListenerFactory = (createAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeScriptProcessorNode, createNotSupportedError, getFirstSample, isNativeOfflineAudioContext, overwriteAccessors) => {\n return (context, nativeContext) => {\n const nativeListener = nativeContext.listener;\n // Bug #117: Only Chrome & Edge support the new interface already.\n const createFakeAudioParams = () => {\n const buffer = new Float32Array(1);\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 9\n });\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n let isScriptProcessorNodeCreated = false;\n let lastOrientation = [0, 0, -1, 0, 1, 0];\n let lastPosition = [0, 0, 0];\n const createScriptProcessorNode = () => {\n if (isScriptProcessorNodeCreated) {\n return;\n }\n isScriptProcessorNodeCreated = true;\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, 256, 9, 0);\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer }) => {\n const orientation = [\n getFirstSample(inputBuffer, buffer, 0),\n getFirstSample(inputBuffer, buffer, 1),\n getFirstSample(inputBuffer, buffer, 2),\n getFirstSample(inputBuffer, buffer, 3),\n getFirstSample(inputBuffer, buffer, 4),\n getFirstSample(inputBuffer, buffer, 5)\n ];\n if (orientation.some((value, index) => value !== lastOrientation[index])) {\n nativeListener.setOrientation(...orientation); // tslint:disable-line:deprecation\n lastOrientation = orientation;\n }\n const positon = [\n getFirstSample(inputBuffer, buffer, 6),\n getFirstSample(inputBuffer, buffer, 7),\n getFirstSample(inputBuffer, buffer, 8)\n ];\n if (positon.some((value, index) => value !== lastPosition[index])) {\n nativeListener.setPosition(...positon); // tslint:disable-line:deprecation\n lastPosition = positon;\n }\n };\n channelMergerNode.connect(scriptProcessorNode);\n };\n const createSetOrientation = (index) => (value) => {\n if (value !== lastOrientation[index]) {\n lastOrientation[index] = value;\n nativeListener.setOrientation(...lastOrientation); // tslint:disable-line:deprecation\n }\n };\n const createSetPosition = (index) => (value) => {\n if (value !== lastPosition[index]) {\n lastPosition[index] = value;\n nativeListener.setPosition(...lastPosition); // tslint:disable-line:deprecation\n }\n };\n const createFakeAudioParam = (input, initialValue, setValue) => {\n const constantSourceNode = createNativeConstantSourceNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: initialValue\n });\n constantSourceNode.connect(channelMergerNode, 0, input);\n // @todo This should be stopped when the context is closed.\n constantSourceNode.start();\n Object.defineProperty(constantSourceNode.offset, \'defaultValue\', {\n get() {\n return initialValue;\n }\n });\n /*\n * Bug #62 & #74: Safari does not support ConstantSourceNodes and does not export the correct values for maxValue and\n * minValue for GainNodes.\n */\n const audioParam = createAudioParam({ context }, isOffline, constantSourceNode.offset, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n overwriteAccessors(audioParam, \'value\', (get) => () => get.call(audioParam), (set) => (value) => {\n try {\n set.call(audioParam, value);\n }\n catch (err) {\n if (err.code !== 9) {\n throw err;\n }\n }\n createScriptProcessorNode();\n if (isOffline) {\n // Bug #117: Using setOrientation() and setPosition() doesn\'t work with an OfflineAudioContext.\n setValue(value);\n }\n });\n audioParam.cancelAndHoldAtTime = ((cancelAndHoldAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = cancelAndHoldAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.cancelAndHoldAtTime);\n audioParam.cancelScheduledValues = ((cancelScheduledValues) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = cancelScheduledValues.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.cancelScheduledValues);\n audioParam.exponentialRampToValueAtTime = ((exponentialRampToValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = exponentialRampToValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.exponentialRampToValueAtTime);\n audioParam.linearRampToValueAtTime = ((linearRampToValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = linearRampToValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.linearRampToValueAtTime);\n audioParam.setTargetAtTime = ((setTargetAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setTargetAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setTargetAtTime);\n audioParam.setValueAtTime = ((setValueAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setValueAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setValueAtTime);\n audioParam.setValueCurveAtTime = ((setValueCurveAtTime) => {\n if (isOffline) {\n return () => {\n throw createNotSupportedError();\n };\n }\n return (...args) => {\n const value = setValueCurveAtTime.apply(audioParam, args);\n createScriptProcessorNode();\n return value;\n };\n })(audioParam.setValueCurveAtTime);\n return audioParam;\n };\n return {\n forwardX: createFakeAudioParam(0, 0, createSetOrientation(0)),\n forwardY: createFakeAudioParam(1, 0, createSetOrientation(1)),\n forwardZ: createFakeAudioParam(2, -1, createSetOrientation(2)),\n positionX: createFakeAudioParam(6, 0, createSetPosition(0)),\n positionY: createFakeAudioParam(7, 0, createSetPosition(1)),\n positionZ: createFakeAudioParam(8, 0, createSetPosition(2)),\n upX: createFakeAudioParam(3, 0, createSetOrientation(3)),\n upY: createFakeAudioParam(4, 1, createSetOrientation(4)),\n upZ: createFakeAudioParam(5, 0, createSetOrientation(5))\n };\n };\n const { forwardX, forwardY, forwardZ, positionX, positionY, positionZ, upX, upY, upZ } = nativeListener.forwardX === undefined ? createFakeAudioParams() : nativeListener;\n return {\n get forwardX() {\n return forwardX;\n },\n get forwardY() {\n return forwardY;\n },\n get forwardZ() {\n return forwardZ;\n },\n get positionX() {\n return positionX;\n },\n get positionY() {\n return positionY;\n },\n get positionZ() {\n return positionZ;\n },\n get upX() {\n return upX;\n },\n get upY() {\n return upY;\n },\n get upZ() {\n return upZ;\n }\n };\n };\n};\n//# sourceMappingURL=audio-listener-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-node.js\nconst isAudioNode = (audioNodeOrAudioParam) => {\n return \'context\' in audioNodeOrAudioParam;\n};\n//# sourceMappingURL=audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/audio-node-output-connection.js\n\nconst isAudioNodeOutputConnection = (outputConnection) => {\n return isAudioNode(outputConnection[0]);\n};\n//# sourceMappingURL=audio-node-output-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/insert-element-in-set.js\nconst insertElementInSet = (set, element, predicate, ignoreDuplicates) => {\n for (const lmnt of set) {\n if (predicate(lmnt)) {\n if (ignoreDuplicates) {\n return false;\n }\n throw Error(\'The set contains at least one similar element.\');\n }\n }\n set.add(element);\n return true;\n};\n//# sourceMappingURL=insert-element-in-set.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/add-active-input-connection-to-audio-param.js\n\nconst addActiveInputConnectionToAudioParam = (activeInputs, source, [output, eventListener], ignoreDuplicates) => {\n insertElementInSet(activeInputs, [source, output, eventListener], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output, ignoreDuplicates);\n};\n//# sourceMappingURL=add-active-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/add-passive-input-connection-to-audio-param.js\n\nconst addPassiveInputConnectionToAudioParam = (passiveInputs, [source, output, eventListener], ignoreDuplicates) => {\n const passiveInputConnections = passiveInputs.get(source);\n if (passiveInputConnections === undefined) {\n passiveInputs.set(source, new Set([[output, eventListener]]));\n }\n else {\n insertElementInSet(passiveInputConnections, [output, eventListener], (passiveInputConnection) => passiveInputConnection[0] === output, ignoreDuplicates);\n }\n};\n//# sourceMappingURL=add-passive-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/native-audio-node-faker.js\nconst isNativeAudioNodeFaker = (nativeAudioNodeOrNativeAudioNodeFaker) => {\n return \'inputs\' in nativeAudioNodeOrNativeAudioNodeFaker;\n};\n//# sourceMappingURL=native-audio-node-faker.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/connect-native-audio-node-to-native-audio-node.js\n\nconst connectNativeAudioNodeToNativeAudioNode = (nativeSourceAudioNode, nativeDestinationAudioNode, output, input) => {\n if (isNativeAudioNodeFaker(nativeDestinationAudioNode)) {\n const fakeNativeDestinationAudioNode = nativeDestinationAudioNode.inputs[input];\n nativeSourceAudioNode.connect(fakeNativeDestinationAudioNode, output, 0);\n return [fakeNativeDestinationAudioNode, output, 0];\n }\n nativeSourceAudioNode.connect(nativeDestinationAudioNode, output, input);\n return [nativeDestinationAudioNode, output, input];\n};\n//# sourceMappingURL=connect-native-audio-node-to-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-active-input-connection.js\nconst deleteActiveInputConnection = (activeInputConnections, source, output) => {\n for (const activeInputConnection of activeInputConnections) {\n if (activeInputConnection[0] === source && activeInputConnection[1] === output) {\n activeInputConnections.delete(activeInputConnection);\n return activeInputConnection;\n }\n }\n return null;\n};\n//# sourceMappingURL=delete-active-input-connection.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-active-input-connection-to-audio-param.js\n\nconst deleteActiveInputConnectionToAudioParam = (activeInputs, source, output) => {\n return pickElementFromSet(activeInputs, (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output);\n};\n//# sourceMappingURL=delete-active-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-event-listeners-of-audio-node.js\n\nconst deleteEventListenerOfAudioNode = (audioNode, eventListener) => {\n const eventListeners = getEventListenersOfAudioNode(audioNode);\n if (!eventListeners.delete(eventListener)) {\n throw new Error(\'Missing the expected event listener.\');\n }\n};\n//# sourceMappingURL=delete-event-listeners-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/delete-passive-input-connection-to-audio-param.js\n\n\nconst deletePassiveInputConnectionToAudioParam = (passiveInputs, source, output) => {\n const passiveInputConnections = getValueForKey(passiveInputs, source);\n const matchingConnection = pickElementFromSet(passiveInputConnections, (passiveInputConnection) => passiveInputConnection[0] === output);\n if (passiveInputConnections.size === 0) {\n passiveInputs.delete(source);\n }\n return matchingConnection;\n};\n//# sourceMappingURL=delete-passive-input-connection-to-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/disconnect-native-audio-node-from-native-audio-node.js\n\nconst disconnectNativeAudioNodeFromNativeAudioNode = (nativeSourceAudioNode, nativeDestinationAudioNode, output, input) => {\n if (isNativeAudioNodeFaker(nativeDestinationAudioNode)) {\n nativeSourceAudioNode.disconnect(nativeDestinationAudioNode.inputs[input], output, 0);\n }\n else {\n nativeSourceAudioNode.disconnect(nativeDestinationAudioNode, output, input);\n }\n};\n//# sourceMappingURL=disconnect-native-audio-node-from-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-native-audio-node.js\n\n\nconst getNativeAudioNode = (audioNode) => {\n return getValueForKey(AUDIO_NODE_STORE, audioNode);\n};\n//# sourceMappingURL=get-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-native-audio-param.js\n\n\nconst getNativeAudioParam = (audioParam) => {\n return getValueForKey(AUDIO_PARAM_STORE, audioParam);\n};\n//# sourceMappingURL=get-native-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-part-of-a-cycle.js\n\nconst isPartOfACycle = (audioNode) => {\n return CYCLE_COUNTERS.has(audioNode);\n};\n//# sourceMappingURL=is-part-of-a-cycle.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-passive-audio-node.js\n\nconst isPassiveAudioNode = (audioNode) => {\n return !ACTIVE_AUDIO_NODE_STORE.has(audioNode);\n};\n//# sourceMappingURL=is-passive-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-node-disconnect-method-support.js\nconst testAudioNodeDisconnectMethodSupport = (nativeAudioContext, nativeAudioWorkletNodeConstructor) => {\n return new Promise((resolve) => {\n /*\n * This bug existed in Safari up until v14.0.2. Since AudioWorklets were not supported in Safari until v14.1 the presence of the\n * constructor for an AudioWorkletNode can be used here to skip the test.\n */\n if (nativeAudioWorkletNodeConstructor !== null) {\n resolve(true);\n }\n else {\n const analyzer = nativeAudioContext.createScriptProcessor(256, 1, 1); // tslint:disable-line deprecation\n const dummy = nativeAudioContext.createGain();\n // Bug #95: Safari does not play one sample buffers.\n const ones = nativeAudioContext.createBuffer(1, 2, 44100);\n const channelData = ones.getChannelData(0);\n channelData[0] = 1;\n channelData[1] = 1;\n const source = nativeAudioContext.createBufferSource();\n source.buffer = ones;\n source.loop = true;\n source.connect(analyzer).connect(nativeAudioContext.destination);\n source.connect(dummy);\n source.disconnect(dummy);\n // tslint:disable-next-line:deprecation\n analyzer.onaudioprocess = (event) => {\n const chnnlDt = event.inputBuffer.getChannelData(0); // tslint:disable-line deprecation\n if (Array.prototype.some.call(chnnlDt, (sample) => sample === 1)) {\n resolve(true);\n }\n else {\n resolve(false);\n }\n source.stop();\n analyzer.onaudioprocess = null; // tslint:disable-line:deprecation\n source.disconnect(analyzer);\n analyzer.disconnect(nativeAudioContext.destination);\n };\n source.start();\n }\n });\n};\n//# sourceMappingURL=test-audio-node-disconnect-method-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/visit-each-audio-node-once.js\nconst visitEachAudioNodeOnce = (cycles, visitor) => {\n const counts = new Map();\n for (const cycle of cycles) {\n for (const audioNode of cycle) {\n const count = counts.get(audioNode);\n counts.set(audioNode, count === undefined ? 1 : count + 1);\n }\n }\n counts.forEach((count, audioNode) => visitor(audioNode, count));\n};\n//# sourceMappingURL=visit-each-audio-node-once.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/native-audio-node.js\nconst isNativeAudioNode = (nativeAudioNodeOrAudioParam) => {\n return \'context\' in nativeAudioNodeOrAudioParam;\n};\n//# sourceMappingURL=native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-node-disconnect-method.js\n\nconst wrapAudioNodeDisconnectMethod = (nativeAudioNode) => {\n const connections = new Map();\n nativeAudioNode.connect = ((connect) => {\n // tslint:disable-next-line:invalid-void no-inferrable-types\n return (destination, output = 0, input = 0) => {\n const returnValue = isNativeAudioNode(destination) ? connect(destination, output, input) : connect(destination, output);\n // Save the new connection only if the calls to connect above didn\'t throw an error.\n const connectionsToDestination = connections.get(destination);\n if (connectionsToDestination === undefined) {\n connections.set(destination, [{ input, output }]);\n }\n else {\n if (connectionsToDestination.every((connection) => connection.input !== input || connection.output !== output)) {\n connectionsToDestination.push({ input, output });\n }\n }\n return returnValue;\n };\n })(nativeAudioNode.connect.bind(nativeAudioNode));\n nativeAudioNode.disconnect = ((disconnect) => {\n return (destinationOrOutput, output, input) => {\n disconnect.apply(nativeAudioNode);\n if (destinationOrOutput === undefined) {\n connections.clear();\n }\n else if (typeof destinationOrOutput === \'number\') {\n for (const [destination, connectionsToDestination] of connections) {\n const filteredConnections = connectionsToDestination.filter((connection) => connection.output !== destinationOrOutput);\n if (filteredConnections.length === 0) {\n connections.delete(destination);\n }\n else {\n connections.set(destination, filteredConnections);\n }\n }\n }\n else if (connections.has(destinationOrOutput)) {\n if (output === undefined) {\n connections.delete(destinationOrOutput);\n }\n else {\n const connectionsToDestination = connections.get(destinationOrOutput);\n if (connectionsToDestination !== undefined) {\n const filteredConnections = connectionsToDestination.filter((connection) => connection.output !== output && (connection.input !== input || input === undefined));\n if (filteredConnections.length === 0) {\n connections.delete(destinationOrOutput);\n }\n else {\n connections.set(destinationOrOutput, filteredConnections);\n }\n }\n }\n }\n for (const [destination, connectionsToDestination] of connections) {\n connectionsToDestination.forEach((connection) => {\n if (isNativeAudioNode(destination)) {\n nativeAudioNode.connect(destination, connection.output, connection.input);\n }\n else {\n nativeAudioNode.connect(destination, connection.output);\n }\n });\n }\n };\n })(nativeAudioNode.disconnect);\n};\n//# sourceMappingURL=wrap-audio-node-disconnect-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-node-constructor.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst addConnectionToAudioParamOfAudioContext = (source, destination, output, isOffline) => {\n const { activeInputs, passiveInputs } = getAudioParamConnections(destination);\n const { outputs } = getAudioNodeConnections(source);\n const eventListeners = getEventListenersOfAudioNode(source);\n const eventListener = (isActive) => {\n const nativeAudioNode = getNativeAudioNode(source);\n const nativeAudioParam = getNativeAudioParam(destination);\n if (isActive) {\n const partialConnection = deletePassiveInputConnectionToAudioParam(passiveInputs, source, output);\n addActiveInputConnectionToAudioParam(activeInputs, source, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n nativeAudioNode.connect(nativeAudioParam, output);\n }\n }\n else {\n const partialConnection = deleteActiveInputConnectionToAudioParam(activeInputs, source, output);\n addPassiveInputConnectionToAudioParam(passiveInputs, partialConnection, false);\n if (!isOffline && !isPartOfACycle(source)) {\n nativeAudioNode.disconnect(nativeAudioParam, output);\n }\n }\n };\n if (insertElementInSet(outputs, [destination, output], (outputConnection) => outputConnection[0] === destination && outputConnection[1] === output, true)) {\n eventListeners.add(eventListener);\n if (isActiveAudioNode(source)) {\n addActiveInputConnectionToAudioParam(activeInputs, source, [output, eventListener], true);\n }\n else {\n addPassiveInputConnectionToAudioParam(passiveInputs, [source, output, eventListener], true);\n }\n return true;\n }\n return false;\n};\nconst deleteInputConnectionOfAudioNode = (source, destination, output, input) => {\n const { activeInputs, passiveInputs } = getAudioNodeConnections(destination);\n const activeInputConnection = deleteActiveInputConnection(activeInputs[input], source, output);\n if (activeInputConnection === null) {\n const passiveInputConnection = deletePassiveInputConnectionToAudioNode(passiveInputs, source, output, input);\n return [passiveInputConnection[2], false];\n }\n return [activeInputConnection[2], true];\n};\nconst deleteInputConnectionOfAudioParam = (source, destination, output) => {\n const { activeInputs, passiveInputs } = getAudioParamConnections(destination);\n const activeInputConnection = deleteActiveInputConnection(activeInputs, source, output);\n if (activeInputConnection === null) {\n const passiveInputConnection = deletePassiveInputConnectionToAudioParam(passiveInputs, source, output);\n return [passiveInputConnection[1], false];\n }\n return [activeInputConnection[2], true];\n};\nconst deleteInputsOfAudioNode = (source, isOffline, destination, output, input) => {\n const [listener, isActive] = deleteInputConnectionOfAudioNode(source, destination, output, input);\n if (listener !== null) {\n deleteEventListenerOfAudioNode(source, listener);\n if (isActive && !isOffline && !isPartOfACycle(source)) {\n disconnectNativeAudioNodeFromNativeAudioNode(getNativeAudioNode(source), getNativeAudioNode(destination), output, input);\n }\n }\n if (isActiveAudioNode(destination)) {\n const { activeInputs } = getAudioNodeConnections(destination);\n setInternalStateToPassiveWhenNecessary(destination, activeInputs);\n }\n};\nconst deleteInputsOfAudioParam = (source, isOffline, destination, output) => {\n const [listener, isActive] = deleteInputConnectionOfAudioParam(source, destination, output);\n if (listener !== null) {\n deleteEventListenerOfAudioNode(source, listener);\n if (isActive && !isOffline && !isPartOfACycle(source)) {\n getNativeAudioNode(source).disconnect(getNativeAudioParam(destination), output);\n }\n }\n};\nconst deleteAnyConnection = (source, isOffline) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n const destinations = [];\n for (const outputConnection of audioNodeConnectionsOfSource.outputs) {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n destinations.push(outputConnection[0]);\n }\n audioNodeConnectionsOfSource.outputs.clear();\n return destinations;\n};\nconst deleteConnectionAtOutput = (source, isOffline, output) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n const destinations = [];\n for (const outputConnection of audioNodeConnectionsOfSource.outputs) {\n if (outputConnection[1] === output) {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n destinations.push(outputConnection[0]);\n audioNodeConnectionsOfSource.outputs.delete(outputConnection);\n }\n }\n return destinations;\n};\nconst deleteConnectionToDestination = (source, isOffline, destination, output, input) => {\n const audioNodeConnectionsOfSource = getAudioNodeConnections(source);\n return Array.from(audioNodeConnectionsOfSource.outputs)\n .filter((outputConnection) => outputConnection[0] === destination &&\n (output === undefined || outputConnection[1] === output) &&\n (input === undefined || outputConnection[2] === input))\n .map((outputConnection) => {\n if (isAudioNodeOutputConnection(outputConnection)) {\n deleteInputsOfAudioNode(source, isOffline, ...outputConnection);\n }\n else {\n deleteInputsOfAudioParam(source, isOffline, ...outputConnection);\n }\n audioNodeConnectionsOfSource.outputs.delete(outputConnection);\n return outputConnection[0];\n });\n};\nconst createAudioNodeConstructor = (addAudioNodeConnections, addConnectionToAudioNode, cacheTestResult, createIncrementCycleCounter, createIndexSizeError, createInvalidAccessError, createNotSupportedError, decrementCycleCounter, detectCycles, eventTargetConstructor, getNativeContext, isNativeAudioContext, isNativeAudioNode, isNativeAudioParam, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor) => {\n return class AudioNode extends eventTargetConstructor {\n constructor(context, isActive, nativeAudioNode, audioNodeRenderer) {\n super(nativeAudioNode);\n this._context = context;\n this._nativeAudioNode = nativeAudioNode;\n const nativeContext = getNativeContext(context);\n // Bug #12: Safari does not support to disconnect a specific destination.\n if (isNativeAudioContext(nativeContext) &&\n true !==\n cacheTestResult(testAudioNodeDisconnectMethodSupport, () => {\n return testAudioNodeDisconnectMethodSupport(nativeContext, nativeAudioWorkletNodeConstructor);\n })) {\n wrapAudioNodeDisconnectMethod(nativeAudioNode);\n }\n AUDIO_NODE_STORE.set(this, nativeAudioNode);\n EVENT_LISTENERS.set(this, new Set());\n if (context.state !== \'closed\' && isActive) {\n setInternalStateToActive(this);\n }\n addAudioNodeConnections(this, audioNodeRenderer, nativeAudioNode);\n }\n get channelCount() {\n return this._nativeAudioNode.channelCount;\n }\n set channelCount(value) {\n this._nativeAudioNode.channelCount = value;\n }\n get channelCountMode() {\n return this._nativeAudioNode.channelCountMode;\n }\n set channelCountMode(value) {\n this._nativeAudioNode.channelCountMode = value;\n }\n get channelInterpretation() {\n return this._nativeAudioNode.channelInterpretation;\n }\n set channelInterpretation(value) {\n this._nativeAudioNode.channelInterpretation = value;\n }\n get context() {\n return this._context;\n }\n get numberOfInputs() {\n return this._nativeAudioNode.numberOfInputs;\n }\n get numberOfOutputs() {\n return this._nativeAudioNode.numberOfOutputs;\n }\n // tslint:disable-next-line:invalid-void\n connect(destination, output = 0, input = 0) {\n // Bug #174: Safari does expose a wrong numberOfOutputs for MediaStreamAudioDestinationNodes.\n if (output < 0 || output >= this._nativeAudioNode.numberOfOutputs) {\n throw createIndexSizeError();\n }\n const nativeContext = getNativeContext(this._context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (isNativeAudioNode(destination) || isNativeAudioParam(destination)) {\n throw createInvalidAccessError();\n }\n if (isAudioNode(destination)) {\n const nativeDestinationAudioNode = getNativeAudioNode(destination);\n try {\n const connection = connectNativeAudioNodeToNativeAudioNode(this._nativeAudioNode, nativeDestinationAudioNode, output, input);\n const isPassive = isPassiveAudioNode(this);\n if (isOffline || isPassive) {\n this._nativeAudioNode.disconnect(...connection);\n }\n if (this.context.state !== \'closed\' && !isPassive && isPassiveAudioNode(destination)) {\n setInternalStateToActive(destination);\n }\n }\n catch (err) {\n // Bug #41: Safari does not throw the correct exception so far.\n if (err.code === 12) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n const isNewConnectionToAudioNode = addConnectionToAudioNode(this, destination, output, input, isOffline);\n // Bug #164: Only Firefox detects cycles so far.\n if (isNewConnectionToAudioNode) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, createIncrementCycleCounter(isOffline));\n }\n return destination;\n }\n const nativeAudioParam = getNativeAudioParam(destination);\n /*\n * Bug #73, #147 & #153: Safari does not support to connect an input signal to the playbackRate AudioParam of an\n * AudioBufferSourceNode. This can\'t be easily detected and that\'s why the outdated name property is used here to identify\n * Safari. In addition to that the maxValue property is used to only detect the affected versions below v14.0.2.\n */\n if (nativeAudioParam.name === \'playbackRate\' && nativeAudioParam.maxValue === 1024) {\n throw createNotSupportedError();\n }\n try {\n this._nativeAudioNode.connect(nativeAudioParam, output);\n if (isOffline || isPassiveAudioNode(this)) {\n this._nativeAudioNode.disconnect(nativeAudioParam, output);\n }\n }\n catch (err) {\n // Bug #58: Safari doesn\'t throw an InvalidAccessError yet.\n if (err.code === 12) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n const isNewConnectionToAudioParam = addConnectionToAudioParamOfAudioContext(this, destination, output, isOffline);\n // Bug #164: Only Firefox detects cycles so far.\n if (isNewConnectionToAudioParam) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, createIncrementCycleCounter(isOffline));\n }\n }\n disconnect(destinationOrOutput, output, input) {\n let destinations;\n const nativeContext = getNativeContext(this._context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (destinationOrOutput === undefined) {\n destinations = deleteAnyConnection(this, isOffline);\n }\n else if (typeof destinationOrOutput === \'number\') {\n if (destinationOrOutput < 0 || destinationOrOutput >= this.numberOfOutputs) {\n throw createIndexSizeError();\n }\n destinations = deleteConnectionAtOutput(this, isOffline, destinationOrOutput);\n }\n else {\n if (output !== undefined && (output < 0 || output >= this.numberOfOutputs)) {\n throw createIndexSizeError();\n }\n if (isAudioNode(destinationOrOutput) && input !== undefined && (input < 0 || input >= destinationOrOutput.numberOfInputs)) {\n throw createIndexSizeError();\n }\n destinations = deleteConnectionToDestination(this, isOffline, destinationOrOutput, output, input);\n if (destinations.length === 0) {\n throw createInvalidAccessError();\n }\n }\n // Bug #164: Only Firefox detects cycles so far.\n for (const destination of destinations) {\n const cycles = detectCycles([this], destination);\n visitEachAudioNodeOnce(cycles, decrementCycleCounter);\n }\n }\n };\n};\n//# sourceMappingURL=audio-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-param-factory.js\n\nconst createAudioParamFactory = (addAudioParamConnections, audioParamAudioNodeStore, audioParamStore, createAudioParamRenderer, createCancelAndHoldAutomationEvent, createCancelScheduledValuesAutomationEvent, createExponentialRampToValueAutomationEvent, createLinearRampToValueAutomationEvent, createSetTargetAutomationEvent, createSetValueAutomationEvent, createSetValueCurveAutomationEvent, nativeAudioContextConstructor, setValueAtTimeUntilPossible) => {\n return (audioNode, isAudioParamOfOfflineAudioContext, nativeAudioParam, maxValue = null, minValue = null) => {\n // Bug #196 Only Safari sets the defaultValue to the initial value.\n const defaultValue = nativeAudioParam.value;\n const automationEventList = new bundle.AutomationEventList(defaultValue);\n const audioParamRenderer = isAudioParamOfOfflineAudioContext ? createAudioParamRenderer(automationEventList) : null;\n const audioParam = {\n get defaultValue() {\n return defaultValue;\n },\n get maxValue() {\n return maxValue === null ? nativeAudioParam.maxValue : maxValue;\n },\n get minValue() {\n return minValue === null ? nativeAudioParam.minValue : minValue;\n },\n get value() {\n return nativeAudioParam.value;\n },\n set value(value) {\n nativeAudioParam.value = value;\n // Bug #98: Firefox & Safari do not yet treat the value setter like a call to setValueAtTime().\n audioParam.setValueAtTime(value, audioNode.context.currentTime);\n },\n cancelAndHoldAtTime(cancelTime) {\n // Bug #28: Firefox & Safari do not yet implement cancelAndHoldAtTime().\n if (typeof nativeAudioParam.cancelAndHoldAtTime === \'function\') {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelAndHoldAutomationEvent(cancelTime));\n nativeAudioParam.cancelAndHoldAtTime(cancelTime);\n }\n else {\n const previousLastEvent = Array.from(automationEventList).pop();\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelAndHoldAutomationEvent(cancelTime));\n const currentLastEvent = Array.from(automationEventList).pop();\n nativeAudioParam.cancelScheduledValues(cancelTime);\n if (previousLastEvent !== currentLastEvent && currentLastEvent !== undefined) {\n if (currentLastEvent.type === \'exponentialRampToValue\') {\n nativeAudioParam.exponentialRampToValueAtTime(currentLastEvent.value, currentLastEvent.endTime);\n }\n else if (currentLastEvent.type === \'linearRampToValue\') {\n nativeAudioParam.linearRampToValueAtTime(currentLastEvent.value, currentLastEvent.endTime);\n }\n else if (currentLastEvent.type === \'setValue\') {\n nativeAudioParam.setValueAtTime(currentLastEvent.value, currentLastEvent.startTime);\n }\n else if (currentLastEvent.type === \'setValueCurve\') {\n nativeAudioParam.setValueCurveAtTime(currentLastEvent.values, currentLastEvent.startTime, currentLastEvent.duration);\n }\n }\n }\n return audioParam;\n },\n cancelScheduledValues(cancelTime) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createCancelScheduledValuesAutomationEvent(cancelTime));\n nativeAudioParam.cancelScheduledValues(cancelTime);\n return audioParam;\n },\n exponentialRampToValueAtTime(value, endTime) {\n // Bug #45: Safari does not throw an error yet.\n if (value === 0) {\n throw new RangeError();\n }\n // Bug #187: Safari does not throw an error yet.\n if (!Number.isFinite(endTime) || endTime < 0) {\n throw new RangeError();\n }\n const currentTime = audioNode.context.currentTime;\n if (audioParamRenderer === null) {\n automationEventList.flush(currentTime);\n }\n // Bug #194: Firefox does not implicitly call setValueAtTime() if there is no previous event.\n if (Array.from(automationEventList).length === 0) {\n automationEventList.add(createSetValueAutomationEvent(defaultValue, currentTime));\n nativeAudioParam.setValueAtTime(defaultValue, currentTime);\n }\n automationEventList.add(createExponentialRampToValueAutomationEvent(value, endTime));\n nativeAudioParam.exponentialRampToValueAtTime(value, endTime);\n return audioParam;\n },\n linearRampToValueAtTime(value, endTime) {\n const currentTime = audioNode.context.currentTime;\n if (audioParamRenderer === null) {\n automationEventList.flush(currentTime);\n }\n // Bug #195: Firefox does not implicitly call setValueAtTime() if there is no previous event.\n if (Array.from(automationEventList).length === 0) {\n automationEventList.add(createSetValueAutomationEvent(defaultValue, currentTime));\n nativeAudioParam.setValueAtTime(defaultValue, currentTime);\n }\n automationEventList.add(createLinearRampToValueAutomationEvent(value, endTime));\n nativeAudioParam.linearRampToValueAtTime(value, endTime);\n return audioParam;\n },\n setTargetAtTime(target, startTime, timeConstant) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetTargetAutomationEvent(target, startTime, timeConstant));\n nativeAudioParam.setTargetAtTime(target, startTime, timeConstant);\n return audioParam;\n },\n setValueAtTime(value, startTime) {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueAutomationEvent(value, startTime));\n nativeAudioParam.setValueAtTime(value, startTime);\n return audioParam;\n },\n setValueCurveAtTime(values, startTime, duration) {\n // Bug 183: Safari only accepts a Float32Array.\n const convertedValues = values instanceof Float32Array ? values : new Float32Array(values);\n /*\n * Bug #152: Safari does not correctly interpolate the values of the curve.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the\n * existence of the webkitAudioContext is used as a workaround here.\n */\n if (nativeAudioContextConstructor !== null && nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n const endTime = startTime + duration;\n const sampleRate = audioNode.context.sampleRate;\n const firstSample = Math.ceil(startTime * sampleRate);\n const lastSample = Math.floor(endTime * sampleRate);\n const numberOfInterpolatedValues = lastSample - firstSample;\n const interpolatedValues = new Float32Array(numberOfInterpolatedValues);\n for (let i = 0; i < numberOfInterpolatedValues; i += 1) {\n const theoreticIndex = ((convertedValues.length - 1) / duration) * ((firstSample + i) / sampleRate - startTime);\n const lowerIndex = Math.floor(theoreticIndex);\n const upperIndex = Math.ceil(theoreticIndex);\n interpolatedValues[i] =\n lowerIndex === upperIndex\n ? convertedValues[lowerIndex]\n : (1 - (theoreticIndex - lowerIndex)) * convertedValues[lowerIndex] +\n (1 - (upperIndex - theoreticIndex)) * convertedValues[upperIndex];\n }\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueCurveAutomationEvent(interpolatedValues, startTime, duration));\n nativeAudioParam.setValueCurveAtTime(interpolatedValues, startTime, duration);\n const timeOfLastSample = lastSample / sampleRate;\n if (timeOfLastSample < endTime) {\n setValueAtTimeUntilPossible(audioParam, interpolatedValues[interpolatedValues.length - 1], timeOfLastSample);\n }\n setValueAtTimeUntilPossible(audioParam, convertedValues[convertedValues.length - 1], endTime);\n }\n else {\n if (audioParamRenderer === null) {\n automationEventList.flush(audioNode.context.currentTime);\n }\n automationEventList.add(createSetValueCurveAutomationEvent(convertedValues, startTime, duration));\n nativeAudioParam.setValueCurveAtTime(convertedValues, startTime, duration);\n }\n return audioParam;\n }\n };\n audioParamStore.set(audioParam, nativeAudioParam);\n audioParamAudioNodeStore.set(audioParam, audioNode);\n addAudioParamConnections(audioParam, audioParamRenderer);\n return audioParam;\n };\n};\n//# sourceMappingURL=audio-param-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-param-renderer.js\nconst createAudioParamRenderer = (automationEventList) => {\n return {\n replay(audioParam) {\n for (const automationEvent of automationEventList) {\n if (automationEvent.type === \'exponentialRampToValue\') {\n const { endTime, value } = automationEvent;\n audioParam.exponentialRampToValueAtTime(value, endTime);\n }\n else if (automationEvent.type === \'linearRampToValue\') {\n const { endTime, value } = automationEvent;\n audioParam.linearRampToValueAtTime(value, endTime);\n }\n else if (automationEvent.type === \'setTarget\') {\n const { startTime, target, timeConstant } = automationEvent;\n audioParam.setTargetAtTime(target, startTime, timeConstant);\n }\n else if (automationEvent.type === \'setValue\') {\n const { startTime, value } = automationEvent;\n audioParam.setValueAtTime(value, startTime);\n }\n else if (automationEvent.type === \'setValueCurve\') {\n const { duration, startTime, values } = automationEvent;\n audioParam.setValueCurveAtTime(values, startTime, duration);\n }\n else {\n throw new Error("Can\'t apply an unknown automation.");\n }\n }\n }\n };\n};\n//# sourceMappingURL=audio-param-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/read-only-map.js\nclass ReadOnlyMap {\n constructor(parameters) {\n this._map = new Map(parameters);\n }\n get size() {\n return this._map.size;\n }\n entries() {\n return this._map.entries();\n }\n forEach(callback, thisArg = null) {\n return this._map.forEach((value, key) => callback.call(thisArg, value, key, this));\n }\n get(name) {\n return this._map.get(name);\n }\n has(name) {\n return this._map.has(name);\n }\n keys() {\n return this._map.keys();\n }\n values() {\n return this._map.values();\n }\n}\n//# sourceMappingURL=read-only-map.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-worklet-node-constructor.js\n\n\nconst audio_worklet_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n // Bug #61: The channelCountMode should be \'max\' according to the spec but is set to \'explicit\' to achieve consistent behavior.\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {},\n processorOptions: {}\n};\nconst createAudioWorkletNodeConstructor = (addUnrenderedAudioWorkletNode, audioNodeConstructor, createAudioParam, createAudioWorkletNodeRenderer, createNativeAudioWorkletNode, getAudioNodeConnections, getBackupOfflineAudioContext, getNativeContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, sanitizeAudioWorkletNodeOptions, setActiveAudioWorkletNodeInputs, testAudioWorkletNodeOptionsClonability, wrapEventListener) => {\n return class AudioWorkletNode extends audioNodeConstructor {\n constructor(context, name, options) {\n var _a;\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const mergedOptions = sanitizeAudioWorkletNodeOptions({ ...audio_worklet_node_constructor_DEFAULT_OPTIONS, ...options });\n // Bug #191: Safari doesn\'t throw an error if the options aren\'t clonable.\n testAudioWorkletNodeOptionsClonability(mergedOptions);\n const nodeNameToProcessorConstructorMap = NODE_NAME_TO_PROCESSOR_CONSTRUCTOR_MAPS.get(nativeContext);\n const processorConstructor = nodeNameToProcessorConstructorMap === null || nodeNameToProcessorConstructorMap === void 0 ? void 0 : nodeNameToProcessorConstructorMap.get(name);\n // Bug #186: Chrome and Edge do not allow to create an AudioWorkletNode on a closed AudioContext.\n const nativeContextOrBackupOfflineAudioContext = isOffline || nativeContext.state !== \'closed\'\n ? nativeContext\n : (_a = getBackupOfflineAudioContext(nativeContext)) !== null && _a !== void 0 ? _a : nativeContext;\n const nativeAudioWorkletNode = createNativeAudioWorkletNode(nativeContextOrBackupOfflineAudioContext, isOffline ? null : context.baseLatency, nativeAudioWorkletNodeConstructor, name, processorConstructor, mergedOptions);\n const audioWorkletNodeRenderer = ((isOffline ? createAudioWorkletNodeRenderer(name, mergedOptions, processorConstructor) : null));\n /*\n * @todo Add a mechanism to switch an AudioWorkletNode to passive once the process() function of the AudioWorkletProcessor\n * returns false.\n */\n super(context, true, nativeAudioWorkletNode, audioWorkletNodeRenderer);\n const parameters = [];\n nativeAudioWorkletNode.parameters.forEach((nativeAudioParam, nm) => {\n const audioParam = createAudioParam(this, isOffline, nativeAudioParam);\n parameters.push([nm, audioParam]);\n });\n this._nativeAudioWorkletNode = nativeAudioWorkletNode;\n this._onprocessorerror = null;\n this._parameters = new ReadOnlyMap(parameters);\n /*\n * Bug #86 & #87: Invoking the renderer of an AudioWorkletNode might be necessary if it has no direct or indirect connection to\n * the destination.\n */\n if (isOffline) {\n addUnrenderedAudioWorkletNode(nativeContext, this);\n }\n const { activeInputs } = getAudioNodeConnections(this);\n setActiveAudioWorkletNodeInputs(nativeAudioWorkletNode, activeInputs);\n }\n get onprocessorerror() {\n return this._onprocessorerror;\n }\n set onprocessorerror(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeAudioWorkletNode.onprocessorerror = wrappedListener;\n const nativeOnProcessorError = this._nativeAudioWorkletNode.onprocessorerror;\n this._onprocessorerror =\n nativeOnProcessorError !== null && nativeOnProcessorError === wrappedListener\n ? value\n : nativeOnProcessorError;\n }\n get parameters() {\n if (this._parameters === null) {\n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n return this._nativeAudioWorkletNode.parameters;\n }\n return this._parameters;\n }\n get port() {\n return this._nativeAudioWorkletNode.port;\n }\n };\n};\n//# sourceMappingURL=audio-worklet-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/copy-from-channel.js\nfunction copyFromChannel(audioBuffer, \n// @todo There is currently no way to define something like { [ key: number | string ]: Float32Array }\nparent, key, channelNumber, bufferOffset) {\n if (typeof audioBuffer.copyFromChannel === \'function\') {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength === 0) {\n parent[key] = new Float32Array(128);\n }\n audioBuffer.copyFromChannel(parent[key], channelNumber, bufferOffset);\n // Bug #5: Safari does not support copyFromChannel().\n }\n else {\n const channelData = audioBuffer.getChannelData(channelNumber);\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength === 0) {\n parent[key] = channelData.slice(bufferOffset, bufferOffset + 128);\n }\n else {\n const slicedInput = new Float32Array(channelData.buffer, bufferOffset * Float32Array.BYTES_PER_ELEMENT, 128);\n parent[key].set(slicedInput);\n }\n }\n}\n//# sourceMappingURL=copy-from-channel.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/copy-to-channel.js\nconst copyToChannel = (audioBuffer, parent, key, channelNumber, bufferOffset) => {\n if (typeof audioBuffer.copyToChannel === \'function\') {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength !== 0) {\n audioBuffer.copyToChannel(parent[key], channelNumber, bufferOffset);\n }\n // Bug #5: Safari does not support copyToChannel().\n }\n else {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (parent[key].byteLength !== 0) {\n audioBuffer.getChannelData(channelNumber).set(parent[key], bufferOffset);\n }\n }\n};\n//# sourceMappingURL=copy-to-channel.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-nested-arrays.js\nconst createNestedArrays = (x, y) => {\n const arrays = [];\n for (let i = 0; i < x; i += 1) {\n const array = [];\n const length = typeof y === \'number\' ? y : y[i];\n for (let j = 0; j < length; j += 1) {\n array.push(new Float32Array(128));\n }\n arrays.push(array);\n }\n return arrays;\n};\n//# sourceMappingURL=create-nested-arrays.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-audio-worklet-processor.js\n\n\n\nconst getAudioWorkletProcessor = (nativeOfflineAudioContext, proxy) => {\n const nodeToProcessorMap = getValueForKey(NODE_TO_PROCESSOR_MAPS, nativeOfflineAudioContext);\n const nativeAudioWorkletNode = getNativeAudioNode(proxy);\n return getValueForKey(nodeToProcessorMap, nativeAudioWorkletNode);\n};\n//# sourceMappingURL=get-audio-worklet-processor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/audio-worklet-node-renderer-factory.js\n\n\n\n\n\n\nconst processBuffer = async (proxy, renderedBuffer, nativeOfflineAudioContext, options, outputChannelCount, processorConstructor, exposeCurrentFrameAndCurrentTime) => {\n // Ceil the length to the next full render quantum.\n // Bug #17: Safari does not yet expose the length.\n const length = renderedBuffer === null ? Math.ceil(proxy.context.length / 128) * 128 : renderedBuffer.length;\n const numberOfInputChannels = options.channelCount * options.numberOfInputs;\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const processedBuffer = numberOfOutputChannels === 0\n ? null\n : nativeOfflineAudioContext.createBuffer(numberOfOutputChannels, length, nativeOfflineAudioContext.sampleRate);\n if (processorConstructor === undefined) {\n throw new Error(\'Missing the processor constructor.\');\n }\n const audioNodeConnections = getAudioNodeConnections(proxy);\n const audioWorkletProcessor = await getAudioWorkletProcessor(nativeOfflineAudioContext, proxy);\n const inputs = createNestedArrays(options.numberOfInputs, options.channelCount);\n const outputs = createNestedArrays(options.numberOfOutputs, outputChannelCount);\n const parameters = Array.from(proxy.parameters.keys()).reduce((prmtrs, name) => ({ ...prmtrs, [name]: new Float32Array(128) }), {});\n for (let i = 0; i < length; i += 128) {\n if (options.numberOfInputs > 0 && renderedBuffer !== null) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < options.channelCount; k += 1) {\n copyFromChannel(renderedBuffer, inputs[j], k, k, i);\n }\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined && renderedBuffer !== null) {\n processorConstructor.parameterDescriptors.forEach(({ name }, index) => {\n copyFromChannel(renderedBuffer, parameters, name, numberOfInputChannels + index, i);\n });\n }\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (outputs[j][k].byteLength === 0) {\n outputs[j][k] = new Float32Array(128);\n }\n }\n }\n try {\n const potentiallyEmptyInputs = inputs.map((input, index) => {\n if (audioNodeConnections.activeInputs[index].size === 0) {\n return [];\n }\n return input;\n });\n const activeSourceFlag = exposeCurrentFrameAndCurrentTime(i / nativeOfflineAudioContext.sampleRate, nativeOfflineAudioContext.sampleRate, () => audioWorkletProcessor.process(potentiallyEmptyInputs, outputs, parameters));\n if (processedBuffer !== null) {\n for (let j = 0, outputChannelSplitterNodeOutput = 0; j < options.numberOfOutputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n copyToChannel(processedBuffer, outputs[j], k, outputChannelSplitterNodeOutput + k, i);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[j];\n }\n }\n if (!activeSourceFlag) {\n break;\n }\n }\n catch (error) {\n proxy.dispatchEvent(new ErrorEvent(\'processorerror\', {\n colno: error.colno,\n filename: error.filename,\n lineno: error.lineno,\n message: error.message\n }));\n break;\n }\n }\n return processedBuffer;\n};\nconst createAudioWorkletNodeRendererFactory = (connectAudioParam, connectMultipleOutputs, createNativeAudioBufferSourceNode, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, deleteUnrenderedAudioWorkletNode, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getNativeAudioNode, nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return (name, options, processorConstructor) => {\n const renderedNativeAudioNodes = new WeakMap();\n let processedBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioWorkletNode = getNativeAudioNode(proxy);\n let nativeOutputNodes = null;\n const nativeAudioWorkletNodeIsOwnedByContext = isOwnedByContext(nativeAudioWorkletNode, nativeOfflineAudioContext);\n const outputChannelCount = Array.isArray(options.outputChannelCount)\n ? options.outputChannelCount\n : Array.from(options.outputChannelCount);\n // Bug #61: Only Chrome, Edge & Firefox have an implementation of the AudioWorkletNode yet.\n if (nativeAudioWorkletNodeConstructor === null) {\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const outputChannelSplitterNode = createNativeChannelSplitterNode(nativeOfflineAudioContext, {\n channelCount: Math.max(1, numberOfOutputChannels),\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: Math.max(1, numberOfOutputChannels)\n });\n const outputChannelMergerNodes = [];\n for (let i = 0; i < proxy.numberOfOutputs; i += 1) {\n outputChannelMergerNodes.push(createNativeChannelMergerNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: outputChannelCount[i]\n }));\n }\n const outputGainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n });\n outputGainNode.connect = connectMultipleOutputs.bind(null, outputChannelMergerNodes);\n outputGainNode.disconnect = disconnectMultipleOutputs.bind(null, outputChannelMergerNodes);\n nativeOutputNodes = [outputChannelSplitterNode, outputChannelMergerNodes, outputGainNode];\n }\n else if (!nativeAudioWorkletNodeIsOwnedByContext) {\n nativeAudioWorkletNode = new nativeAudioWorkletNodeConstructor(nativeOfflineAudioContext, name);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeOutputNodes === null ? nativeAudioWorkletNode : nativeOutputNodes[2]);\n if (nativeOutputNodes !== null) {\n if (processedBufferPromise === null) {\n if (processorConstructor === undefined) {\n throw new Error(\'Missing the processor constructor.\');\n }\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n // Bug #47: The AudioDestinationNode in Safari gets not initialized correctly.\n const numberOfInputChannels = proxy.channelCount * proxy.numberOfInputs;\n const numberOfParameters = processorConstructor.parameterDescriptors === undefined ? 0 : processorConstructor.parameterDescriptors.length;\n const numberOfChannels = numberOfInputChannels + numberOfParameters;\n const renderBuffer = async () => {\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(numberOfChannels, \n // Ceil the length to the next full render quantum.\n // Bug #17: Safari does not yet expose the length.\n Math.ceil(proxy.context.length / 128) * 128, nativeOfflineAudioContext.sampleRate);\n const gainNodes = [];\n const inputChannelSplitterNodes = [];\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes.push(createNativeGainNode(partialOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n }));\n inputChannelSplitterNodes.push(createNativeChannelSplitterNode(partialOfflineAudioContext, {\n channelCount: options.channelCount,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: options.channelCount\n }));\n }\n const constantSourceNodes = await Promise.all(Array.from(proxy.parameters.values()).map(async (audioParam) => {\n const constantSourceNode = createNativeConstantSourceNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: audioParam.value\n });\n await renderAutomation(partialOfflineAudioContext, audioParam, constantSourceNode.offset);\n return constantSourceNode;\n }));\n const inputChannelMergerNode = createNativeChannelMergerNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: Math.max(1, numberOfInputChannels + numberOfParameters)\n });\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes[i].connect(inputChannelSplitterNodes[i]);\n for (let j = 0; j < options.channelCount; j += 1) {\n inputChannelSplitterNodes[i].connect(inputChannelMergerNode, j, i * options.channelCount + j);\n }\n }\n for (const [index, constantSourceNode] of constantSourceNodes.entries()) {\n constantSourceNode.connect(inputChannelMergerNode, 0, numberOfInputChannels + index);\n constantSourceNode.start(0);\n }\n inputChannelMergerNode.connect(partialOfflineAudioContext.destination);\n await Promise.all(gainNodes.map((gainNode) => renderInputsOfAudioNode(proxy, partialOfflineAudioContext, gainNode)));\n return renderNativeOfflineAudioContext(partialOfflineAudioContext);\n };\n processedBufferPromise = processBuffer(proxy, numberOfChannels === 0 ? null : await renderBuffer(), nativeOfflineAudioContext, options, outputChannelCount, processorConstructor, exposeCurrentFrameAndCurrentTime);\n }\n const processedBuffer = await processedBufferPromise;\n const audioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const [outputChannelSplitterNode, outputChannelMergerNodes, outputGainNode] = nativeOutputNodes;\n if (processedBuffer !== null) {\n audioBufferSourceNode.buffer = processedBuffer;\n audioBufferSourceNode.start(0);\n }\n audioBufferSourceNode.connect(outputChannelSplitterNode);\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < proxy.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.connect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n return outputGainNode;\n }\n if (!nativeAudioWorkletNodeIsOwnedByContext) {\n for (const [nm, audioParam] of proxy.parameters.entries()) {\n await renderAutomation(nativeOfflineAudioContext, audioParam, \n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n nativeAudioWorkletNode.parameters.get(nm));\n }\n }\n else {\n for (const [nm, audioParam] of proxy.parameters.entries()) {\n await connectAudioParam(nativeOfflineAudioContext, audioParam, \n // @todo The definition that TypeScript uses of the AudioParamMap is lacking many methods.\n nativeAudioWorkletNode.parameters.get(nm));\n }\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioWorkletNode);\n return nativeAudioWorkletNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n deleteUnrenderedAudioWorkletNode(nativeOfflineAudioContext, proxy);\n const renderedNativeAudioWorkletNodeOrGainNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioWorkletNodeOrGainNode !== undefined) {\n return Promise.resolve(renderedNativeAudioWorkletNodeOrGainNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=audio-worklet-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/base-audio-context-constructor.js\nconst createBaseAudioContextConstructor = (addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor) => {\n return class BaseAudioContext extends minimalBaseAudioContextConstructor {\n constructor(_nativeContext, numberOfChannels) {\n super(_nativeContext, numberOfChannels);\n this._nativeContext = _nativeContext;\n this._audioWorklet =\n addAudioWorkletModule === undefined\n ? undefined\n : {\n addModule: (moduleURL, options) => {\n return addAudioWorkletModule(this, moduleURL, options);\n }\n };\n }\n get audioWorklet() {\n return this._audioWorklet;\n }\n createAnalyser() {\n return new analyserNodeConstructor(this);\n }\n createBiquadFilter() {\n return new biquadFilterNodeConstructor(this);\n }\n createBuffer(numberOfChannels, length, sampleRate) {\n return new audioBufferConstructor({ length, numberOfChannels, sampleRate });\n }\n createBufferSource() {\n return new audioBufferSourceNodeConstructor(this);\n }\n createChannelMerger(numberOfInputs = 6) {\n return new channelMergerNodeConstructor(this, { numberOfInputs });\n }\n createChannelSplitter(numberOfOutputs = 6) {\n return new channelSplitterNodeConstructor(this, { numberOfOutputs });\n }\n createConstantSource() {\n return new constantSourceNodeConstructor(this);\n }\n createConvolver() {\n return new convolverNodeConstructor(this);\n }\n createDelay(maxDelayTime = 1) {\n return new delayNodeConstructor(this, { maxDelayTime });\n }\n createDynamicsCompressor() {\n return new dynamicsCompressorNodeConstructor(this);\n }\n createGain() {\n return new gainNodeConstructor(this);\n }\n createIIRFilter(feedforward, feedback) {\n return new iIRFilterNodeConstructor(this, { feedback, feedforward });\n }\n createOscillator() {\n return new oscillatorNodeConstructor(this);\n }\n createPanner() {\n return new pannerNodeConstructor(this);\n }\n createPeriodicWave(real, imag, constraints = { disableNormalization: false }) {\n return new periodicWaveConstructor(this, { ...constraints, imag, real });\n }\n createStereoPanner() {\n return new stereoPannerNodeConstructor(this);\n }\n createWaveShaper() {\n return new waveShaperNodeConstructor(this);\n }\n decodeAudioData(audioData, successCallback, errorCallback) {\n return decodeAudioData(this._nativeContext, audioData).then((audioBuffer) => {\n if (typeof successCallback === \'function\') {\n successCallback(audioBuffer);\n }\n return audioBuffer;\n }, (err) => {\n if (typeof errorCallback === \'function\') {\n errorCallback(err);\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=base-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/biquad-filter-node-constructor.js\n\nconst biquad_filter_node_constructor_DEFAULT_OPTIONS = {\n Q: 1,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n detune: 0,\n frequency: 350,\n gain: 0,\n type: \'lowpass\'\n};\nconst createBiquadFilterNodeConstructor = (audioNodeConstructor, createAudioParam, createBiquadFilterNodeRenderer, createInvalidAccessError, createNativeBiquadFilterNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class BiquadFilterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...biquad_filter_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeBiquadFilterNode = createNativeBiquadFilterNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const biquadFilterNodeRenderer = (isOffline ? createBiquadFilterNodeRenderer() : null);\n super(context, false, nativeBiquadFilterNode, biquadFilterNodeRenderer);\n // Bug #80: Safari does not export the correct values for maxValue and minValue.\n this._Q = createAudioParam(this, isOffline, nativeBiquadFilterNode.Q, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n // Bug #78: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._detune = createAudioParam(this, isOffline, nativeBiquadFilterNode.detune, 1200 * Math.log2(MOST_POSITIVE_SINGLE_FLOAT), -1200 * Math.log2(MOST_POSITIVE_SINGLE_FLOAT));\n // Bug #77: Firefox & Safari do not export the correct value for minValue.\n this._frequency = createAudioParam(this, isOffline, nativeBiquadFilterNode.frequency, context.sampleRate / 2, 0);\n // Bug #79: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._gain = createAudioParam(this, isOffline, nativeBiquadFilterNode.gain, 40 * Math.log10(MOST_POSITIVE_SINGLE_FLOAT), MOST_NEGATIVE_SINGLE_FLOAT);\n this._nativeBiquadFilterNode = nativeBiquadFilterNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get detune() {\n return this._detune;\n }\n get frequency() {\n return this._frequency;\n }\n get gain() {\n return this._gain;\n }\n get Q() {\n return this._Q;\n }\n get type() {\n return this._nativeBiquadFilterNode.type;\n }\n set type(value) {\n this._nativeBiquadFilterNode.type = value;\n }\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n // Bug #189: Safari does throw an InvalidStateError.\n try {\n this._nativeBiquadFilterNode.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);\n }\n catch (err) {\n if (err.code === 11) {\n throw createInvalidAccessError();\n }\n throw err;\n }\n // Bug #68: Safari does not throw an error if the parameters differ in their length.\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n }\n };\n};\n//# sourceMappingURL=biquad-filter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/biquad-filter-node-renderer-factory.js\n\nconst createBiquadFilterNodeRendererFactory = (connectAudioParam, createNativeBiquadFilterNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeBiquadFilterNodes = new WeakMap();\n const createBiquadFilterNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeBiquadFilterNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeBiquadFilterNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeBiquadFilterNodeIsOwnedByContext = isOwnedByContext(nativeBiquadFilterNode, nativeOfflineAudioContext);\n if (!nativeBiquadFilterNodeIsOwnedByContext) {\n const options = {\n Q: nativeBiquadFilterNode.Q.value,\n channelCount: nativeBiquadFilterNode.channelCount,\n channelCountMode: nativeBiquadFilterNode.channelCountMode,\n channelInterpretation: nativeBiquadFilterNode.channelInterpretation,\n detune: nativeBiquadFilterNode.detune.value,\n frequency: nativeBiquadFilterNode.frequency.value,\n gain: nativeBiquadFilterNode.gain.value,\n type: nativeBiquadFilterNode.type\n };\n nativeBiquadFilterNode = createNativeBiquadFilterNode(nativeOfflineAudioContext, options);\n }\n renderedNativeBiquadFilterNodes.set(nativeOfflineAudioContext, nativeBiquadFilterNode);\n if (!nativeBiquadFilterNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.Q, nativeBiquadFilterNode.Q);\n await renderAutomation(nativeOfflineAudioContext, proxy.detune, nativeBiquadFilterNode.detune);\n await renderAutomation(nativeOfflineAudioContext, proxy.frequency, nativeBiquadFilterNode.frequency);\n await renderAutomation(nativeOfflineAudioContext, proxy.gain, nativeBiquadFilterNode.gain);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.Q, nativeBiquadFilterNode.Q);\n await connectAudioParam(nativeOfflineAudioContext, proxy.detune, nativeBiquadFilterNode.detune);\n await connectAudioParam(nativeOfflineAudioContext, proxy.frequency, nativeBiquadFilterNode.frequency);\n await connectAudioParam(nativeOfflineAudioContext, proxy.gain, nativeBiquadFilterNode.gain);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeBiquadFilterNode);\n return nativeBiquadFilterNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeBiquadFilterNode = renderedNativeBiquadFilterNodes.get(nativeOfflineAudioContext);\n if (renderedNativeBiquadFilterNode !== undefined) {\n return Promise.resolve(renderedNativeBiquadFilterNode);\n }\n return createBiquadFilterNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=biquad-filter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/cache-test-result.js\nconst createCacheTestResult = (ongoingTests, testResults) => {\n return (tester, test) => {\n const cachedTestResult = testResults.get(tester);\n if (cachedTestResult !== undefined) {\n return cachedTestResult;\n }\n const ongoingTest = ongoingTests.get(tester);\n if (ongoingTest !== undefined) {\n return ongoingTest;\n }\n try {\n const synchronousTestResult = test();\n if (synchronousTestResult instanceof Promise) {\n ongoingTests.set(tester, synchronousTestResult);\n return synchronousTestResult\n .catch(() => false)\n .then((finalTestResult) => {\n ongoingTests.delete(tester);\n testResults.set(tester, finalTestResult);\n return finalTestResult;\n });\n }\n testResults.set(tester, synchronousTestResult);\n return synchronousTestResult;\n }\n catch {\n testResults.set(tester, false);\n return false;\n }\n };\n};\n//# sourceMappingURL=cache-test-result.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-merger-node-constructor.js\nconst channel_merger_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n};\nconst createChannelMergerNodeConstructor = (audioNodeConstructor, createChannelMergerNodeRenderer, createNativeChannelMergerNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class ChannelMergerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...channel_merger_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeChannelMergerNode = createNativeChannelMergerNode(nativeContext, mergedOptions);\n const channelMergerNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createChannelMergerNodeRenderer() : null));\n super(context, false, nativeChannelMergerNode, channelMergerNodeRenderer);\n }\n };\n};\n//# sourceMappingURL=channel-merger-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-merger-node-renderer-factory.js\n\nconst createChannelMergerNodeRendererFactory = (createNativeChannelMergerNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioNode = getNativeAudioNode(proxy);\n // If the initially used nativeAudioNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAudioNodeIsOwnedByContext = isOwnedByContext(nativeAudioNode, nativeOfflineAudioContext);\n if (!nativeAudioNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAudioNode.channelCount,\n channelCountMode: nativeAudioNode.channelCountMode,\n channelInterpretation: nativeAudioNode.channelInterpretation,\n numberOfInputs: nativeAudioNode.numberOfInputs\n };\n nativeAudioNode = createNativeChannelMergerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioNode);\n return nativeAudioNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=channel-merger-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-splitter-node-constructor.js\nconst channel_splitter_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 6,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: 6\n};\nconst createChannelSplitterNodeConstructor = (audioNodeConstructor, createChannelSplitterNodeRenderer, createNativeChannelSplitterNode, getNativeContext, isNativeOfflineAudioContext, sanitizeChannelSplitterOptions) => {\n return class ChannelSplitterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = sanitizeChannelSplitterOptions({ ...channel_splitter_node_constructor_DEFAULT_OPTIONS, ...options });\n const nativeChannelSplitterNode = createNativeChannelSplitterNode(nativeContext, mergedOptions);\n const channelSplitterNodeRenderer = ((isNativeOfflineAudioContext(nativeContext) ? createChannelSplitterNodeRenderer() : null));\n super(context, false, nativeChannelSplitterNode, channelSplitterNodeRenderer);\n }\n };\n};\n//# sourceMappingURL=channel-splitter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/channel-splitter-node-renderer-factory.js\n\nconst createChannelSplitterNodeRendererFactory = (createNativeChannelSplitterNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioNode = getNativeAudioNode(proxy);\n // If the initially used nativeAudioNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeAudioNodeIsOwnedByContext = isOwnedByContext(nativeAudioNode, nativeOfflineAudioContext);\n if (!nativeAudioNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeAudioNode.channelCount,\n channelCountMode: nativeAudioNode.channelCountMode,\n channelInterpretation: nativeAudioNode.channelInterpretation,\n numberOfOutputs: nativeAudioNode.numberOfOutputs\n };\n nativeAudioNode = createNativeChannelSplitterNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioNode);\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeAudioNode);\n return nativeAudioNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=channel-splitter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connect-audio-param.js\nconst createConnectAudioParam = (renderInputsOfAudioParam) => {\n return (nativeOfflineAudioContext, audioParam, nativeAudioParam) => {\n return renderInputsOfAudioParam(audioParam, nativeOfflineAudioContext, nativeAudioParam);\n };\n};\n//# sourceMappingURL=connect-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connect-multiple-outputs.js\n\nconst createConnectMultipleOutputs = (createIndexSizeError) => {\n return (outputAudioNodes, destination, output = 0, input = 0) => {\n const outputAudioNode = outputAudioNodes[output];\n if (outputAudioNode === undefined) {\n throw createIndexSizeError();\n }\n if (isNativeAudioNode(destination)) {\n return outputAudioNode.connect(destination, 0, input);\n }\n return outputAudioNode.connect(destination, 0);\n };\n};\n//# sourceMappingURL=connect-multiple-outputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/connected-native-audio-buffer-source-node-factory.js\nconst createConnectedNativeAudioBufferSourceNodeFactory = (createNativeAudioBufferSourceNode) => {\n return (nativeContext, nativeAudioNode) => {\n const nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const nativeAudioBuffer = nativeContext.createBuffer(1, 2, 44100);\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n nativeAudioBufferSourceNode.loop = true;\n nativeAudioBufferSourceNode.connect(nativeAudioNode);\n nativeAudioBufferSourceNode.start();\n return () => {\n nativeAudioBufferSourceNode.stop();\n nativeAudioBufferSourceNode.disconnect(nativeAudioNode);\n };\n };\n};\n//# sourceMappingURL=connected-native-audio-buffer-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/constant-source-node-constructor.js\n\n\n\n\nconst constant_source_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n offset: 1\n};\nconst createConstantSourceNodeConstructor = (audioNodeConstructor, createAudioParam, createConstantSourceNodeRendererFactory, createNativeConstantSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class ConstantSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...constant_source_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeConstantSourceNode = createNativeConstantSourceNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const constantSourceNodeRenderer = ((isOffline ? createConstantSourceNodeRendererFactory() : null));\n super(context, false, nativeConstantSourceNode, constantSourceNodeRenderer);\n this._constantSourceNodeRenderer = constantSourceNodeRenderer;\n this._nativeConstantSourceNode = nativeConstantSourceNode;\n /*\n * Bug #62 & #74: Safari does not support ConstantSourceNodes and does not export the correct values for maxValue and minValue\n * for GainNodes.\n */\n this._offset = createAudioParam(this, isOffline, nativeConstantSourceNode.offset, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._onended = null;\n }\n get offset() {\n return this._offset;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeConstantSourceNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeConstantSourceNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n start(when = 0) {\n this._nativeConstantSourceNode.start(when);\n if (this._constantSourceNodeRenderer !== null) {\n this._constantSourceNodeRenderer.start = when;\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeConstantSourceNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeConstantSourceNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeConstantSourceNode.stop(when);\n if (this._constantSourceNodeRenderer !== null) {\n this._constantSourceNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=constant-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/constant-source-node-renderer-factory.js\n\nconst createConstantSourceNodeRendererFactory = (connectAudioParam, createNativeConstantSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeConstantSourceNodes = new WeakMap();\n let start = null;\n let stop = null;\n const createConstantSourceNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeConstantSourceNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeConstantSourceNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeConstantSourceNodeIsOwnedByContext = isOwnedByContext(nativeConstantSourceNode, nativeOfflineAudioContext);\n if (!nativeConstantSourceNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeConstantSourceNode.channelCount,\n channelCountMode: nativeConstantSourceNode.channelCountMode,\n channelInterpretation: nativeConstantSourceNode.channelInterpretation,\n offset: nativeConstantSourceNode.offset.value\n };\n nativeConstantSourceNode = createNativeConstantSourceNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeConstantSourceNode.start(start);\n }\n if (stop !== null) {\n nativeConstantSourceNode.stop(stop);\n }\n }\n renderedNativeConstantSourceNodes.set(nativeOfflineAudioContext, nativeConstantSourceNode);\n if (!nativeConstantSourceNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.offset, nativeConstantSourceNode.offset);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.offset, nativeConstantSourceNode.offset);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConstantSourceNode);\n return nativeConstantSourceNode;\n };\n return {\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeConstantSourceNode = renderedNativeConstantSourceNodes.get(nativeOfflineAudioContext);\n if (renderedNativeConstantSourceNode !== undefined) {\n return Promise.resolve(renderedNativeConstantSourceNode);\n }\n return createConstantSourceNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=constant-source-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convert-number-to-unsigned-long.js\nconst createConvertNumberToUnsignedLong = (unit32Array) => {\n return (value) => {\n unit32Array[0] = value;\n return unit32Array[0];\n };\n};\n//# sourceMappingURL=convert-number-to-unsigned-long.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convolver-node-constructor.js\nconst convolver_node_constructor_DEFAULT_OPTIONS = {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n disableNormalization: false\n};\nconst createConvolverNodeConstructor = (audioNodeConstructor, createConvolverNodeRenderer, createNativeConvolverNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class ConvolverNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...convolver_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeConvolverNode = createNativeConvolverNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const convolverNodeRenderer = (isOffline ? createConvolverNodeRenderer() : null);\n super(context, false, nativeConvolverNode, convolverNodeRenderer);\n this._isBufferNullified = false;\n this._nativeConvolverNode = nativeConvolverNode;\n if (mergedOptions.buffer !== null) {\n setAudioNodeTailTime(this, mergedOptions.buffer.duration);\n }\n }\n get buffer() {\n if (this._isBufferNullified) {\n return null;\n }\n return this._nativeConvolverNode.buffer;\n }\n set buffer(value) {\n this._nativeConvolverNode.buffer = value;\n // Bug #115: Safari does not allow to set the buffer to null.\n if (value === null && this._nativeConvolverNode.buffer !== null) {\n const nativeContext = this._nativeConvolverNode.context;\n this._nativeConvolverNode.buffer = nativeContext.createBuffer(1, 1, nativeContext.sampleRate);\n this._isBufferNullified = true;\n setAudioNodeTailTime(this, 0);\n }\n else {\n this._isBufferNullified = false;\n setAudioNodeTailTime(this, this._nativeConvolverNode.buffer === null ? 0 : this._nativeConvolverNode.buffer.duration);\n }\n }\n get normalize() {\n return this._nativeConvolverNode.normalize;\n }\n set normalize(value) {\n this._nativeConvolverNode.normalize = value;\n }\n };\n};\n//# sourceMappingURL=convolver-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/convolver-node-renderer-factory.js\n\n\nconst createConvolverNodeRendererFactory = (createNativeConvolverNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeConvolverNodes = new WeakMap();\n const createConvolverNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeConvolverNode = getNativeAudioNode(proxy);\n // If the initially used nativeConvolverNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeConvolverNodeIsOwnedByContext = isOwnedByContext(nativeConvolverNode, nativeOfflineAudioContext);\n if (!nativeConvolverNodeIsOwnedByContext) {\n const options = {\n buffer: nativeConvolverNode.buffer,\n channelCount: nativeConvolverNode.channelCount,\n channelCountMode: nativeConvolverNode.channelCountMode,\n channelInterpretation: nativeConvolverNode.channelInterpretation,\n disableNormalization: !nativeConvolverNode.normalize\n };\n nativeConvolverNode = createNativeConvolverNode(nativeOfflineAudioContext, options);\n }\n renderedNativeConvolverNodes.set(nativeOfflineAudioContext, nativeConvolverNode);\n if (isNativeAudioNodeFaker(nativeConvolverNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConvolverNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeConvolverNode);\n }\n return nativeConvolverNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeConvolverNode = renderedNativeConvolverNodes.get(nativeOfflineAudioContext);\n if (renderedNativeConvolverNode !== undefined) {\n return Promise.resolve(renderedNativeConvolverNode);\n }\n return createConvolverNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=convolver-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/create-native-offline-audio-context.js\nconst createCreateNativeOfflineAudioContext = (createNotSupportedError, nativeOfflineAudioContextConstructor) => {\n return (numberOfChannels, length, sampleRate) => {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n try {\n return new nativeOfflineAudioContextConstructor(numberOfChannels, length, sampleRate);\n }\n catch (err) {\n // Bug #143, #144 & #146: Safari throws a SyntaxError when numberOfChannels, length or sampleRate are invalid.\n if (err.name === \'SyntaxError\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n };\n};\n//# sourceMappingURL=create-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/data-clone-error.js\nconst createDataCloneError = () => new DOMException(\'\', \'DataCloneError\');\n//# sourceMappingURL=data-clone-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/detach-array-buffer.js\nconst detachArrayBuffer = (arrayBuffer) => {\n const { port1, port2 } = new MessageChannel();\n return new Promise((resolve) => {\n const closeAndResolve = () => {\n port2.onmessage = null;\n port1.close();\n port2.close();\n resolve();\n };\n port2.onmessage = () => closeAndResolve();\n try {\n port1.postMessage(arrayBuffer, [arrayBuffer]);\n }\n catch {\n // Ignore errors.\n }\n finally {\n closeAndResolve();\n }\n });\n};\n//# sourceMappingURL=detach-array-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/decode-audio-data.js\n\n\nconst createDecodeAudioData = (audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, detachedArrayBuffers, getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n return (anyContext, audioData) => {\n const nativeContext = isNativeContext(anyContext) ? anyContext : getNativeContext(anyContext);\n // Bug #43: Only Chrome and Edge do throw a DataCloneError.\n if (detachedArrayBuffers.has(audioData)) {\n const err = createDataCloneError();\n return Promise.reject(err);\n }\n // The audioData parameter maybe of a type which can\'t be added to a WeakSet.\n try {\n detachedArrayBuffers.add(audioData);\n }\n catch {\n // Ignore errors.\n }\n // Bug #21: Safari does not support promises yet.\n if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeContext))) {\n return nativeContext.decodeAudioData(audioData).then((audioBuffer) => {\n // Bug #133: Safari does neuter the ArrayBuffer.\n detachArrayBuffer(audioData).catch(() => {\n // Ignore errors.\n });\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n return audioBuffer;\n });\n }\n // Bug #21: Safari does not return a Promise yet.\n return new Promise((resolve, reject) => {\n const complete = async () => {\n // Bug #133: Safari does neuter the ArrayBuffer.\n try {\n await detachArrayBuffer(audioData);\n }\n catch {\n // Ignore errors.\n }\n };\n const fail = (err) => {\n reject(err);\n complete();\n };\n // Bug #26: Safari throws a synchronous error.\n try {\n // Bug #1: Safari requires a successCallback.\n nativeContext.decodeAudioData(audioData, (audioBuffer) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n complete().then(() => resolve(audioBuffer));\n }, (err) => {\n // Bug #4: Safari returns null instead of an error.\n if (err === null) {\n fail(createEncodingError());\n }\n else {\n fail(err);\n }\n });\n }\n catch (err) {\n fail(err);\n }\n });\n };\n};\n//# sourceMappingURL=decode-audio-data.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/decrement-cycle-counter.js\n\nconst createDecrementCycleCounter = (connectNativeAudioNodeToNativeAudioNode, cycleCounters, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, getNativeContext, isActiveAudioNode, isNativeOfflineAudioContext) => {\n return (audioNode, count) => {\n const cycleCounter = cycleCounters.get(audioNode);\n if (cycleCounter === undefined) {\n throw new Error(\'Missing the expected cycle count.\');\n }\n const nativeContext = getNativeContext(audioNode.context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n if (cycleCounter === count) {\n cycleCounters.delete(audioNode);\n if (!isOffline && isActiveAudioNode(audioNode)) {\n const nativeSourceAudioNode = getNativeAudioNode(audioNode);\n const { outputs } = getAudioNodeConnections(audioNode);\n for (const output of outputs) {\n if (isAudioNodeOutputConnection(output)) {\n const nativeDestinationAudioNode = getNativeAudioNode(output[0]);\n connectNativeAudioNodeToNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output[1], output[2]);\n }\n else {\n const nativeDestinationAudioParam = getNativeAudioParam(output[0]);\n nativeSourceAudioNode.connect(nativeDestinationAudioParam, output[1]);\n }\n }\n }\n }\n else {\n cycleCounters.set(audioNode, cycleCounter - count);\n }\n };\n};\n//# sourceMappingURL=decrement-cycle-counter.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delay-node-constructor.js\nconst delay_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n delayTime: 0,\n maxDelayTime: 1\n};\nconst createDelayNodeConstructor = (audioNodeConstructor, createAudioParam, createDelayNodeRenderer, createNativeDelayNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class DelayNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...delay_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeDelayNode = createNativeDelayNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const delayNodeRenderer = (isOffline ? createDelayNodeRenderer(mergedOptions.maxDelayTime) : null);\n super(context, false, nativeDelayNode, delayNodeRenderer);\n this._delayTime = createAudioParam(this, isOffline, nativeDelayNode.delayTime);\n setAudioNodeTailTime(this, mergedOptions.maxDelayTime);\n }\n get delayTime() {\n return this._delayTime;\n }\n };\n};\n//# sourceMappingURL=delay-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delay-node-renderer-factory.js\n\nconst createDelayNodeRendererFactory = (connectAudioParam, createNativeDelayNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return (maxDelayTime) => {\n const renderedNativeDelayNodes = new WeakMap();\n const createDelayNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeDelayNode = getNativeAudioNode(proxy);\n // If the initially used nativeDelayNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeDelayNodeIsOwnedByContext = isOwnedByContext(nativeDelayNode, nativeOfflineAudioContext);\n if (!nativeDelayNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeDelayNode.channelCount,\n channelCountMode: nativeDelayNode.channelCountMode,\n channelInterpretation: nativeDelayNode.channelInterpretation,\n delayTime: nativeDelayNode.delayTime.value,\n maxDelayTime\n };\n nativeDelayNode = createNativeDelayNode(nativeOfflineAudioContext, options);\n }\n renderedNativeDelayNodes.set(nativeOfflineAudioContext, nativeDelayNode);\n if (!nativeDelayNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.delayTime, nativeDelayNode.delayTime);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.delayTime, nativeDelayNode.delayTime);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeDelayNode);\n return nativeDelayNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeDelayNode = renderedNativeDelayNodes.get(nativeOfflineAudioContext);\n if (renderedNativeDelayNode !== undefined) {\n return Promise.resolve(renderedNativeDelayNode);\n }\n return createDelayNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=delay-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delete-active-input-connection-to-audio-node.js\nconst createDeleteActiveInputConnectionToAudioNode = (pickElementFromSet) => {\n return (activeInputs, source, output, input) => {\n return pickElementFromSet(activeInputs[input], (activeInputConnection) => activeInputConnection[0] === source && activeInputConnection[1] === output);\n };\n};\n//# sourceMappingURL=delete-active-input-connection-to-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/delete-unrendered-audio-worklet-node.js\nconst createDeleteUnrenderedAudioWorkletNode = (getUnrenderedAudioWorkletNodes) => {\n return (nativeContext, audioWorkletNode) => {\n getUnrenderedAudioWorkletNodes(nativeContext).delete(audioWorkletNode);\n };\n};\n//# sourceMappingURL=delete-unrendered-audio-worklet-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/guards/delay-node.js\nconst isDelayNode = (audioNode) => {\n return \'delayTime\' in audioNode;\n};\n//# sourceMappingURL=delay-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/detect-cycles.js\n\n\nconst createDetectCycles = (audioParamAudioNodeStore, getAudioNodeConnections, getValueForKey) => {\n return function detectCycles(chain, nextLink) {\n const audioNode = isAudioNode(nextLink) ? nextLink : getValueForKey(audioParamAudioNodeStore, nextLink);\n if (isDelayNode(audioNode)) {\n return [];\n }\n if (chain[0] === audioNode) {\n return [chain];\n }\n if (chain.includes(audioNode)) {\n return [];\n }\n const { outputs } = getAudioNodeConnections(audioNode);\n return Array.from(outputs)\n .map((outputConnection) => detectCycles([...chain, audioNode], outputConnection[0]))\n .reduce((mergedCycles, nestedCycles) => mergedCycles.concat(nestedCycles), []);\n };\n};\n//# sourceMappingURL=detect-cycles.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/disconnect-multiple-outputs.js\n\nconst getOutputAudioNodeAtIndex = (createIndexSizeError, outputAudioNodes, output) => {\n const outputAudioNode = outputAudioNodes[output];\n if (outputAudioNode === undefined) {\n throw createIndexSizeError();\n }\n return outputAudioNode;\n};\nconst createDisconnectMultipleOutputs = (createIndexSizeError) => {\n return (outputAudioNodes, destinationOrOutput = undefined, output = undefined, input = 0) => {\n if (destinationOrOutput === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect());\n }\n if (typeof destinationOrOutput === \'number\') {\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, destinationOrOutput).disconnect();\n }\n if (isNativeAudioNode(destinationOrOutput)) {\n if (output === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect(destinationOrOutput));\n }\n if (input === undefined) {\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0);\n }\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0, input);\n }\n if (output === undefined) {\n return outputAudioNodes.forEach((outputAudioNode) => outputAudioNode.disconnect(destinationOrOutput));\n }\n return getOutputAudioNodeAtIndex(createIndexSizeError, outputAudioNodes, output).disconnect(destinationOrOutput, 0);\n };\n};\n//# sourceMappingURL=disconnect-multiple-outputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/dynamics-compressor-node-constructor.js\nconst dynamics_compressor_node_constructor_DEFAULT_OPTIONS = {\n attack: 0.003,\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n knee: 30,\n ratio: 12,\n release: 0.25,\n threshold: -24\n};\nconst createDynamicsCompressorNodeConstructor = (audioNodeConstructor, createAudioParam, createDynamicsCompressorNodeRenderer, createNativeDynamicsCompressorNode, createNotSupportedError, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class DynamicsCompressorNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...dynamics_compressor_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeDynamicsCompressorNode = createNativeDynamicsCompressorNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const dynamicsCompressorNodeRenderer = (isOffline ? createDynamicsCompressorNodeRenderer() : null);\n super(context, false, nativeDynamicsCompressorNode, dynamicsCompressorNodeRenderer);\n this._attack = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.attack);\n this._knee = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.knee);\n this._nativeDynamicsCompressorNode = nativeDynamicsCompressorNode;\n this._ratio = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.ratio);\n this._release = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.release);\n this._threshold = createAudioParam(this, isOffline, nativeDynamicsCompressorNode.threshold);\n setAudioNodeTailTime(this, 0.006);\n }\n get attack() {\n return this._attack;\n }\n // Bug #108: Safari allows a channelCount of three and above which is why the getter and setter needs to be overwritten here.\n get channelCount() {\n return this._nativeDynamicsCompressorNode.channelCount;\n }\n set channelCount(value) {\n const previousChannelCount = this._nativeDynamicsCompressorNode.channelCount;\n this._nativeDynamicsCompressorNode.channelCount = value;\n if (value > 2) {\n this._nativeDynamicsCompressorNode.channelCount = previousChannelCount;\n throw createNotSupportedError();\n }\n }\n /*\n * Bug #109: Only Chrome and Firefox disallow a channelCountMode of \'max\' yet which is why the getter and setter needs to be\n * overwritten here.\n */\n get channelCountMode() {\n return this._nativeDynamicsCompressorNode.channelCountMode;\n }\n set channelCountMode(value) {\n const previousChannelCount = this._nativeDynamicsCompressorNode.channelCountMode;\n this._nativeDynamicsCompressorNode.channelCountMode = value;\n if (value === \'max\') {\n this._nativeDynamicsCompressorNode.channelCountMode = previousChannelCount;\n throw createNotSupportedError();\n }\n }\n get knee() {\n return this._knee;\n }\n get ratio() {\n return this._ratio;\n }\n get reduction() {\n // Bug #111: Safari returns an AudioParam instead of a number.\n if (typeof this._nativeDynamicsCompressorNode.reduction.value === \'number\') {\n return this._nativeDynamicsCompressorNode.reduction.value;\n }\n return this._nativeDynamicsCompressorNode.reduction;\n }\n get release() {\n return this._release;\n }\n get threshold() {\n return this._threshold;\n }\n };\n};\n//# sourceMappingURL=dynamics-compressor-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/dynamics-compressor-node-renderer-factory.js\n\nconst createDynamicsCompressorNodeRendererFactory = (connectAudioParam, createNativeDynamicsCompressorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeDynamicsCompressorNodes = new WeakMap();\n const createDynamicsCompressorNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeDynamicsCompressorNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeDynamicsCompressorNode was not constructed on the same OfflineAudioContext it needs to be\n * created again.\n */\n const nativeDynamicsCompressorNodeIsOwnedByContext = isOwnedByContext(nativeDynamicsCompressorNode, nativeOfflineAudioContext);\n if (!nativeDynamicsCompressorNodeIsOwnedByContext) {\n const options = {\n attack: nativeDynamicsCompressorNode.attack.value,\n channelCount: nativeDynamicsCompressorNode.channelCount,\n channelCountMode: nativeDynamicsCompressorNode.channelCountMode,\n channelInterpretation: nativeDynamicsCompressorNode.channelInterpretation,\n knee: nativeDynamicsCompressorNode.knee.value,\n ratio: nativeDynamicsCompressorNode.ratio.value,\n release: nativeDynamicsCompressorNode.release.value,\n threshold: nativeDynamicsCompressorNode.threshold.value\n };\n nativeDynamicsCompressorNode = createNativeDynamicsCompressorNode(nativeOfflineAudioContext, options);\n }\n renderedNativeDynamicsCompressorNodes.set(nativeOfflineAudioContext, nativeDynamicsCompressorNode);\n if (!nativeDynamicsCompressorNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.attack, nativeDynamicsCompressorNode.attack);\n await renderAutomation(nativeOfflineAudioContext, proxy.knee, nativeDynamicsCompressorNode.knee);\n await renderAutomation(nativeOfflineAudioContext, proxy.ratio, nativeDynamicsCompressorNode.ratio);\n await renderAutomation(nativeOfflineAudioContext, proxy.release, nativeDynamicsCompressorNode.release);\n await renderAutomation(nativeOfflineAudioContext, proxy.threshold, nativeDynamicsCompressorNode.threshold);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.attack, nativeDynamicsCompressorNode.attack);\n await connectAudioParam(nativeOfflineAudioContext, proxy.knee, nativeDynamicsCompressorNode.knee);\n await connectAudioParam(nativeOfflineAudioContext, proxy.ratio, nativeDynamicsCompressorNode.ratio);\n await connectAudioParam(nativeOfflineAudioContext, proxy.release, nativeDynamicsCompressorNode.release);\n await connectAudioParam(nativeOfflineAudioContext, proxy.threshold, nativeDynamicsCompressorNode.threshold);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeDynamicsCompressorNode);\n return nativeDynamicsCompressorNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeDynamicsCompressorNode = renderedNativeDynamicsCompressorNodes.get(nativeOfflineAudioContext);\n if (renderedNativeDynamicsCompressorNode !== undefined) {\n return Promise.resolve(renderedNativeDynamicsCompressorNode);\n }\n return createDynamicsCompressorNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=dynamics-compressor-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/encoding-error.js\nconst createEncodingError = () => new DOMException(\'\', \'EncodingError\');\n//# sourceMappingURL=encoding-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/evaluate-source.js\nconst createEvaluateSource = (window) => {\n return (source) => new Promise((resolve, reject) => {\n if (window === null) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n return;\n }\n const head = window.document.head;\n if (head === null) {\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n }\n else {\n const script = window.document.createElement(\'script\');\n // @todo Safari doesn\'t like URLs with a type of \'application/javascript; charset=utf-8\'.\n const blob = new Blob([source], { type: \'application/javascript\' });\n const url = URL.createObjectURL(blob);\n const originalOnErrorHandler = window.onerror;\n const removeErrorEventListenerAndRevokeUrl = () => {\n window.onerror = originalOnErrorHandler;\n URL.revokeObjectURL(url);\n };\n window.onerror = (message, src, lineno, colno, error) => {\n // @todo Edge thinks the source is the one of the html document.\n if (src === url || (src === window.location.href && lineno === 1 && colno === 1)) {\n removeErrorEventListenerAndRevokeUrl();\n reject(error);\n return false;\n }\n if (originalOnErrorHandler !== null) {\n return originalOnErrorHandler(message, src, lineno, colno, error);\n }\n };\n script.onerror = () => {\n removeErrorEventListenerAndRevokeUrl();\n // Bug #182 Chrome and Edge do throw an instance of a SyntaxError instead of a DOMException.\n reject(new SyntaxError());\n };\n script.onload = () => {\n removeErrorEventListenerAndRevokeUrl();\n resolve();\n };\n script.src = url;\n script.type = \'module\';\n head.appendChild(script);\n }\n });\n};\n//# sourceMappingURL=evaluate-source.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/event-target-constructor.js\nconst createEventTargetConstructor = (wrapEventListener) => {\n return class EventTarget {\n constructor(_nativeEventTarget) {\n this._nativeEventTarget = _nativeEventTarget;\n this._listeners = new WeakMap();\n }\n addEventListener(type, listener, options) {\n if (listener !== null) {\n let wrappedEventListener = this._listeners.get(listener);\n if (wrappedEventListener === undefined) {\n wrappedEventListener = wrapEventListener(this, listener);\n if (typeof listener === \'function\') {\n this._listeners.set(listener, wrappedEventListener);\n }\n }\n this._nativeEventTarget.addEventListener(type, wrappedEventListener, options);\n }\n }\n dispatchEvent(event) {\n return this._nativeEventTarget.dispatchEvent(event);\n }\n removeEventListener(type, listener, options) {\n const wrappedEventListener = listener === null ? undefined : this._listeners.get(listener);\n this._nativeEventTarget.removeEventListener(type, wrappedEventListener === undefined ? null : wrappedEventListener, options);\n }\n };\n};\n//# sourceMappingURL=event-target-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/expose-current-frame-and-current-time.js\nconst createExposeCurrentFrameAndCurrentTime = (window) => {\n return (currentTime, sampleRate, fn) => {\n Object.defineProperties(window, {\n currentFrame: {\n configurable: true,\n get() {\n return Math.round(currentTime * sampleRate);\n }\n },\n currentTime: {\n configurable: true,\n get() {\n return currentTime;\n }\n }\n });\n try {\n return fn();\n }\n finally {\n if (window !== null) {\n delete window.currentFrame;\n delete window.currentTime;\n }\n }\n };\n};\n//# sourceMappingURL=expose-current-frame-and-current-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/fetch-source.js\nconst createFetchSource = (createAbortError) => {\n return async (url) => {\n try {\n const response = await fetch(url);\n if (response.ok) {\n return [await response.text(), response.url];\n }\n }\n catch {\n // Ignore errors.\n } // tslint:disable-line:no-empty\n throw createAbortError();\n };\n};\n//# sourceMappingURL=fetch-source.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/gain-node-constructor.js\n\nconst gain_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n gain: 1\n};\nconst createGainNodeConstructor = (audioNodeConstructor, createAudioParam, createGainNodeRenderer, createNativeGainNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class GainNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...gain_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeGainNode = createNativeGainNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const gainNodeRenderer = (isOffline ? createGainNodeRenderer() : null);\n super(context, false, nativeGainNode, gainNodeRenderer);\n // Bug #74: Safari does not export the correct values for maxValue and minValue.\n this._gain = createAudioParam(this, isOffline, nativeGainNode.gain, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n }\n get gain() {\n return this._gain;\n }\n };\n};\n//# sourceMappingURL=gain-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/gain-node-renderer-factory.js\n\nconst createGainNodeRendererFactory = (connectAudioParam, createNativeGainNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeGainNodes = new WeakMap();\n const createGainNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeGainNode = getNativeAudioNode(proxy);\n // If the initially used nativeGainNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeGainNodeIsOwnedByContext = isOwnedByContext(nativeGainNode, nativeOfflineAudioContext);\n if (!nativeGainNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeGainNode.channelCount,\n channelCountMode: nativeGainNode.channelCountMode,\n channelInterpretation: nativeGainNode.channelInterpretation,\n gain: nativeGainNode.gain.value\n };\n nativeGainNode = createNativeGainNode(nativeOfflineAudioContext, options);\n }\n renderedNativeGainNodes.set(nativeOfflineAudioContext, nativeGainNode);\n if (!nativeGainNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.gain, nativeGainNode.gain);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.gain, nativeGainNode.gain);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeGainNode);\n return nativeGainNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeGainNode = renderedNativeGainNodes.get(nativeOfflineAudioContext);\n if (renderedNativeGainNode !== undefined) {\n return Promise.resolve(renderedNativeGainNode);\n }\n return createGainNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=gain-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-active-audio-worklet-node-inputs.js\nconst createGetActiveAudioWorkletNodeInputs = (activeAudioWorkletNodeInputsStore, getValueForKey) => {\n return (nativeAudioWorkletNode) => getValueForKey(activeAudioWorkletNodeInputsStore, nativeAudioWorkletNode);\n};\n//# sourceMappingURL=get-active-audio-worklet-node-inputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-node-renderer.js\nconst createGetAudioNodeRenderer = (getAudioNodeConnections) => {\n return (audioNode) => {\n const audioNodeConnections = getAudioNodeConnections(audioNode);\n if (audioNodeConnections.renderer === null) {\n throw new Error(\'Missing the renderer of the given AudioNode in the audio graph.\');\n }\n return audioNodeConnections.renderer;\n };\n};\n//# sourceMappingURL=get-audio-node-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-node-tail-time.js\nconst createGetAudioNodeTailTime = (audioNodeTailTimeStore) => {\n return (audioNode) => { var _a; return (_a = audioNodeTailTimeStore.get(audioNode)) !== null && _a !== void 0 ? _a : 0; };\n};\n//# sourceMappingURL=get-audio-node-tail-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-audio-param-renderer.js\nconst createGetAudioParamRenderer = (getAudioParamConnections) => {\n return (audioParam) => {\n const audioParamConnections = getAudioParamConnections(audioParam);\n if (audioParamConnections.renderer === null) {\n throw new Error(\'Missing the renderer of the given AudioParam in the audio graph.\');\n }\n return audioParamConnections.renderer;\n };\n};\n//# sourceMappingURL=get-audio-param-renderer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-backup-offline-audio-context.js\nconst createGetBackupOfflineAudioContext = (backupOfflineAudioContextStore) => {\n return (nativeContext) => {\n return backupOfflineAudioContextStore.get(nativeContext);\n };\n};\n//# sourceMappingURL=get-backup-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/invalid-state-error.js\nconst createInvalidStateError = () => new DOMException(\'\', \'InvalidStateError\');\n//# sourceMappingURL=invalid-state-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-native-context.js\n\nconst createGetNativeContext = (contextStore) => {\n return (context) => {\n const nativeContext = contextStore.get(context);\n if (nativeContext === undefined) {\n throw createInvalidStateError();\n }\n return (nativeContext);\n };\n};\n//# sourceMappingURL=get-native-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-or-create-backup-offline-audio-context.js\nconst createGetOrCreateBackupOfflineAudioContext = (backupOfflineAudioContextStore, nativeOfflineAudioContextConstructor) => {\n return (nativeContext) => {\n let backupOfflineAudioContext = backupOfflineAudioContextStore.get(nativeContext);\n if (backupOfflineAudioContext !== undefined) {\n return backupOfflineAudioContext;\n }\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n // Bug #141: Safari does not support creating an OfflineAudioContext with less than 44100 Hz.\n backupOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n backupOfflineAudioContextStore.set(nativeContext, backupOfflineAudioContext);\n return backupOfflineAudioContext;\n };\n};\n//# sourceMappingURL=get-or-create-backup-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/get-unrendered-audio-worklet-nodes.js\nconst createGetUnrenderedAudioWorkletNodes = (unrenderedAudioWorkletNodeStore) => {\n return (nativeContext) => {\n const unrenderedAudioWorkletNodes = unrenderedAudioWorkletNodeStore.get(nativeContext);\n if (unrenderedAudioWorkletNodes === undefined) {\n throw new Error(\'The context has no set of AudioWorkletNodes.\');\n }\n return unrenderedAudioWorkletNodes;\n };\n};\n//# sourceMappingURL=get-unrendered-audio-worklet-nodes.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/invalid-access-error.js\nconst createInvalidAccessError = () => new DOMException(\'\', \'InvalidAccessError\');\n//# sourceMappingURL=invalid-access-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-iir-filter-node-get-frequency-response-method.js\n\nconst wrapIIRFilterNodeGetFrequencyResponseMethod = (nativeIIRFilterNode) => {\n nativeIIRFilterNode.getFrequencyResponse = ((getFrequencyResponse) => {\n return (frequencyHz, magResponse, phaseResponse) => {\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n return getFrequencyResponse.call(nativeIIRFilterNode, frequencyHz, magResponse, phaseResponse);\n };\n })(nativeIIRFilterNode.getFrequencyResponse);\n};\n//# sourceMappingURL=wrap-iir-filter-node-get-frequency-response-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/iir-filter-node-constructor.js\n\nconst iir_filter_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\'\n};\nconst createIIRFilterNodeConstructor = (audioNodeConstructor, createNativeIIRFilterNode, createIIRFilterNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class IIRFilterNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const mergedOptions = { ...iir_filter_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeIIRFilterNode = createNativeIIRFilterNode(nativeContext, isOffline ? null : context.baseLatency, mergedOptions);\n const iirFilterNodeRenderer = ((isOffline ? createIIRFilterNodeRenderer(mergedOptions.feedback, mergedOptions.feedforward) : null));\n super(context, false, nativeIIRFilterNode, iirFilterNodeRenderer);\n // Bug #23 & #24: FirefoxDeveloper does not throw an InvalidAccessError.\n // @todo Write a test which allows other browsers to remain unpatched.\n wrapIIRFilterNodeGetFrequencyResponseMethod(nativeIIRFilterNode);\n this._nativeIIRFilterNode = nativeIIRFilterNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n return this._nativeIIRFilterNode.getFrequencyResponse(frequencyHz, magResponse, phaseResponse);\n }\n };\n};\n//# sourceMappingURL=iir-filter-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/filter-buffer.js\n// This implementation as shamelessly inspired by source code of\n// tslint:disable-next-line:max-line-length\n// {@link https://chromium.googlesource.com/chromium/src.git/+/master/third_party/WebKit/Source/platform/audio/IIRFilter.cpp|Chromium\'s IIRFilter}.\nconst filterBuffer = (feedback, feedbackLength, feedforward, feedforwardLength, minLength, xBuffer, yBuffer, bufferIndex, bufferLength, input, output) => {\n const inputLength = input.length;\n let i = bufferIndex;\n for (let j = 0; j < inputLength; j += 1) {\n let y = feedforward[0] * input[j];\n for (let k = 1; k < minLength; k += 1) {\n const x = (i - k) & (bufferLength - 1); // tslint:disable-line:no-bitwise\n y += feedforward[k] * xBuffer[x];\n y -= feedback[k] * yBuffer[x];\n }\n for (let k = minLength; k < feedforwardLength; k += 1) {\n y += feedforward[k] * xBuffer[(i - k) & (bufferLength - 1)]; // tslint:disable-line:no-bitwise\n }\n for (let k = minLength; k < feedbackLength; k += 1) {\n y -= feedback[k] * yBuffer[(i - k) & (bufferLength - 1)]; // tslint:disable-line:no-bitwise\n }\n xBuffer[i] = input[j];\n yBuffer[i] = y;\n i = (i + 1) & (bufferLength - 1); // tslint:disable-line:no-bitwise\n output[j] = y;\n }\n return i;\n};\n//# sourceMappingURL=filter-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/iir-filter-node-renderer-factory.js\n\n\nconst filterFullBuffer = (renderedBuffer, nativeOfflineAudioContext, feedback, feedforward) => {\n const convertedFeedback = feedback instanceof Float64Array ? feedback : new Float64Array(feedback);\n const convertedFeedforward = feedforward instanceof Float64Array ? feedforward : new Float64Array(feedforward);\n const feedbackLength = convertedFeedback.length;\n const feedforwardLength = convertedFeedforward.length;\n const minLength = Math.min(feedbackLength, feedforwardLength);\n if (convertedFeedback[0] !== 1) {\n for (let i = 0; i < feedbackLength; i += 1) {\n convertedFeedforward[i] /= convertedFeedback[0];\n }\n for (let i = 1; i < feedforwardLength; i += 1) {\n convertedFeedback[i] /= convertedFeedback[0];\n }\n }\n const bufferLength = 32;\n const xBuffer = new Float32Array(bufferLength);\n const yBuffer = new Float32Array(bufferLength);\n const filteredBuffer = nativeOfflineAudioContext.createBuffer(renderedBuffer.numberOfChannels, renderedBuffer.length, renderedBuffer.sampleRate);\n const numberOfChannels = renderedBuffer.numberOfChannels;\n for (let i = 0; i < numberOfChannels; i += 1) {\n const input = renderedBuffer.getChannelData(i);\n const output = filteredBuffer.getChannelData(i);\n xBuffer.fill(0);\n yBuffer.fill(0);\n filterBuffer(convertedFeedback, feedbackLength, convertedFeedforward, feedforwardLength, minLength, xBuffer, yBuffer, 0, bufferLength, input, output);\n }\n return filteredBuffer;\n};\nconst createIIRFilterNodeRendererFactory = (createNativeAudioBufferSourceNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return (feedback, feedforward) => {\n const renderedNativeAudioNodes = new WeakMap();\n let filteredBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeAudioBufferSourceNode = null;\n let nativeIIRFilterNode = getNativeAudioNode(proxy);\n // If the initially used nativeIIRFilterNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeIIRFilterNodeIsOwnedByContext = isOwnedByContext(nativeIIRFilterNode, nativeOfflineAudioContext);\n // Bug #9: Safari does not support IIRFilterNodes.\n if (nativeOfflineAudioContext.createIIRFilter === undefined) {\n nativeAudioBufferSourceNode = createNativeAudioBufferSourceNode(nativeOfflineAudioContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n }\n else if (!nativeIIRFilterNodeIsOwnedByContext) {\n // @todo TypeScript defines the parameters of createIIRFilter() as arrays of numbers.\n nativeIIRFilterNode = nativeOfflineAudioContext.createIIRFilter(feedforward, feedback);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeAudioBufferSourceNode === null ? nativeIIRFilterNode : nativeAudioBufferSourceNode);\n if (nativeAudioBufferSourceNode !== null) {\n if (filteredBufferPromise === null) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(\n // Bug #47: The AudioDestinationNode in Safari gets not initialized correctly.\n proxy.context.destination.channelCount, \n // Bug #17: Safari does not yet expose the length.\n proxy.context.length, nativeOfflineAudioContext.sampleRate);\n filteredBufferPromise = (async () => {\n await renderInputsOfAudioNode(proxy, partialOfflineAudioContext, partialOfflineAudioContext.destination);\n const renderedBuffer = await renderNativeOfflineAudioContext(partialOfflineAudioContext);\n return filterFullBuffer(renderedBuffer, nativeOfflineAudioContext, feedback, feedforward);\n })();\n }\n const filteredBuffer = await filteredBufferPromise;\n nativeAudioBufferSourceNode.buffer = filteredBuffer;\n nativeAudioBufferSourceNode.start(0);\n return nativeAudioBufferSourceNode;\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeIIRFilterNode);\n return nativeIIRFilterNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeAudioNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeAudioNode !== undefined) {\n return Promise.resolve(renderedNativeAudioNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=iir-filter-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/increment-cycle-counter-factory.js\n\nconst createIncrementCycleCounterFactory = (cycleCounters, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, isActiveAudioNode) => {\n return (isOffline) => {\n return (audioNode, count) => {\n const cycleCounter = cycleCounters.get(audioNode);\n if (cycleCounter === undefined) {\n if (!isOffline && isActiveAudioNode(audioNode)) {\n const nativeSourceAudioNode = getNativeAudioNode(audioNode);\n const { outputs } = getAudioNodeConnections(audioNode);\n for (const output of outputs) {\n if (isAudioNodeOutputConnection(output)) {\n const nativeDestinationAudioNode = getNativeAudioNode(output[0]);\n disconnectNativeAudioNodeFromNativeAudioNode(nativeSourceAudioNode, nativeDestinationAudioNode, output[1], output[2]);\n }\n else {\n const nativeDestinationAudioParam = getNativeAudioParam(output[0]);\n nativeSourceAudioNode.disconnect(nativeDestinationAudioParam, output[1]);\n }\n }\n }\n cycleCounters.set(audioNode, count);\n }\n else {\n cycleCounters.set(audioNode, cycleCounter + count);\n }\n };\n };\n};\n//# sourceMappingURL=increment-cycle-counter-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-context.js\nconst createIsAnyAudioContext = (contextStore, isNativeAudioContext) => {\n return (anything) => {\n const nativeContext = contextStore.get(anything);\n return isNativeAudioContext(nativeContext) || isNativeAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-any-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-node.js\nconst createIsAnyAudioNode = (audioNodeStore, isNativeAudioNode) => {\n return (anything) => audioNodeStore.has(anything) || isNativeAudioNode(anything);\n};\n//# sourceMappingURL=is-any-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-audio-param.js\nconst createIsAnyAudioParam = (audioParamStore, isNativeAudioParam) => {\n return (anything) => audioParamStore.has(anything) || isNativeAudioParam(anything);\n};\n//# sourceMappingURL=is-any-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-any-offline-audio-context.js\nconst createIsAnyOfflineAudioContext = (contextStore, isNativeOfflineAudioContext) => {\n return (anything) => {\n const nativeContext = contextStore.get(anything);\n return isNativeOfflineAudioContext(nativeContext) || isNativeOfflineAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-any-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-context.js\nconst createIsNativeAudioContext = (nativeAudioContextConstructor) => {\n return (anything) => {\n return nativeAudioContextConstructor !== null && anything instanceof nativeAudioContextConstructor;\n };\n};\n//# sourceMappingURL=is-native-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-node.js\nconst createIsNativeAudioNode = (window) => {\n return (anything) => {\n return window !== null && typeof window.AudioNode === \'function\' && anything instanceof window.AudioNode;\n };\n};\n//# sourceMappingURL=is-native-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-audio-param.js\nconst createIsNativeAudioParam = (window) => {\n return (anything) => {\n return window !== null && typeof window.AudioParam === \'function\' && anything instanceof window.AudioParam;\n };\n};\n//# sourceMappingURL=is-native-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-context.js\nconst createIsNativeContext = (isNativeAudioContext, isNativeOfflineAudioContext) => {\n return (anything) => {\n return isNativeAudioContext(anything) || isNativeOfflineAudioContext(anything);\n };\n};\n//# sourceMappingURL=is-native-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-native-offline-audio-context.js\nconst createIsNativeOfflineAudioContext = (nativeOfflineAudioContextConstructor) => {\n return (anything) => {\n return nativeOfflineAudioContextConstructor !== null && anything instanceof nativeOfflineAudioContextConstructor;\n };\n};\n//# sourceMappingURL=is-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/is-secure-context.js\nconst createIsSecureContext = (window) => window !== null && window.isSecureContext;\n//# sourceMappingURL=is-secure-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-element-audio-source-node-constructor.js\nconst createMediaElementAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaElementAudioSourceNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaElementAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaElementAudioSourceNode = createNativeMediaElementAudioSourceNode(nativeContext, options);\n // Bug #171: Safari allows to create a MediaElementAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw TypeError();\n }\n super(context, true, nativeMediaElementAudioSourceNode, null);\n this._nativeMediaElementAudioSourceNode = nativeMediaElementAudioSourceNode;\n }\n get mediaElement() {\n return this._nativeMediaElementAudioSourceNode.mediaElement;\n }\n };\n};\n//# sourceMappingURL=media-element-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-audio-destination-node-constructor.js\nconst media_stream_audio_destination_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\'\n};\nconst createMediaStreamAudioDestinationNodeConstructor = (audioNodeConstructor, createNativeMediaStreamAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaStreamAudioDestinationNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n // Bug #173: Safari allows to create a MediaStreamAudioDestinationNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw new TypeError();\n }\n const mergedOptions = { ...media_stream_audio_destination_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeMediaStreamAudioDestinationNode = createNativeMediaStreamAudioDestinationNode(nativeContext, mergedOptions);\n super(context, false, nativeMediaStreamAudioDestinationNode, null);\n this._nativeMediaStreamAudioDestinationNode = nativeMediaStreamAudioDestinationNode;\n }\n get stream() {\n return this._nativeMediaStreamAudioDestinationNode.stream;\n }\n };\n};\n//# sourceMappingURL=media-stream-audio-destination-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-audio-source-node-constructor.js\nconst createMediaStreamAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaStreamAudioSourceNode, getNativeContext, isNativeOfflineAudioContext) => {\n return class MediaStreamAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaStreamAudioSourceNode = createNativeMediaStreamAudioSourceNode(nativeContext, options);\n // Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeContext)) {\n throw new TypeError();\n }\n super(context, true, nativeMediaStreamAudioSourceNode, null);\n this._nativeMediaStreamAudioSourceNode = nativeMediaStreamAudioSourceNode;\n }\n get mediaStream() {\n return this._nativeMediaStreamAudioSourceNode.mediaStream;\n }\n };\n};\n//# sourceMappingURL=media-stream-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/media-stream-track-audio-source-node-constructor.js\nconst createMediaStreamTrackAudioSourceNodeConstructor = (audioNodeConstructor, createNativeMediaStreamTrackAudioSourceNode, getNativeContext) => {\n return class MediaStreamTrackAudioSourceNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const nativeMediaStreamTrackAudioSourceNode = createNativeMediaStreamTrackAudioSourceNode(nativeContext, options);\n super(context, true, nativeMediaStreamTrackAudioSourceNode, null);\n }\n };\n};\n//# sourceMappingURL=media-stream-track-audio-source-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-audio-context-constructor.js\n\n\nconst createMinimalAudioContextConstructor = (createInvalidStateError, createNotSupportedError, createUnknownError, minimalBaseAudioContextConstructor, nativeAudioContextConstructor) => {\n return class MinimalAudioContext extends minimalBaseAudioContextConstructor {\n constructor(options = {}) {\n if (nativeAudioContextConstructor === null) {\n throw new Error(\'Missing the native AudioContext constructor.\');\n }\n let nativeAudioContext;\n try {\n nativeAudioContext = new nativeAudioContextConstructor(options);\n }\n catch (err) {\n // Bug #192 Safari does throw a SyntaxError if the sampleRate is not supported.\n if (err.code === 12 && err.message === \'sampleRate is not in range\') {\n throw createNotSupportedError();\n }\n throw err;\n }\n // Bug #131 Safari returns null when there are four other AudioContexts running already.\n if (nativeAudioContext === null) {\n throw createUnknownError();\n }\n // Bug #51 Only Chrome and Edge throw an error if the given latencyHint is invalid.\n if (!isValidLatencyHint(options.latencyHint)) {\n throw new TypeError(`The provided value \'${options.latencyHint}\' is not a valid enum value of type AudioContextLatencyCategory.`);\n }\n // Bug #150 Safari does not support setting the sampleRate.\n if (options.sampleRate !== undefined && nativeAudioContext.sampleRate !== options.sampleRate) {\n throw createNotSupportedError();\n }\n super(nativeAudioContext, 2);\n const { latencyHint } = options;\n const { sampleRate } = nativeAudioContext;\n // @todo The values for \'balanced\', \'interactive\' and \'playback\' are just copied from Chrome\'s implementation.\n this._baseLatency =\n typeof nativeAudioContext.baseLatency === \'number\'\n ? nativeAudioContext.baseLatency\n : latencyHint === \'balanced\'\n ? 512 / sampleRate\n : latencyHint === \'interactive\' || latencyHint === undefined\n ? 256 / sampleRate\n : latencyHint === \'playback\'\n ? 1024 / sampleRate\n : /*\n * @todo The min (256) and max (16384) values are taken from the allowed bufferSize values of a\n * ScriptProcessorNode.\n */\n (Math.max(2, Math.min(128, Math.round((latencyHint * sampleRate) / 128))) * 128) / sampleRate;\n this._nativeAudioContext = nativeAudioContext;\n // Bug #188: Safari will set the context\'s state to \'interrupted\' in case the user switches tabs.\n if (nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n this._nativeGainNode = nativeAudioContext.createGain();\n this._nativeOscillatorNode = nativeAudioContext.createOscillator();\n this._nativeGainNode.gain.value = 1e-37;\n this._nativeOscillatorNode.connect(this._nativeGainNode).connect(nativeAudioContext.destination);\n this._nativeOscillatorNode.start();\n }\n else {\n this._nativeGainNode = null;\n this._nativeOscillatorNode = null;\n }\n this._state = null;\n /*\n * Bug #34: Chrome and Edge pretend to be running right away, but fire an onstatechange event when the state actually changes\n * to \'running\'.\n */\n if (nativeAudioContext.state === \'running\') {\n this._state = \'suspended\';\n const revokeState = () => {\n if (this._state === \'suspended\') {\n this._state = null;\n }\n nativeAudioContext.removeEventListener(\'statechange\', revokeState);\n };\n nativeAudioContext.addEventListener(\'statechange\', revokeState);\n }\n }\n get baseLatency() {\n return this._baseLatency;\n }\n get state() {\n return this._state !== null ? this._state : this._nativeAudioContext.state;\n }\n close() {\n // Bug #35: Firefox does not throw an error if the AudioContext was closed before.\n if (this.state === \'closed\') {\n return this._nativeAudioContext.close().then(() => {\n throw createInvalidStateError();\n });\n }\n // Bug #34: If the state was set to suspended before it should be revoked now.\n if (this._state === \'suspended\') {\n this._state = null;\n }\n return this._nativeAudioContext.close().then(() => {\n if (this._nativeGainNode !== null && this._nativeOscillatorNode !== null) {\n this._nativeOscillatorNode.stop();\n this._nativeGainNode.disconnect();\n this._nativeOscillatorNode.disconnect();\n }\n deactivateAudioGraph(this);\n });\n }\n resume() {\n if (this._state === \'suspended\') {\n return new Promise((resolve, reject) => {\n const resolvePromise = () => {\n this._nativeAudioContext.removeEventListener(\'statechange\', resolvePromise);\n if (this._nativeAudioContext.state === \'running\') {\n resolve();\n }\n else {\n this.resume().then(resolve, reject);\n }\n };\n this._nativeAudioContext.addEventListener(\'statechange\', resolvePromise);\n });\n }\n return this._nativeAudioContext.resume().catch((err) => {\n // Bug #55: Chrome and Edge do throw an InvalidAccessError instead of an InvalidStateError.\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined || err.code === 15) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n suspend() {\n return this._nativeAudioContext.suspend().catch((err) => {\n // Bug #56: Safari invokes the catch handler but without an error.\n if (err === undefined) {\n throw createInvalidStateError();\n }\n throw err;\n });\n }\n };\n};\n//# sourceMappingURL=minimal-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-base-audio-context-constructor.js\n\nconst createMinimalBaseAudioContextConstructor = (audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener) => {\n return class MinimalBaseAudioContext extends eventTargetConstructor {\n constructor(_nativeContext, numberOfChannels) {\n super(_nativeContext);\n this._nativeContext = _nativeContext;\n CONTEXT_STORE.set(this, _nativeContext);\n if (isNativeOfflineAudioContext(_nativeContext)) {\n unrenderedAudioWorkletNodeStore.set(_nativeContext, new Set());\n }\n this._destination = new audioDestinationNodeConstructor(this, numberOfChannels);\n this._listener = createAudioListener(this, _nativeContext);\n this._onstatechange = null;\n }\n get currentTime() {\n return this._nativeContext.currentTime;\n }\n get destination() {\n return this._destination;\n }\n get listener() {\n return this._listener;\n }\n get onstatechange() {\n return this._onstatechange;\n }\n set onstatechange(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeContext.onstatechange = wrappedListener;\n const nativeOnStateChange = this._nativeContext.onstatechange;\n this._onstatechange = nativeOnStateChange !== null && nativeOnStateChange === wrappedListener ? value : nativeOnStateChange;\n }\n get sampleRate() {\n return this._nativeContext.sampleRate;\n }\n get state() {\n return this._nativeContext.state;\n }\n };\n};\n//# sourceMappingURL=minimal-base-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-promise-support.js\nconst testPromiseSupport = (nativeContext) => {\n // This 12 numbers represent the 48 bytes of an empty WAVE file with a single sample.\n const uint32Array = new Uint32Array([1179011410, 40, 1163280727, 544501094, 16, 131073, 44100, 176400, 1048580, 1635017060, 4, 0]);\n try {\n // Bug #1: Safari requires a successCallback.\n const promise = nativeContext.decodeAudioData(uint32Array.buffer, () => {\n // Ignore the success callback.\n });\n if (promise === undefined) {\n return false;\n }\n promise.catch(() => {\n // Ignore rejected errors.\n });\n return true;\n }\n catch {\n // Ignore errors.\n }\n return false;\n};\n//# sourceMappingURL=test-promise-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/minimal-offline-audio-context-constructor.js\n\n\nconst minimal_offline_audio_context_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createMinimalOfflineAudioContextConstructor = (cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, minimalBaseAudioContextConstructor, startRendering) => {\n return class MinimalOfflineAudioContext extends minimalBaseAudioContextConstructor {\n constructor(options) {\n const { length, numberOfChannels, sampleRate } = { ...minimal_offline_audio_context_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOfflineAudioContext = createNativeOfflineAudioContext(numberOfChannels, length, sampleRate);\n // #21 Safari does not support promises and therefore would fire the statechange event before the promise can be resolved.\n if (!cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n nativeOfflineAudioContext.addEventListener(\'statechange\', (() => {\n let i = 0;\n const delayStateChangeEvent = (event) => {\n if (this._state === \'running\') {\n if (i > 0) {\n nativeOfflineAudioContext.removeEventListener(\'statechange\', delayStateChangeEvent);\n event.stopImmediatePropagation();\n this._waitForThePromiseToSettle(event);\n }\n else {\n i += 1;\n }\n }\n };\n return delayStateChangeEvent;\n })());\n }\n super(nativeOfflineAudioContext, numberOfChannels);\n this._length = length;\n this._nativeOfflineAudioContext = nativeOfflineAudioContext;\n this._state = null;\n }\n get length() {\n // Bug #17: Safari does not yet expose the length.\n if (this._nativeOfflineAudioContext.length === undefined) {\n return this._length;\n }\n return this._nativeOfflineAudioContext.length;\n }\n get state() {\n return this._state === null ? this._nativeOfflineAudioContext.state : this._state;\n }\n startRendering() {\n /*\n * Bug #9 & #59: It is theoretically possible that startRendering() will first render a partialOfflineAudioContext. Therefore\n * the state of the nativeOfflineAudioContext might no transition to running immediately.\n */\n if (this._state === \'running\') {\n return Promise.reject(createInvalidStateError());\n }\n this._state = \'running\';\n return startRendering(this.destination, this._nativeOfflineAudioContext).finally(() => {\n this._state = null;\n deactivateAudioGraph(this);\n });\n }\n _waitForThePromiseToSettle(event) {\n if (this._state === null) {\n this._nativeOfflineAudioContext.dispatchEvent(event);\n }\n else {\n setTimeout(() => this._waitForThePromiseToSettle(event));\n }\n }\n };\n};\n//# sourceMappingURL=minimal-offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/monitor-connections.js\nconst createMonitorConnections = (insertElementInSet, isNativeAudioNode) => {\n return (nativeAudioNode, whenConnected, whenDisconnected) => {\n const connections = new Set();\n nativeAudioNode.connect = ((connect) => {\n // tslint:disable-next-line:invalid-void no-inferrable-types\n return (destination, output = 0, input = 0) => {\n const wasDisconnected = connections.size === 0;\n if (isNativeAudioNode(destination)) {\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n connect.call(nativeAudioNode, destination, output, input);\n insertElementInSet(connections, [destination, output, input], (connection) => connection[0] === destination && connection[1] === output && connection[2] === input, true);\n if (wasDisconnected) {\n whenConnected();\n }\n return destination;\n }\n connect.call(nativeAudioNode, destination, output);\n insertElementInSet(connections, [destination, output], (connection) => connection[0] === destination && connection[1] === output, true);\n if (wasDisconnected) {\n whenConnected();\n }\n return;\n };\n })(nativeAudioNode.connect);\n nativeAudioNode.disconnect = ((disconnect) => {\n return (destinationOrOutput, output, input) => {\n const wasConnected = connections.size > 0;\n if (destinationOrOutput === undefined) {\n disconnect.apply(nativeAudioNode);\n connections.clear();\n }\n else if (typeof destinationOrOutput === \'number\') {\n // @todo TypeScript cannot infer the overloaded signature with 1 argument yet.\n disconnect.call(nativeAudioNode, destinationOrOutput);\n for (const connection of connections) {\n if (connection[1] === destinationOrOutput) {\n connections.delete(connection);\n }\n }\n }\n else {\n if (isNativeAudioNode(destinationOrOutput)) {\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n disconnect.call(nativeAudioNode, destinationOrOutput, output, input);\n }\n else {\n // @todo TypeScript cannot infer the overloaded signature with 2 arguments yet.\n disconnect.call(nativeAudioNode, destinationOrOutput, output);\n }\n for (const connection of connections) {\n if (connection[0] === destinationOrOutput &&\n (output === undefined || connection[1] === output) &&\n (input === undefined || connection[2] === input)) {\n connections.delete(connection);\n }\n }\n }\n const isDisconnected = connections.size === 0;\n if (wasConnected && isDisconnected) {\n whenDisconnected();\n }\n };\n })(nativeAudioNode.disconnect);\n return nativeAudioNode;\n };\n};\n//# sourceMappingURL=monitor-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-option.js\nconst assignNativeAudioNodeOption = (nativeAudioNode, options, option) => {\n const value = options[option];\n if (value !== undefined && value !== nativeAudioNode[option]) {\n nativeAudioNode[option] = value;\n }\n};\n//# sourceMappingURL=assign-native-audio-node-option.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-options.js\n\nconst assignNativeAudioNodeOptions = (nativeAudioNode, options) => {\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelCount\');\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelCountMode\');\n assignNativeAudioNodeOption(nativeAudioNode, options, \'channelInterpretation\');\n};\n//# sourceMappingURL=assign-native-audio-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-analyser-node-get-float-time-domain-data-method-support.js\nconst testAnalyserNodeGetFloatTimeDomainDataMethodSupport = (nativeAnalyserNode) => {\n return typeof nativeAnalyserNode.getFloatTimeDomainData === \'function\';\n};\n//# sourceMappingURL=test-analyser-node-get-float-time-domain-data-method-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-analyser-node-get-float-time-domain-data-method.js\nconst wrapAnalyserNodeGetFloatTimeDomainDataMethod = (nativeAnalyserNode) => {\n nativeAnalyserNode.getFloatTimeDomainData = (array) => {\n const byteTimeDomainData = new Uint8Array(array.length);\n nativeAnalyserNode.getByteTimeDomainData(byteTimeDomainData);\n const length = Math.max(byteTimeDomainData.length, nativeAnalyserNode.fftSize);\n for (let i = 0; i < length; i += 1) {\n array[i] = (byteTimeDomainData[i] - 128) * 0.0078125;\n }\n return array;\n };\n};\n//# sourceMappingURL=wrap-analyser-node-get-float-time-domain-data-method.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-analyser-node-factory.js\n\n\n\n\nconst createNativeAnalyserNodeFactory = (cacheTestResult, createIndexSizeError) => {\n return (nativeContext, options) => {\n const nativeAnalyserNode = nativeContext.createAnalyser();\n // Bug #37: Firefox does not create an AnalyserNode with the default properties.\n assignNativeAudioNodeOptions(nativeAnalyserNode, options);\n // Bug #118: Safari does not throw an error if maxDecibels is not more than minDecibels.\n if (!(options.maxDecibels > options.minDecibels)) {\n throw createIndexSizeError();\n }\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'fftSize\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'maxDecibels\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'minDecibels\');\n assignNativeAudioNodeOption(nativeAnalyserNode, options, \'smoothingTimeConstant\');\n // Bug #36: Safari does not support getFloatTimeDomainData() yet.\n if (!cacheTestResult(testAnalyserNodeGetFloatTimeDomainDataMethodSupport, () => testAnalyserNodeGetFloatTimeDomainDataMethodSupport(nativeAnalyserNode))) {\n wrapAnalyserNodeGetFloatTimeDomainDataMethod(nativeAnalyserNode);\n }\n return nativeAnalyserNode;\n };\n};\n//# sourceMappingURL=native-analyser-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-buffer-constructor.js\nconst createNativeAudioBufferConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'AudioBuffer\')) {\n return window.AudioBuffer;\n }\n return null;\n};\n//# sourceMappingURL=native-audio-buffer-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/assign-native-audio-node-audio-param-value.js\nconst assignNativeAudioNodeAudioParamValue = (nativeAudioNode, options, audioParam) => {\n const value = options[audioParam];\n if (value !== undefined && value !== nativeAudioNode[audioParam].value) {\n nativeAudioNode[audioParam].value = value;\n }\n};\n//# sourceMappingURL=assign-native-audio-node-audio-param-value.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-source-node-start-method-consecutive-calls.js\n\nconst wrapAudioBufferSourceNodeStartMethodConsecutiveCalls = (nativeAudioBufferSourceNode) => {\n nativeAudioBufferSourceNode.start = ((start) => {\n let isScheduled = false;\n return (when = 0, offset = 0, duration) => {\n if (isScheduled) {\n throw createInvalidStateError();\n }\n start.call(nativeAudioBufferSourceNode, when, offset, duration);\n isScheduled = true;\n };\n })(nativeAudioBufferSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-start-method-consecutive-calls.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-start-method-negative-parameters.js\nconst wrapAudioScheduledSourceNodeStartMethodNegativeParameters = (nativeAudioScheduledSourceNode) => {\n nativeAudioScheduledSourceNode.start = ((start) => {\n return (when = 0, offset = 0, duration) => {\n if ((typeof duration === \'number\' && duration < 0) || offset < 0 || when < 0) {\n throw new RangeError("The parameters can\'t be negative.");\n }\n // @todo TypeScript cannot infer the overloaded signature with 3 arguments yet.\n start.call(nativeAudioScheduledSourceNode, when, offset, duration);\n };\n })(nativeAudioScheduledSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-start-method-negative-parameters.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-stop-method-negative-parameters.js\nconst wrapAudioScheduledSourceNodeStopMethodNegativeParameters = (nativeAudioScheduledSourceNode) => {\n nativeAudioScheduledSourceNode.stop = ((stop) => {\n return (when = 0) => {\n if (when < 0) {\n throw new RangeError("The parameter can\'t be negative.");\n }\n stop.call(nativeAudioScheduledSourceNode, when);\n };\n })(nativeAudioScheduledSourceNode.stop);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-stop-method-negative-parameters.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-buffer-source-node-factory.js\n\n\n\n\n\n\nconst createNativeAudioBufferSourceNodeFactory = (addSilentConnection, cacheTestResult, testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, testAudioBufferSourceNodeStartMethodOffsetClampingSupport, testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioBufferSourceNodeStartMethodOffsetClampling, wrapAudioBufferSourceNodeStopMethodNullifiedBuffer, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls) => {\n return (nativeContext, options) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n assignNativeAudioNodeOptions(nativeAudioBufferSourceNode, options);\n assignNativeAudioNodeAudioParamValue(nativeAudioBufferSourceNode, options, \'playbackRate\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'buffer\');\n // Bug #149: Safari does not yet support the detune AudioParam.\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loop\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loopEnd\');\n assignNativeAudioNodeOption(nativeAudioBufferSourceNode, options, \'loopStart\');\n // Bug #69: Safari does allow calls to start() of an already scheduled AudioBufferSourceNode.\n if (!cacheTestResult(testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, () => testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStartMethodConsecutiveCalls(nativeAudioBufferSourceNode);\n }\n // Bug #154 & #155: Safari does not handle offsets which are equal to or greater than the duration of the buffer.\n if (!cacheTestResult(testAudioBufferSourceNodeStartMethodOffsetClampingSupport, () => testAudioBufferSourceNodeStartMethodOffsetClampingSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStartMethodOffsetClampling(nativeAudioBufferSourceNode);\n }\n // Bug #162: Safari does throw an error when stop() is called on an AudioBufferSourceNode which has no buffer assigned to it.\n if (!cacheTestResult(testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, () => testAudioBufferSourceNodeStopMethodNullifiedBufferSupport(nativeContext))) {\n wrapAudioBufferSourceNodeStopMethodNullifiedBuffer(nativeAudioBufferSourceNode, nativeContext);\n }\n // Bug #44: Safari does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeAudioBufferSourceNode);\n }\n // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeAudioBufferSourceNode, nativeContext);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeAudioBufferSourceNode);\n }\n // Bug #175: Safari will not fire an ended event if the AudioBufferSourceNode is unconnected.\n addSilentConnection(nativeContext, nativeAudioBufferSourceNode);\n return nativeAudioBufferSourceNode;\n };\n};\n//# sourceMappingURL=native-audio-buffer-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-context-constructor.js\nconst createNativeAudioContextConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'AudioContext\')) {\n return window.AudioContext;\n }\n return window.hasOwnProperty(\'webkitAudioContext\') ? window.webkitAudioContext : null;\n};\n//# sourceMappingURL=native-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-destination-node.js\nconst createNativeAudioDestinationNodeFactory = (createNativeGainNode, overwriteAccessors) => {\n return (nativeContext, channelCount, isNodeOfNativeOfflineAudioContext) => {\n const nativeAudioDestinationNode = nativeContext.destination;\n // Bug #132: Safari does not have the correct channelCount.\n if (nativeAudioDestinationNode.channelCount !== channelCount) {\n try {\n nativeAudioDestinationNode.channelCount = channelCount;\n }\n catch {\n // Bug #169: Safari throws an error on each attempt to change the channelCount.\n }\n }\n // Bug #83: Safari does not have the correct channelCountMode.\n if (isNodeOfNativeOfflineAudioContext && nativeAudioDestinationNode.channelCountMode !== \'explicit\') {\n nativeAudioDestinationNode.channelCountMode = \'explicit\';\n }\n // Bug #47: The AudioDestinationNode in Safari does not initialize the maxChannelCount property correctly.\n if (nativeAudioDestinationNode.maxChannelCount === 0) {\n Object.defineProperty(nativeAudioDestinationNode, \'maxChannelCount\', {\n value: channelCount\n });\n }\n // Bug #168: No browser does yet have an AudioDestinationNode with an output.\n const gainNode = createNativeGainNode(nativeContext, {\n channelCount,\n channelCountMode: nativeAudioDestinationNode.channelCountMode,\n channelInterpretation: nativeAudioDestinationNode.channelInterpretation,\n gain: 1\n });\n overwriteAccessors(gainNode, \'channelCount\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n try {\n nativeAudioDestinationNode.channelCount = value;\n }\n catch (err) {\n // Bug #169: Safari throws an error on each attempt to change the channelCount.\n if (value > nativeAudioDestinationNode.maxChannelCount) {\n throw err;\n }\n }\n });\n overwriteAccessors(gainNode, \'channelCountMode\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n nativeAudioDestinationNode.channelCountMode = value;\n });\n overwriteAccessors(gainNode, \'channelInterpretation\', (get) => () => get.call(gainNode), (set) => (value) => {\n set.call(gainNode, value);\n nativeAudioDestinationNode.channelInterpretation = value;\n });\n Object.defineProperty(gainNode, \'maxChannelCount\', {\n get: () => nativeAudioDestinationNode.maxChannelCount\n });\n // @todo This should be disconnected when the context is closed.\n gainNode.connect(nativeAudioDestinationNode);\n return gainNode;\n };\n};\n//# sourceMappingURL=native-audio-destination-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-constructor.js\nconst createNativeAudioWorkletNodeConstructor = (window) => {\n if (window === null) {\n return null;\n }\n return window.hasOwnProperty(\'AudioWorkletNode\') ? window.AudioWorkletNode : null;\n};\n//# sourceMappingURL=native-audio-worklet-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-clonability-of-audio-worklet-node-options.js\nconst testClonabilityOfAudioWorkletNodeOptions = (audioWorkletNodeOptions) => {\n const { port1 } = new MessageChannel();\n try {\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port1.postMessage(audioWorkletNodeOptions);\n }\n finally {\n port1.close();\n }\n};\n//# sourceMappingURL=test-clonability-of-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-factory.js\n\nconst createNativeAudioWorkletNodeFactory = (createInvalidStateError, createNativeAudioWorkletNodeFaker, createNativeGainNode, createNotSupportedError, monitorConnections) => {\n return (nativeContext, baseLatency, nativeAudioWorkletNodeConstructor, name, processorConstructor, options) => {\n if (nativeAudioWorkletNodeConstructor !== null) {\n try {\n const nativeAudioWorkletNode = new nativeAudioWorkletNodeConstructor(nativeContext, name, options);\n const patchedEventListeners = new Map();\n let onprocessorerror = null;\n Object.defineProperties(nativeAudioWorkletNode, {\n /*\n * Bug #61: Overwriting the property accessors for channelCount and channelCountMode is necessary as long as some\n * browsers have no native implementation to achieve a consistent behavior.\n */\n channelCount: {\n get: () => options.channelCount,\n set: () => {\n throw createInvalidStateError();\n }\n },\n channelCountMode: {\n get: () => \'explicit\',\n set: () => {\n throw createInvalidStateError();\n }\n },\n // Bug #156: Chrome and Edge do not yet fire an ErrorEvent.\n onprocessorerror: {\n get: () => onprocessorerror,\n set: (value) => {\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNode.removeEventListener(\'processorerror\', onprocessorerror);\n }\n onprocessorerror = typeof value === \'function\' ? value : null;\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNode.addEventListener(\'processorerror\', onprocessorerror);\n }\n }\n }\n });\n nativeAudioWorkletNode.addEventListener = ((addEventListener) => {\n return (...args) => {\n if (args[0] === \'processorerror\') {\n const unpatchedEventListener = typeof args[1] === \'function\'\n ? args[1]\n : typeof args[1] === \'object\' && args[1] !== null && typeof args[1].handleEvent === \'function\'\n ? args[1].handleEvent\n : null;\n if (unpatchedEventListener !== null) {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n args[1] = patchedEventListener;\n }\n else {\n args[1] = (event) => {\n // Bug #178: Chrome and Edge do fire an event of type error.\n if (event.type === \'error\') {\n Object.defineProperties(event, {\n type: { value: \'processorerror\' }\n });\n unpatchedEventListener(event);\n }\n else {\n unpatchedEventListener(new ErrorEvent(args[0], { ...event }));\n }\n };\n patchedEventListeners.set(unpatchedEventListener, args[1]);\n }\n }\n }\n // Bug #178: Chrome and Edge do fire an event of type error.\n addEventListener.call(nativeAudioWorkletNode, \'error\', args[1], args[2]);\n return addEventListener.call(nativeAudioWorkletNode, ...args);\n };\n })(nativeAudioWorkletNode.addEventListener);\n nativeAudioWorkletNode.removeEventListener = ((removeEventListener) => {\n return (...args) => {\n if (args[0] === \'processorerror\') {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n patchedEventListeners.delete(args[1]);\n args[1] = patchedEventListener;\n }\n }\n // Bug #178: Chrome and Edge do fire an event of type error.\n removeEventListener.call(nativeAudioWorkletNode, \'error\', args[1], args[2]);\n return removeEventListener.call(nativeAudioWorkletNode, args[0], args[1], args[2]);\n };\n })(nativeAudioWorkletNode.removeEventListener);\n /*\n * Bug #86: Chrome and Edge do not invoke the process() function if the corresponding AudioWorkletNode is unconnected but\n * has an output.\n */\n if (options.numberOfOutputs !== 0) {\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeAudioWorkletNode.connect(nativeGainNode).connect(nativeContext.destination);\n const whenConnected = () => nativeGainNode.disconnect();\n const whenDisconnected = () => nativeGainNode.connect(nativeContext.destination);\n // @todo Disconnect the connection when the process() function of the AudioWorkletNode returns false.\n return monitorConnections(nativeAudioWorkletNode, whenConnected, whenDisconnected);\n }\n return nativeAudioWorkletNode;\n }\n catch (err) {\n // Bug #60: Chrome & Edge throw an InvalidStateError instead of a NotSupportedError.\n if (err.code === 11) {\n throw createNotSupportedError();\n }\n throw err;\n }\n }\n // Bug #61: Only Chrome & Edge have an implementation of the AudioWorkletNode yet.\n if (processorConstructor === undefined) {\n throw createNotSupportedError();\n }\n testClonabilityOfAudioWorkletNodeOptions(options);\n return createNativeAudioWorkletNodeFaker(nativeContext, baseLatency, processorConstructor, options);\n };\n};\n//# sourceMappingURL=native-audio-worklet-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/compute-buffer-size.js\nconst computeBufferSize = (baseLatency, sampleRate) => {\n if (baseLatency === null) {\n return 512;\n }\n return Math.max(512, Math.min(16384, Math.pow(2, Math.round(Math.log2(baseLatency * sampleRate)))));\n};\n//# sourceMappingURL=compute-buffer-size.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/clone-audio-worklet-node-options.js\nconst cloneAudioWorkletNodeOptions = (audioWorkletNodeOptions) => {\n return new Promise((resolve, reject) => {\n const { port1, port2 } = new MessageChannel();\n port1.onmessage = ({ data }) => {\n port1.close();\n port2.close();\n resolve(data);\n };\n port1.onmessageerror = ({ data }) => {\n port1.close();\n port2.close();\n reject(data);\n };\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port2.postMessage(audioWorkletNodeOptions);\n });\n};\n//# sourceMappingURL=clone-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-audio-worklet-processor-promise.js\n\nconst createAudioWorkletProcessorPromise = async (processorConstructor, audioWorkletNodeOptions) => {\n const clonedAudioWorkletNodeOptions = await cloneAudioWorkletNodeOptions(audioWorkletNodeOptions);\n return new processorConstructor(clonedAudioWorkletNodeOptions);\n};\n//# sourceMappingURL=create-audio-worklet-processor-promise.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/create-audio-worklet-processor.js\n\n\nconst createAudioWorkletProcessor = (nativeContext, nativeAudioWorkletNode, processorConstructor, audioWorkletNodeOptions) => {\n let nodeToProcessorMap = NODE_TO_PROCESSOR_MAPS.get(nativeContext);\n if (nodeToProcessorMap === undefined) {\n nodeToProcessorMap = new WeakMap();\n NODE_TO_PROCESSOR_MAPS.set(nativeContext, nodeToProcessorMap);\n }\n const audioWorkletProcessorPromise = createAudioWorkletProcessorPromise(processorConstructor, audioWorkletNodeOptions);\n nodeToProcessorMap.set(nativeAudioWorkletNode, audioWorkletProcessorPromise);\n return audioWorkletProcessorPromise;\n};\n//# sourceMappingURL=create-audio-worklet-processor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-audio-worklet-node-faker-factory.js\n\n\n\n\n\n\n\nconst createNativeAudioWorkletNodeFakerFactory = (connectMultipleOutputs, createIndexSizeError, createInvalidStateError, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, createNativeScriptProcessorNode, createNotSupportedError, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getActiveAudioWorkletNodeInputs, monitorConnections) => {\n return (nativeContext, baseLatency, processorConstructor, options) => {\n if (options.numberOfInputs === 0 && options.numberOfOutputs === 0) {\n throw createNotSupportedError();\n }\n const outputChannelCount = Array.isArray(options.outputChannelCount)\n ? options.outputChannelCount\n : Array.from(options.outputChannelCount);\n // @todo Check if any of the channelCount values is greater than the implementation\'s maximum number of channels.\n if (outputChannelCount.some((channelCount) => channelCount < 1)) {\n throw createNotSupportedError();\n }\n if (outputChannelCount.length !== options.numberOfOutputs) {\n throw createIndexSizeError();\n }\n // Bug #61: This is not part of the standard but required for the faker to work.\n if (options.channelCountMode !== \'explicit\') {\n throw createNotSupportedError();\n }\n const numberOfInputChannels = options.channelCount * options.numberOfInputs;\n const numberOfOutputChannels = outputChannelCount.reduce((sum, value) => sum + value, 0);\n const numberOfParameters = processorConstructor.parameterDescriptors === undefined ? 0 : processorConstructor.parameterDescriptors.length;\n // Bug #61: This is not part of the standard but required for the faker to work.\n if (numberOfInputChannels + numberOfParameters > 6 || numberOfOutputChannels > 6) {\n throw createNotSupportedError();\n }\n const messageChannel = new MessageChannel();\n const gainNodes = [];\n const inputChannelSplitterNodes = [];\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes.push(createNativeGainNode(nativeContext, {\n channelCount: options.channelCount,\n channelCountMode: options.channelCountMode,\n channelInterpretation: options.channelInterpretation,\n gain: 1\n }));\n inputChannelSplitterNodes.push(createNativeChannelSplitterNode(nativeContext, {\n channelCount: options.channelCount,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: options.channelCount\n }));\n }\n const constantSourceNodes = [];\n if (processorConstructor.parameterDescriptors !== undefined) {\n for (const { defaultValue, maxValue, minValue, name } of processorConstructor.parameterDescriptors) {\n const constantSourceNode = createNativeConstantSourceNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: options.parameterData[name] !== undefined\n ? options.parameterData[name]\n : defaultValue === undefined\n ? 0\n : defaultValue\n });\n Object.defineProperties(constantSourceNode.offset, {\n defaultValue: {\n get: () => (defaultValue === undefined ? 0 : defaultValue)\n },\n maxValue: {\n get: () => (maxValue === undefined ? MOST_POSITIVE_SINGLE_FLOAT : maxValue)\n },\n minValue: {\n get: () => (minValue === undefined ? MOST_NEGATIVE_SINGLE_FLOAT : minValue)\n }\n });\n constantSourceNodes.push(constantSourceNode);\n }\n }\n const inputChannelMergerNode = createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: Math.max(1, numberOfInputChannels + numberOfParameters)\n });\n const bufferSize = computeBufferSize(baseLatency, nativeContext.sampleRate);\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, bufferSize, numberOfInputChannels + numberOfParameters, \n // Bug #87: Only Firefox will fire an AudioProcessingEvent if there is no connected output.\n Math.max(1, numberOfOutputChannels));\n const outputChannelSplitterNode = createNativeChannelSplitterNode(nativeContext, {\n channelCount: Math.max(1, numberOfOutputChannels),\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: Math.max(1, numberOfOutputChannels)\n });\n const outputChannelMergerNodes = [];\n for (let i = 0; i < options.numberOfOutputs; i += 1) {\n outputChannelMergerNodes.push(createNativeChannelMergerNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: outputChannelCount[i]\n }));\n }\n for (let i = 0; i < options.numberOfInputs; i += 1) {\n gainNodes[i].connect(inputChannelSplitterNodes[i]);\n for (let j = 0; j < options.channelCount; j += 1) {\n inputChannelSplitterNodes[i].connect(inputChannelMergerNode, j, i * options.channelCount + j);\n }\n }\n const parameterMap = new ReadOnlyMap(processorConstructor.parameterDescriptors === undefined\n ? []\n : processorConstructor.parameterDescriptors.map(({ name }, index) => {\n const constantSourceNode = constantSourceNodes[index];\n constantSourceNode.connect(inputChannelMergerNode, 0, numberOfInputChannels + index);\n constantSourceNode.start(0);\n return [name, constantSourceNode.offset];\n }));\n inputChannelMergerNode.connect(scriptProcessorNode);\n let channelInterpretation = options.channelInterpretation;\n let onprocessorerror = null;\n // Bug #87: Expose at least one output to make this node connectable.\n const outputAudioNodes = options.numberOfOutputs === 0 ? [scriptProcessorNode] : outputChannelMergerNodes;\n const nativeAudioWorkletNodeFaker = {\n get bufferSize() {\n return bufferSize;\n },\n get channelCount() {\n return options.channelCount;\n },\n set channelCount(_) {\n // Bug #61: This is not part of the standard but required for the faker to work.\n throw createInvalidStateError();\n },\n get channelCountMode() {\n return options.channelCountMode;\n },\n set channelCountMode(_) {\n // Bug #61: This is not part of the standard but required for the faker to work.\n throw createInvalidStateError();\n },\n get channelInterpretation() {\n return channelInterpretation;\n },\n set channelInterpretation(value) {\n for (const gainNode of gainNodes) {\n gainNode.channelInterpretation = value;\n }\n channelInterpretation = value;\n },\n get context() {\n return scriptProcessorNode.context;\n },\n get inputs() {\n return gainNodes;\n },\n get numberOfInputs() {\n return options.numberOfInputs;\n },\n get numberOfOutputs() {\n return options.numberOfOutputs;\n },\n get onprocessorerror() {\n return onprocessorerror;\n },\n set onprocessorerror(value) {\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNodeFaker.removeEventListener(\'processorerror\', onprocessorerror);\n }\n onprocessorerror = typeof value === \'function\' ? value : null;\n if (typeof onprocessorerror === \'function\') {\n nativeAudioWorkletNodeFaker.addEventListener(\'processorerror\', onprocessorerror);\n }\n },\n get parameters() {\n return parameterMap;\n },\n get port() {\n return messageChannel.port2;\n },\n addEventListener(...args) {\n return scriptProcessorNode.addEventListener(args[0], args[1], args[2]);\n },\n connect: connectMultipleOutputs.bind(null, outputAudioNodes),\n disconnect: disconnectMultipleOutputs.bind(null, outputAudioNodes),\n dispatchEvent(...args) {\n return scriptProcessorNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return scriptProcessorNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n const patchedEventListeners = new Map();\n messageChannel.port1.addEventListener = ((addEventListener) => {\n return (...args) => {\n if (args[0] === \'message\') {\n const unpatchedEventListener = typeof args[1] === \'function\'\n ? args[1]\n : typeof args[1] === \'object\' && args[1] !== null && typeof args[1].handleEvent === \'function\'\n ? args[1].handleEvent\n : null;\n if (unpatchedEventListener !== null) {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n args[1] = patchedEventListener;\n }\n else {\n args[1] = (event) => {\n exposeCurrentFrameAndCurrentTime(nativeContext.currentTime, nativeContext.sampleRate, () => unpatchedEventListener(event));\n };\n patchedEventListeners.set(unpatchedEventListener, args[1]);\n }\n }\n }\n return addEventListener.call(messageChannel.port1, args[0], args[1], args[2]);\n };\n })(messageChannel.port1.addEventListener);\n messageChannel.port1.removeEventListener = ((removeEventListener) => {\n return (...args) => {\n if (args[0] === \'message\') {\n const patchedEventListener = patchedEventListeners.get(args[1]);\n if (patchedEventListener !== undefined) {\n patchedEventListeners.delete(args[1]);\n args[1] = patchedEventListener;\n }\n }\n return removeEventListener.call(messageChannel.port1, args[0], args[1], args[2]);\n };\n })(messageChannel.port1.removeEventListener);\n let onmessage = null;\n Object.defineProperty(messageChannel.port1, \'onmessage\', {\n get: () => onmessage,\n set: (value) => {\n if (typeof onmessage === \'function\') {\n messageChannel.port1.removeEventListener(\'message\', onmessage);\n }\n onmessage = typeof value === \'function\' ? value : null;\n if (typeof onmessage === \'function\') {\n messageChannel.port1.addEventListener(\'message\', onmessage);\n messageChannel.port1.start();\n }\n }\n });\n processorConstructor.prototype.port = messageChannel.port1;\n let audioWorkletProcessor = null;\n const audioWorkletProcessorPromise = createAudioWorkletProcessor(nativeContext, nativeAudioWorkletNodeFaker, processorConstructor, options);\n audioWorkletProcessorPromise.then((dWrkltPrcssr) => (audioWorkletProcessor = dWrkltPrcssr));\n const inputs = createNestedArrays(options.numberOfInputs, options.channelCount);\n const outputs = createNestedArrays(options.numberOfOutputs, outputChannelCount);\n const parameters = processorConstructor.parameterDescriptors === undefined\n ? []\n : processorConstructor.parameterDescriptors.reduce((prmtrs, { name }) => ({ ...prmtrs, [name]: new Float32Array(128) }), {});\n let isActive = true;\n const disconnectOutputsGraph = () => {\n if (options.numberOfOutputs > 0) {\n scriptProcessorNode.disconnect(outputChannelSplitterNode);\n }\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < options.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.disconnect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n };\n const activeInputIndexes = new Map();\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer, outputBuffer }) => {\n if (audioWorkletProcessor !== null) {\n const activeInputs = getActiveAudioWorkletNodeInputs(nativeAudioWorkletNodeFaker);\n for (let i = 0; i < bufferSize; i += 128) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < options.channelCount; k += 1) {\n copyFromChannel(inputBuffer, inputs[j], k, k, i);\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined) {\n processorConstructor.parameterDescriptors.forEach(({ name }, index) => {\n copyFromChannel(inputBuffer, parameters, name, numberOfInputChannels + index, i);\n });\n }\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n // The byteLength will be 0 when the ArrayBuffer was transferred.\n if (outputs[j][k].byteLength === 0) {\n outputs[j][k] = new Float32Array(128);\n }\n }\n }\n try {\n const potentiallyEmptyInputs = inputs.map((input, index) => {\n const activeInput = activeInputs[index];\n if (activeInput.size > 0) {\n activeInputIndexes.set(index, bufferSize / 128);\n return input;\n }\n const count = activeInputIndexes.get(index);\n if (count === undefined) {\n return [];\n }\n if (input.every((channelData) => channelData.every((sample) => sample === 0))) {\n if (count === 1) {\n activeInputIndexes.delete(index);\n }\n else {\n activeInputIndexes.set(index, count - 1);\n }\n }\n return input;\n });\n const activeSourceFlag = exposeCurrentFrameAndCurrentTime(nativeContext.currentTime + i / nativeContext.sampleRate, nativeContext.sampleRate, () => audioWorkletProcessor.process(potentiallyEmptyInputs, outputs, parameters));\n isActive = activeSourceFlag;\n for (let j = 0, outputChannelSplitterNodeOutput = 0; j < options.numberOfOutputs; j += 1) {\n for (let k = 0; k < outputChannelCount[j]; k += 1) {\n copyToChannel(outputBuffer, outputs[j], k, outputChannelSplitterNodeOutput + k, i);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[j];\n }\n }\n catch (error) {\n isActive = false;\n nativeAudioWorkletNodeFaker.dispatchEvent(new ErrorEvent(\'processorerror\', {\n colno: error.colno,\n filename: error.filename,\n lineno: error.lineno,\n message: error.message\n }));\n }\n if (!isActive) {\n for (let j = 0; j < options.numberOfInputs; j += 1) {\n gainNodes[j].disconnect(inputChannelSplitterNodes[j]);\n for (let k = 0; k < options.channelCount; k += 1) {\n inputChannelSplitterNodes[i].disconnect(inputChannelMergerNode, k, j * options.channelCount + k);\n }\n }\n if (processorConstructor.parameterDescriptors !== undefined) {\n const length = processorConstructor.parameterDescriptors.length;\n for (let j = 0; j < length; j += 1) {\n const constantSourceNode = constantSourceNodes[j];\n constantSourceNode.disconnect(inputChannelMergerNode, 0, numberOfInputChannels + j);\n constantSourceNode.stop();\n }\n }\n inputChannelMergerNode.disconnect(scriptProcessorNode);\n scriptProcessorNode.onaudioprocess = null; // tslint:disable-line:deprecation\n if (isConnected) {\n disconnectOutputsGraph();\n }\n else {\n disconnectFakeGraph();\n }\n break;\n }\n }\n }\n };\n let isConnected = false;\n // Bug #87: Only Firefox will fire an AudioProcessingEvent if there is no connected output.\n const nativeGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n const connectFakeGraph = () => scriptProcessorNode.connect(nativeGainNode).connect(nativeContext.destination);\n const disconnectFakeGraph = () => {\n scriptProcessorNode.disconnect(nativeGainNode);\n nativeGainNode.disconnect();\n };\n const whenConnected = () => {\n if (isActive) {\n disconnectFakeGraph();\n if (options.numberOfOutputs > 0) {\n scriptProcessorNode.connect(outputChannelSplitterNode);\n }\n for (let i = 0, outputChannelSplitterNodeOutput = 0; i < options.numberOfOutputs; i += 1) {\n const outputChannelMergerNode = outputChannelMergerNodes[i];\n for (let j = 0; j < outputChannelCount[i]; j += 1) {\n outputChannelSplitterNode.connect(outputChannelMergerNode, outputChannelSplitterNodeOutput + j, j);\n }\n outputChannelSplitterNodeOutput += outputChannelCount[i];\n }\n }\n isConnected = true;\n };\n const whenDisconnected = () => {\n if (isActive) {\n connectFakeGraph();\n disconnectOutputsGraph();\n }\n isConnected = false;\n };\n connectFakeGraph();\n return monitorConnections(nativeAudioWorkletNodeFaker, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-audio-worklet-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-biquad-filter-node.js\n\n\n\nconst createNativeBiquadFilterNode = (nativeContext, options) => {\n const nativeBiquadFilterNode = nativeContext.createBiquadFilter();\n assignNativeAudioNodeOptions(nativeBiquadFilterNode, options);\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'Q\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'detune\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'frequency\');\n assignNativeAudioNodeAudioParamValue(nativeBiquadFilterNode, options, \'gain\');\n assignNativeAudioNodeOption(nativeBiquadFilterNode, options, \'type\');\n return nativeBiquadFilterNode;\n};\n//# sourceMappingURL=native-biquad-filter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-channel-merger-node-factory.js\n\nconst createNativeChannelMergerNodeFactory = (nativeAudioContextConstructor, wrapChannelMergerNode) => {\n return (nativeContext, options) => {\n const nativeChannelMergerNode = nativeContext.createChannelMerger(options.numberOfInputs);\n /*\n * Bug #20: Safari requires a connection of any kind to treat the input signal correctly.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the existence of\n * the webkitAudioContext is used as a workaround here.\n */\n if (nativeAudioContextConstructor !== null && nativeAudioContextConstructor.name === \'webkitAudioContext\') {\n wrapChannelMergerNode(nativeContext, nativeChannelMergerNode);\n }\n assignNativeAudioNodeOptions(nativeChannelMergerNode, options);\n return nativeChannelMergerNode;\n };\n};\n//# sourceMappingURL=native-channel-merger-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-channel-splitter-node.js\n\nconst wrapChannelSplitterNode = (channelSplitterNode) => {\n const channelCount = channelSplitterNode.numberOfOutputs;\n // Bug #97: Safari does not throw an error when attempting to change the channelCount to something other than its initial value.\n Object.defineProperty(channelSplitterNode, \'channelCount\', {\n get: () => channelCount,\n set: (value) => {\n if (value !== channelCount) {\n throw createInvalidStateError();\n }\n }\n });\n // Bug #30: Safari does not throw an error when attempting to change the channelCountMode to something other than explicit.\n Object.defineProperty(channelSplitterNode, \'channelCountMode\', {\n get: () => \'explicit\',\n set: (value) => {\n if (value !== \'explicit\') {\n throw createInvalidStateError();\n }\n }\n });\n // Bug #32: Safari does not throw an error when attempting to change the channelInterpretation to something other than discrete.\n Object.defineProperty(channelSplitterNode, \'channelInterpretation\', {\n get: () => \'discrete\',\n set: (value) => {\n if (value !== \'discrete\') {\n throw createInvalidStateError();\n }\n }\n });\n};\n//# sourceMappingURL=wrap-channel-splitter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-channel-splitter-node.js\n\n\nconst createNativeChannelSplitterNode = (nativeContext, options) => {\n const nativeChannelSplitterNode = nativeContext.createChannelSplitter(options.numberOfOutputs);\n // Bug #96: Safari does not have the correct channelCount.\n // Bug #29: Safari does not have the correct channelCountMode.\n // Bug #31: Safari does not have the correct channelInterpretation.\n assignNativeAudioNodeOptions(nativeChannelSplitterNode, options);\n // Bug #29, #30, #31, #32, #96 & #97: Only Chrome, Edge & Firefox partially support the spec yet.\n wrapChannelSplitterNode(nativeChannelSplitterNode);\n return nativeChannelSplitterNode;\n};\n//# sourceMappingURL=native-channel-splitter-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-constant-source-node-factory.js\n\n\n\n\nconst createNativeConstantSourceNodeFactory = (addSilentConnection, cacheTestResult, createNativeConstantSourceNodeFaker, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport) => {\n return (nativeContext, options) => {\n // Bug #62: Safari does not support ConstantSourceNodes.\n if (nativeContext.createConstantSource === undefined) {\n return createNativeConstantSourceNodeFaker(nativeContext, options);\n }\n const nativeConstantSourceNode = nativeContext.createConstantSource();\n assignNativeAudioNodeOptions(nativeConstantSourceNode, options);\n assignNativeAudioNodeAudioParamValue(nativeConstantSourceNode, options, \'offset\');\n // Bug #44: Safari does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeConstantSourceNode);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeConstantSourceNode);\n }\n // Bug #175: Safari will not fire an ended event if the ConstantSourceNode is unconnected.\n addSilentConnection(nativeContext, nativeConstantSourceNode);\n return nativeConstantSourceNode;\n };\n};\n//# sourceMappingURL=native-constant-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/intercept-connections.js\nconst interceptConnections = (original, interceptor) => {\n original.connect = interceptor.connect.bind(interceptor);\n original.disconnect = interceptor.disconnect.bind(interceptor);\n return original;\n};\n//# sourceMappingURL=intercept-connections.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-constant-source-node-faker-factory.js\n\nconst createNativeConstantSourceNodeFakerFactory = (addSilentConnection, createNativeAudioBufferSourceNode, createNativeGainNode, monitorConnections) => {\n return (nativeContext, { offset, ...audioNodeOptions }) => {\n const audioBuffer = nativeContext.createBuffer(1, 2, 44100);\n const audioBufferSourceNode = createNativeAudioBufferSourceNode(nativeContext, {\n buffer: null,\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n playbackRate: 1\n });\n const gainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: offset });\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n const channelData = audioBuffer.getChannelData(0);\n // Bug #95: Safari does not play or loop one sample buffers.\n channelData[0] = 1;\n channelData[1] = 1;\n audioBufferSourceNode.buffer = audioBuffer;\n audioBufferSourceNode.loop = true;\n const nativeConstantSourceNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return gainNode.channelCount;\n },\n set channelCount(value) {\n gainNode.channelCount = value;\n },\n get channelCountMode() {\n return gainNode.channelCountMode;\n },\n set channelCountMode(value) {\n gainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return gainNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n gainNode.channelInterpretation = value;\n },\n get context() {\n return gainNode.context;\n },\n get inputs() {\n return [];\n },\n get numberOfInputs() {\n return audioBufferSourceNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return gainNode.numberOfOutputs;\n },\n get offset() {\n return gainNode.gain;\n },\n get onended() {\n return audioBufferSourceNode.onended;\n },\n set onended(value) {\n audioBufferSourceNode.onended = value;\n },\n addEventListener(...args) {\n return audioBufferSourceNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return audioBufferSourceNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return audioBufferSourceNode.removeEventListener(args[0], args[1], args[2]);\n },\n start(when = 0) {\n audioBufferSourceNode.start.call(audioBufferSourceNode, when);\n },\n stop(when = 0) {\n audioBufferSourceNode.stop.call(audioBufferSourceNode, when);\n }\n };\n const whenConnected = () => audioBufferSourceNode.connect(gainNode);\n const whenDisconnected = () => audioBufferSourceNode.disconnect(gainNode);\n // Bug #175: Safari will not fire an ended event if the AudioBufferSourceNode is unconnected.\n addSilentConnection(nativeContext, audioBufferSourceNode);\n return monitorConnections(interceptConnections(nativeConstantSourceNodeFaker, gainNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-constant-source-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-convolver-node-factory.js\n\n\nconst createNativeConvolverNodeFactory = (createNotSupportedError, overwriteAccessors) => {\n return (nativeContext, options) => {\n const nativeConvolverNode = nativeContext.createConvolver();\n assignNativeAudioNodeOptions(nativeConvolverNode, options);\n // The normalize property needs to be set before setting the buffer.\n if (options.disableNormalization === nativeConvolverNode.normalize) {\n nativeConvolverNode.normalize = !options.disableNormalization;\n }\n assignNativeAudioNodeOption(nativeConvolverNode, options, \'buffer\');\n // Bug #113: Safari does allow to set the channelCount to a value larger than 2.\n if (options.channelCount > 2) {\n throw createNotSupportedError();\n }\n overwriteAccessors(nativeConvolverNode, \'channelCount\', (get) => () => get.call(nativeConvolverNode), (set) => (value) => {\n if (value > 2) {\n throw createNotSupportedError();\n }\n return set.call(nativeConvolverNode, value);\n });\n // Bug #114: Safari allows to set the channelCountMode to \'max\'.\n if (options.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n overwriteAccessors(nativeConvolverNode, \'channelCountMode\', (get) => () => get.call(nativeConvolverNode), (set) => (value) => {\n if (value === \'max\') {\n throw createNotSupportedError();\n }\n return set.call(nativeConvolverNode, value);\n });\n return nativeConvolverNode;\n };\n};\n//# sourceMappingURL=native-convolver-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-delay-node.js\n\n\nconst createNativeDelayNode = (nativeContext, options) => {\n const nativeDelayNode = nativeContext.createDelay(options.maxDelayTime);\n assignNativeAudioNodeOptions(nativeDelayNode, options);\n assignNativeAudioNodeAudioParamValue(nativeDelayNode, options, \'delayTime\');\n return nativeDelayNode;\n};\n//# sourceMappingURL=native-delay-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-dynamics-compressor-node-factory.js\n\n\nconst createNativeDynamicsCompressorNodeFactory = (createNotSupportedError) => {\n return (nativeContext, options) => {\n const nativeDynamicsCompressorNode = nativeContext.createDynamicsCompressor();\n assignNativeAudioNodeOptions(nativeDynamicsCompressorNode, options);\n // Bug #108: Safari allows a channelCount of three and above.\n if (options.channelCount > 2) {\n throw createNotSupportedError();\n }\n // Bug #109: Only Chrome and Firefox disallow a channelCountMode of \'max\'.\n if (options.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'attack\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'knee\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'ratio\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'release\');\n assignNativeAudioNodeAudioParamValue(nativeDynamicsCompressorNode, options, \'threshold\');\n return nativeDynamicsCompressorNode;\n };\n};\n//# sourceMappingURL=native-dynamics-compressor-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-gain-node.js\n\n\nconst createNativeGainNode = (nativeContext, options) => {\n const nativeGainNode = nativeContext.createGain();\n assignNativeAudioNodeOptions(nativeGainNode, options);\n assignNativeAudioNodeAudioParamValue(nativeGainNode, options, \'gain\');\n return nativeGainNode;\n};\n//# sourceMappingURL=native-gain-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-iir-filter-node-factory.js\n\nconst createNativeIIRFilterNodeFactory = (createNativeIIRFilterNodeFaker) => {\n return (nativeContext, baseLatency, options) => {\n // Bug #9: Safari does not support IIRFilterNodes.\n if (nativeContext.createIIRFilter === undefined) {\n return createNativeIIRFilterNodeFaker(nativeContext, baseLatency, options);\n }\n // @todo TypeScript defines the parameters of createIIRFilter() as arrays of numbers.\n const nativeIIRFilterNode = nativeContext.createIIRFilter(options.feedforward, options.feedback);\n assignNativeAudioNodeOptions(nativeIIRFilterNode, options);\n return nativeIIRFilterNode;\n };\n};\n//# sourceMappingURL=native-iir-filter-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-iir-filter-node-faker-factory.js\n\n\n\nfunction divide(a, b) {\n const denominator = b[0] * b[0] + b[1] * b[1];\n return [(a[0] * b[0] + a[1] * b[1]) / denominator, (a[1] * b[0] - a[0] * b[1]) / denominator];\n}\nfunction multiply(a, b) {\n return [a[0] * b[0] - a[1] * b[1], a[0] * b[1] + a[1] * b[0]];\n}\nfunction evaluatePolynomial(coefficient, z) {\n let result = [0, 0];\n for (let i = coefficient.length - 1; i >= 0; i -= 1) {\n result = multiply(result, z);\n result[0] += coefficient[i];\n }\n return result;\n}\nconst createNativeIIRFilterNodeFakerFactory = (createInvalidAccessError, createInvalidStateError, createNativeScriptProcessorNode, createNotSupportedError) => {\n return (nativeContext, baseLatency, { channelCount, channelCountMode, channelInterpretation, feedback, feedforward }) => {\n const bufferSize = computeBufferSize(baseLatency, nativeContext.sampleRate);\n const convertedFeedback = feedback instanceof Float64Array ? feedback : new Float64Array(feedback);\n const convertedFeedforward = feedforward instanceof Float64Array ? feedforward : new Float64Array(feedforward);\n const feedbackLength = convertedFeedback.length;\n const feedforwardLength = convertedFeedforward.length;\n const minLength = Math.min(feedbackLength, feedforwardLength);\n if (feedbackLength === 0 || feedbackLength > 20) {\n throw createNotSupportedError();\n }\n if (convertedFeedback[0] === 0) {\n throw createInvalidStateError();\n }\n if (feedforwardLength === 0 || feedforwardLength > 20) {\n throw createNotSupportedError();\n }\n if (convertedFeedforward[0] === 0) {\n throw createInvalidStateError();\n }\n if (convertedFeedback[0] !== 1) {\n for (let i = 0; i < feedforwardLength; i += 1) {\n convertedFeedforward[i] /= convertedFeedback[0];\n }\n for (let i = 1; i < feedbackLength; i += 1) {\n convertedFeedback[i] /= convertedFeedback[0];\n }\n }\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, bufferSize, channelCount, channelCount);\n scriptProcessorNode.channelCount = channelCount;\n scriptProcessorNode.channelCountMode = channelCountMode;\n scriptProcessorNode.channelInterpretation = channelInterpretation;\n const bufferLength = 32;\n const bufferIndexes = [];\n const xBuffers = [];\n const yBuffers = [];\n for (let i = 0; i < channelCount; i += 1) {\n bufferIndexes.push(0);\n const xBuffer = new Float32Array(bufferLength);\n const yBuffer = new Float32Array(bufferLength);\n xBuffer.fill(0);\n yBuffer.fill(0);\n xBuffers.push(xBuffer);\n yBuffers.push(yBuffer);\n }\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = (event) => {\n const inputBuffer = event.inputBuffer;\n const outputBuffer = event.outputBuffer;\n const numberOfChannels = inputBuffer.numberOfChannels;\n for (let i = 0; i < numberOfChannels; i += 1) {\n const input = inputBuffer.getChannelData(i);\n const output = outputBuffer.getChannelData(i);\n bufferIndexes[i] = filterBuffer(convertedFeedback, feedbackLength, convertedFeedforward, feedforwardLength, minLength, xBuffers[i], yBuffers[i], bufferIndexes[i], bufferLength, input, output);\n }\n };\n const nyquist = nativeContext.sampleRate / 2;\n const nativeIIRFilterNodeFaker = {\n get bufferSize() {\n return bufferSize;\n },\n get channelCount() {\n return scriptProcessorNode.channelCount;\n },\n set channelCount(value) {\n scriptProcessorNode.channelCount = value;\n },\n get channelCountMode() {\n return scriptProcessorNode.channelCountMode;\n },\n set channelCountMode(value) {\n scriptProcessorNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return scriptProcessorNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n scriptProcessorNode.channelInterpretation = value;\n },\n get context() {\n return scriptProcessorNode.context;\n },\n get inputs() {\n return [scriptProcessorNode];\n },\n get numberOfInputs() {\n return scriptProcessorNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return scriptProcessorNode.numberOfOutputs;\n },\n addEventListener(...args) {\n // @todo Dissallow adding an audioprocess listener.\n return scriptProcessorNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return scriptProcessorNode.dispatchEvent(args[0]);\n },\n getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {\n if (frequencyHz.length !== magResponse.length || magResponse.length !== phaseResponse.length) {\n throw createInvalidAccessError();\n }\n const length = frequencyHz.length;\n for (let i = 0; i < length; i += 1) {\n const omega = -Math.PI * (frequencyHz[i] / nyquist);\n const z = [Math.cos(omega), Math.sin(omega)];\n const numerator = evaluatePolynomial(convertedFeedforward, z);\n const denominator = evaluatePolynomial(convertedFeedback, z);\n const response = divide(numerator, denominator);\n magResponse[i] = Math.sqrt(response[0] * response[0] + response[1] * response[1]);\n phaseResponse[i] = Math.atan2(response[1], response[0]);\n }\n },\n removeEventListener(...args) {\n return scriptProcessorNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n return interceptConnections(nativeIIRFilterNodeFaker, scriptProcessorNode);\n };\n};\n//# sourceMappingURL=native-iir-filter-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-element-audio-source-node.js\nconst createNativeMediaElementAudioSourceNode = (nativeAudioContext, options) => {\n return nativeAudioContext.createMediaElementSource(options.mediaElement);\n};\n//# sourceMappingURL=native-media-element-audio-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-audio-destination-node.js\n\nconst createNativeMediaStreamAudioDestinationNode = (nativeAudioContext, options) => {\n const nativeMediaStreamAudioDestinationNode = nativeAudioContext.createMediaStreamDestination();\n assignNativeAudioNodeOptions(nativeMediaStreamAudioDestinationNode, options);\n // Bug #174: Safari does expose a wrong numberOfOutputs.\n if (nativeMediaStreamAudioDestinationNode.numberOfOutputs === 1) {\n Object.defineProperty(nativeMediaStreamAudioDestinationNode, \'numberOfOutputs\', { get: () => 0 });\n }\n return nativeMediaStreamAudioDestinationNode;\n};\n//# sourceMappingURL=native-media-stream-audio-destination-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-audio-source-node.js\nconst createNativeMediaStreamAudioSourceNode = (nativeAudioContext, { mediaStream }) => {\n const audioStreamTracks = mediaStream.getAudioTracks();\n /*\n * Bug #151: Safari does not use the audio track as input anymore if it gets removed from the mediaStream after construction.\n * Bug #159: Safari picks the first audio track if the MediaStream has more than one audio track.\n */\n audioStreamTracks.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));\n const filteredAudioStreamTracks = audioStreamTracks.slice(0, 1);\n const nativeMediaStreamAudioSourceNode = nativeAudioContext.createMediaStreamSource(new MediaStream(filteredAudioStreamTracks));\n /*\n * Bug #151 & #159: The given mediaStream gets reconstructed before it gets passed to the native node which is why the accessor needs\n * to be overwritten as it would otherwise expose the reconstructed version.\n */\n Object.defineProperty(nativeMediaStreamAudioSourceNode, \'mediaStream\', { value: mediaStream });\n return nativeMediaStreamAudioSourceNode;\n};\n//# sourceMappingURL=native-media-stream-audio-source-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-media-stream-track-audio-source-node-factory.js\nconst createNativeMediaStreamTrackAudioSourceNodeFactory = (createInvalidStateError, isNativeOfflineAudioContext) => {\n return (nativeAudioContext, { mediaStreamTrack }) => {\n // Bug #121: Only Firefox does yet support the MediaStreamTrackAudioSourceNode.\n if (typeof nativeAudioContext.createMediaStreamTrackSource === \'function\') {\n return nativeAudioContext.createMediaStreamTrackSource(mediaStreamTrack);\n }\n const mediaStream = new MediaStream([mediaStreamTrack]);\n const nativeMediaStreamAudioSourceNode = nativeAudioContext.createMediaStreamSource(mediaStream);\n // Bug #120: Firefox does not throw an error if the mediaStream has no audio track.\n if (mediaStreamTrack.kind !== \'audio\') {\n throw createInvalidStateError();\n }\n // Bug #172: Safari allows to create a MediaStreamAudioSourceNode with an OfflineAudioContext.\n if (isNativeOfflineAudioContext(nativeAudioContext)) {\n throw new TypeError();\n }\n return nativeMediaStreamAudioSourceNode;\n };\n};\n//# sourceMappingURL=native-media-stream-track-audio-source-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-offline-audio-context-constructor.js\nconst createNativeOfflineAudioContextConstructor = (window) => {\n if (window === null) {\n return null;\n }\n if (window.hasOwnProperty(\'OfflineAudioContext\')) {\n return window.OfflineAudioContext;\n }\n return window.hasOwnProperty(\'webkitOfflineAudioContext\') ? window.webkitOfflineAudioContext : null;\n};\n//# sourceMappingURL=native-offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-oscillator-node-factory.js\n\n\n\n\n\nconst createNativeOscillatorNodeFactory = (addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls) => {\n return (nativeContext, options) => {\n const nativeOscillatorNode = nativeContext.createOscillator();\n assignNativeAudioNodeOptions(nativeOscillatorNode, options);\n assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, \'detune\');\n assignNativeAudioNodeAudioParamValue(nativeOscillatorNode, options, \'frequency\');\n if (options.periodicWave !== undefined) {\n nativeOscillatorNode.setPeriodicWave(options.periodicWave);\n }\n else {\n assignNativeAudioNodeOption(nativeOscillatorNode, options, \'type\');\n }\n // Bug #44: Only Chrome & Edge throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStartMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStartMethodNegativeParameters(nativeOscillatorNode);\n }\n // Bug #19: Safari does not ignore calls to stop() of an already stopped AudioBufferSourceNode.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, () => testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls(nativeOscillatorNode, nativeContext);\n }\n // Bug #44: Only Firefox does not throw a RangeError yet.\n if (!cacheTestResult(testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, () => testAudioScheduledSourceNodeStopMethodNegativeParametersSupport(nativeContext))) {\n wrapAudioScheduledSourceNodeStopMethodNegativeParameters(nativeOscillatorNode);\n }\n // Bug #175: Safari will not fire an ended event if the OscillatorNode is unconnected.\n addSilentConnection(nativeContext, nativeOscillatorNode);\n return nativeOscillatorNode;\n };\n};\n//# sourceMappingURL=native-oscillator-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-panner-node-factory.js\n\n\n\nconst createNativePannerNodeFactory = (createNativePannerNodeFaker) => {\n return (nativeContext, options) => {\n const nativePannerNode = nativeContext.createPanner();\n // Bug #124: Safari does not support modifying the orientation and the position with AudioParams.\n if (nativePannerNode.orientationX === undefined) {\n return createNativePannerNodeFaker(nativeContext, options);\n }\n assignNativeAudioNodeOptions(nativePannerNode, options);\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationX\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationY\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'orientationZ\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionX\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionY\');\n assignNativeAudioNodeAudioParamValue(nativePannerNode, options, \'positionZ\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneInnerAngle\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneOuterAngle\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'coneOuterGain\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'distanceModel\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'maxDistance\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'panningModel\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'refDistance\');\n assignNativeAudioNodeOption(nativePannerNode, options, \'rolloffFactor\');\n return nativePannerNode;\n };\n};\n//# sourceMappingURL=native-panner-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-panner-node-faker-factory.js\n\n\nconst createNativePannerNodeFakerFactory = (connectNativeAudioNodeToNativeAudioNode, createInvalidStateError, createNativeChannelMergerNode, createNativeGainNode, createNativeScriptProcessorNode, createNativeWaveShaperNode, createNotSupportedError, disconnectNativeAudioNodeFromNativeAudioNode, getFirstSample, monitorConnections) => {\n return (nativeContext, { coneInnerAngle, coneOuterAngle, coneOuterGain, distanceModel, maxDistance, orientationX, orientationY, orientationZ, panningModel, positionX, positionY, positionZ, refDistance, rolloffFactor, ...audioNodeOptions }) => {\n const pannerNode = nativeContext.createPanner();\n // Bug #125: Safari does not throw an error yet.\n if (audioNodeOptions.channelCount > 2) {\n throw createNotSupportedError();\n }\n // Bug #126: Safari does not throw an error yet.\n if (audioNodeOptions.channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n assignNativeAudioNodeOptions(pannerNode, audioNodeOptions);\n const SINGLE_CHANNEL_OPTIONS = {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\'\n };\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n ...SINGLE_CHANNEL_OPTIONS,\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n });\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const orientationXGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 1 });\n const orientationYGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const orientationZGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionXGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionYGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const positionZGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeContext, 256, 6, 1);\n const waveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_OPTIONS,\n curve: new Float32Array([1, 1]),\n oversample: \'none\'\n });\n let lastOrientation = [orientationX, orientationY, orientationZ];\n let lastPosition = [positionX, positionY, positionZ];\n const buffer = new Float32Array(1);\n // tslint:disable-next-line:deprecation\n scriptProcessorNode.onaudioprocess = ({ inputBuffer }) => {\n const orientation = [\n getFirstSample(inputBuffer, buffer, 0),\n getFirstSample(inputBuffer, buffer, 1),\n getFirstSample(inputBuffer, buffer, 2)\n ];\n if (orientation.some((value, index) => value !== lastOrientation[index])) {\n pannerNode.setOrientation(...orientation); // tslint:disable-line:deprecation\n lastOrientation = orientation;\n }\n const positon = [\n getFirstSample(inputBuffer, buffer, 3),\n getFirstSample(inputBuffer, buffer, 4),\n getFirstSample(inputBuffer, buffer, 5)\n ];\n if (positon.some((value, index) => value !== lastPosition[index])) {\n pannerNode.setPosition(...positon); // tslint:disable-line:deprecation\n lastPosition = positon;\n }\n };\n Object.defineProperty(orientationYGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(orientationZGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionXGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionYGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(positionZGainNode.gain, \'defaultValue\', { get: () => 0 });\n const nativePannerNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return pannerNode.channelCount;\n },\n set channelCount(value) {\n // Bug #125: Safari does not throw an error yet.\n if (value > 2) {\n throw createNotSupportedError();\n }\n inputGainNode.channelCount = value;\n pannerNode.channelCount = value;\n },\n get channelCountMode() {\n return pannerNode.channelCountMode;\n },\n set channelCountMode(value) {\n // Bug #126: Safari does not throw an error yet.\n if (value === \'max\') {\n throw createNotSupportedError();\n }\n inputGainNode.channelCountMode = value;\n pannerNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return pannerNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n pannerNode.channelInterpretation = value;\n },\n get coneInnerAngle() {\n return pannerNode.coneInnerAngle;\n },\n set coneInnerAngle(value) {\n pannerNode.coneInnerAngle = value;\n },\n get coneOuterAngle() {\n return pannerNode.coneOuterAngle;\n },\n set coneOuterAngle(value) {\n pannerNode.coneOuterAngle = value;\n },\n get coneOuterGain() {\n return pannerNode.coneOuterGain;\n },\n set coneOuterGain(value) {\n // Bug #127: Safari does not throw an InvalidStateError yet.\n if (value < 0 || value > 1) {\n throw createInvalidStateError();\n }\n pannerNode.coneOuterGain = value;\n },\n get context() {\n return pannerNode.context;\n },\n get distanceModel() {\n return pannerNode.distanceModel;\n },\n set distanceModel(value) {\n pannerNode.distanceModel = value;\n },\n get inputs() {\n return [inputGainNode];\n },\n get maxDistance() {\n return pannerNode.maxDistance;\n },\n set maxDistance(value) {\n // Bug #128: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.maxDistance = value;\n },\n get numberOfInputs() {\n return pannerNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return pannerNode.numberOfOutputs;\n },\n get orientationX() {\n return orientationXGainNode.gain;\n },\n get orientationY() {\n return orientationYGainNode.gain;\n },\n get orientationZ() {\n return orientationZGainNode.gain;\n },\n get panningModel() {\n return pannerNode.panningModel;\n },\n set panningModel(value) {\n pannerNode.panningModel = value;\n },\n get positionX() {\n return positionXGainNode.gain;\n },\n get positionY() {\n return positionYGainNode.gain;\n },\n get positionZ() {\n return positionZGainNode.gain;\n },\n get refDistance() {\n return pannerNode.refDistance;\n },\n set refDistance(value) {\n // Bug #129: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.refDistance = value;\n },\n get rolloffFactor() {\n return pannerNode.rolloffFactor;\n },\n set rolloffFactor(value) {\n // Bug #130: Safari does not throw an error yet.\n if (value < 0) {\n throw new RangeError();\n }\n pannerNode.rolloffFactor = value;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n if (coneInnerAngle !== nativePannerNodeFaker.coneInnerAngle) {\n nativePannerNodeFaker.coneInnerAngle = coneInnerAngle;\n }\n if (coneOuterAngle !== nativePannerNodeFaker.coneOuterAngle) {\n nativePannerNodeFaker.coneOuterAngle = coneOuterAngle;\n }\n if (coneOuterGain !== nativePannerNodeFaker.coneOuterGain) {\n nativePannerNodeFaker.coneOuterGain = coneOuterGain;\n }\n if (distanceModel !== nativePannerNodeFaker.distanceModel) {\n nativePannerNodeFaker.distanceModel = distanceModel;\n }\n if (maxDistance !== nativePannerNodeFaker.maxDistance) {\n nativePannerNodeFaker.maxDistance = maxDistance;\n }\n if (orientationX !== nativePannerNodeFaker.orientationX.value) {\n nativePannerNodeFaker.orientationX.value = orientationX;\n }\n if (orientationY !== nativePannerNodeFaker.orientationY.value) {\n nativePannerNodeFaker.orientationY.value = orientationY;\n }\n if (orientationZ !== nativePannerNodeFaker.orientationZ.value) {\n nativePannerNodeFaker.orientationZ.value = orientationZ;\n }\n if (panningModel !== nativePannerNodeFaker.panningModel) {\n nativePannerNodeFaker.panningModel = panningModel;\n }\n if (positionX !== nativePannerNodeFaker.positionX.value) {\n nativePannerNodeFaker.positionX.value = positionX;\n }\n if (positionY !== nativePannerNodeFaker.positionY.value) {\n nativePannerNodeFaker.positionY.value = positionY;\n }\n if (positionZ !== nativePannerNodeFaker.positionZ.value) {\n nativePannerNodeFaker.positionZ.value = positionZ;\n }\n if (refDistance !== nativePannerNodeFaker.refDistance) {\n nativePannerNodeFaker.refDistance = refDistance;\n }\n if (rolloffFactor !== nativePannerNodeFaker.rolloffFactor) {\n nativePannerNodeFaker.rolloffFactor = rolloffFactor;\n }\n if (lastOrientation[0] !== 1 || lastOrientation[1] !== 0 || lastOrientation[2] !== 0) {\n pannerNode.setOrientation(...lastOrientation); // tslint:disable-line:deprecation\n }\n if (lastPosition[0] !== 0 || lastPosition[1] !== 0 || lastPosition[2] !== 0) {\n pannerNode.setPosition(...lastPosition); // tslint:disable-line:deprecation\n }\n const whenConnected = () => {\n inputGainNode.connect(pannerNode);\n // Bug #119: Safari does not fully support the WaveShaperNode.\n connectNativeAudioNodeToNativeAudioNode(inputGainNode, waveShaperNode, 0, 0);\n waveShaperNode.connect(orientationXGainNode).connect(channelMergerNode, 0, 0);\n waveShaperNode.connect(orientationYGainNode).connect(channelMergerNode, 0, 1);\n waveShaperNode.connect(orientationZGainNode).connect(channelMergerNode, 0, 2);\n waveShaperNode.connect(positionXGainNode).connect(channelMergerNode, 0, 3);\n waveShaperNode.connect(positionYGainNode).connect(channelMergerNode, 0, 4);\n waveShaperNode.connect(positionZGainNode).connect(channelMergerNode, 0, 5);\n channelMergerNode.connect(scriptProcessorNode).connect(nativeContext.destination);\n };\n const whenDisconnected = () => {\n inputGainNode.disconnect(pannerNode);\n // Bug #119: Safari does not fully support the WaveShaperNode.\n disconnectNativeAudioNodeFromNativeAudioNode(inputGainNode, waveShaperNode, 0, 0);\n waveShaperNode.disconnect(orientationXGainNode);\n orientationXGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(orientationYGainNode);\n orientationYGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(orientationZGainNode);\n orientationZGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionXGainNode);\n positionXGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionYGainNode);\n positionYGainNode.disconnect(channelMergerNode);\n waveShaperNode.disconnect(positionZGainNode);\n positionZGainNode.disconnect(channelMergerNode);\n channelMergerNode.disconnect(scriptProcessorNode);\n scriptProcessorNode.disconnect(nativeContext.destination);\n };\n return monitorConnections(interceptConnections(nativePannerNodeFaker, pannerNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-panner-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-periodic-wave-factory.js\nconst createNativePeriodicWaveFactory = (createIndexSizeError) => {\n return (nativeContext, { disableNormalization, imag, real }) => {\n // Bug #180: Safari does not allow to use ordinary arrays.\n const convertedImag = imag instanceof Float32Array ? imag : new Float32Array(imag);\n const convertedReal = real instanceof Float32Array ? real : new Float32Array(real);\n const nativePeriodicWave = nativeContext.createPeriodicWave(convertedReal, convertedImag, { disableNormalization });\n // Bug #181: Safari does not throw an IndexSizeError so far if the given arrays have less than two values.\n if (Array.from(imag).length < 2) {\n throw createIndexSizeError();\n }\n return nativePeriodicWave;\n };\n};\n//# sourceMappingURL=native-periodic-wave-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-script-processor-node.js\nconst createNativeScriptProcessorNode = (nativeContext, bufferSize, numberOfInputChannels, numberOfOutputChannels) => {\n return nativeContext.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels); // tslint:disable-line deprecation\n};\n//# sourceMappingURL=native-script-processor-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-stereo-panner-node-factory.js\n\n\nconst createNativeStereoPannerNodeFactory = (createNativeStereoPannerNodeFaker, createNotSupportedError) => {\n return (nativeContext, options) => {\n const channelCountMode = options.channelCountMode;\n /*\n * Bug #105: The channelCountMode of \'clamped-max\' should be supported. However it is not possible to write a polyfill for Safari\n * which supports it and therefore it can\'t be supported at all.\n */\n if (channelCountMode === \'clamped-max\') {\n throw createNotSupportedError();\n }\n // Bug #105: Safari does not support the StereoPannerNode.\n if (nativeContext.createStereoPanner === undefined) {\n return createNativeStereoPannerNodeFaker(nativeContext, options);\n }\n const nativeStereoPannerNode = nativeContext.createStereoPanner();\n assignNativeAudioNodeOptions(nativeStereoPannerNode, options);\n assignNativeAudioNodeAudioParamValue(nativeStereoPannerNode, options, \'pan\');\n /*\n * Bug #105: The channelCountMode of \'clamped-max\' should be supported. However it is not possible to write a polyfill for Safari\n * which supports it and therefore it can\'t be supported at all.\n */\n Object.defineProperty(nativeStereoPannerNode, \'channelCountMode\', {\n get: () => channelCountMode,\n set: (value) => {\n if (value !== channelCountMode) {\n throw createNotSupportedError();\n }\n }\n });\n return nativeStereoPannerNode;\n };\n};\n//# sourceMappingURL=native-stereo-panner-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-stereo-panner-node-faker-factory.js\n\nconst createNativeStereoPannerNodeFakerFactory = (createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeGainNode, createNativeWaveShaperNode, createNotSupportedError, monitorConnections) => {\n // The curve has a size of 14bit plus 1 value to have an exact representation for zero. This value has been determined experimentally.\n const CURVE_SIZE = 16385;\n const DC_CURVE = new Float32Array([1, 1]);\n const HALF_PI = Math.PI / 2;\n const SINGLE_CHANNEL_OPTIONS = { channelCount: 1, channelCountMode: \'explicit\', channelInterpretation: \'discrete\' };\n const SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS = { ...SINGLE_CHANNEL_OPTIONS, oversample: \'none\' };\n const buildInternalGraphForMono = (nativeContext, inputGainNode, panGainNode, channelMergerNode) => {\n const leftWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightWaveShaperCurve = new Float32Array(CURVE_SIZE);\n for (let i = 0; i < CURVE_SIZE; i += 1) {\n const x = (i / (CURVE_SIZE - 1)) * HALF_PI;\n leftWaveShaperCurve[i] = Math.cos(x);\n rightWaveShaperCurve[i] = Math.sin(x);\n }\n const leftGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: leftWaveShaperCurve }));\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const panWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: DC_CURVE }));\n const rightGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: rightWaveShaperCurve }));\n return {\n connectGraph() {\n inputGainNode.connect(leftGainNode);\n inputGainNode.connect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n inputGainNode.connect(rightGainNode);\n panWaveShaperNode.connect(panGainNode);\n panGainNode.connect(leftWaveShaperNode.inputs === undefined ? leftWaveShaperNode : leftWaveShaperNode.inputs[0]);\n panGainNode.connect(rightWaveShaperNode.inputs === undefined ? rightWaveShaperNode : rightWaveShaperNode.inputs[0]);\n leftWaveShaperNode.connect(leftGainNode.gain);\n rightWaveShaperNode.connect(rightGainNode.gain);\n leftGainNode.connect(channelMergerNode, 0, 0);\n rightGainNode.connect(channelMergerNode, 0, 1);\n },\n disconnectGraph() {\n inputGainNode.disconnect(leftGainNode);\n inputGainNode.disconnect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n inputGainNode.disconnect(rightGainNode);\n panWaveShaperNode.disconnect(panGainNode);\n panGainNode.disconnect(leftWaveShaperNode.inputs === undefined ? leftWaveShaperNode : leftWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightWaveShaperNode.inputs === undefined ? rightWaveShaperNode : rightWaveShaperNode.inputs[0]);\n leftWaveShaperNode.disconnect(leftGainNode.gain);\n rightWaveShaperNode.disconnect(rightGainNode.gain);\n leftGainNode.disconnect(channelMergerNode, 0, 0);\n rightGainNode.disconnect(channelMergerNode, 0, 1);\n }\n };\n };\n const buildInternalGraphForStereo = (nativeContext, inputGainNode, panGainNode, channelMergerNode) => {\n const leftInputForLeftOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const leftInputForRightOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightInputForLeftOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const rightInputForRightOutputWaveShaperCurve = new Float32Array(CURVE_SIZE);\n const centerIndex = Math.floor(CURVE_SIZE / 2);\n for (let i = 0; i < CURVE_SIZE; i += 1) {\n if (i > centerIndex) {\n const x = ((i - centerIndex) / (CURVE_SIZE - 1 - centerIndex)) * HALF_PI;\n leftInputForLeftOutputWaveShaperCurve[i] = Math.cos(x);\n leftInputForRightOutputWaveShaperCurve[i] = Math.sin(x);\n rightInputForLeftOutputWaveShaperCurve[i] = 0;\n rightInputForRightOutputWaveShaperCurve[i] = 1;\n }\n else {\n const x = (i / (CURVE_SIZE - 1 - centerIndex)) * HALF_PI;\n leftInputForLeftOutputWaveShaperCurve[i] = 1;\n leftInputForRightOutputWaveShaperCurve[i] = 0;\n rightInputForLeftOutputWaveShaperCurve[i] = Math.cos(x);\n rightInputForRightOutputWaveShaperCurve[i] = Math.sin(x);\n }\n }\n const channelSplitterNode = createNativeChannelSplitterNode(nativeContext, {\n channelCount: 2,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n numberOfOutputs: 2\n });\n const leftInputForLeftOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftInputForLeftOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: leftInputForLeftOutputWaveShaperCurve\n });\n const leftInputForRightOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const leftInputForRightOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: leftInputForRightOutputWaveShaperCurve\n });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const panWaveShaperNode = (createNativeWaveShaperNode(nativeContext, { ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS, curve: DC_CURVE }));\n const rightInputForLeftOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightInputForLeftOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: rightInputForLeftOutputWaveShaperCurve\n });\n const rightInputForRightOutputGainNode = createNativeGainNode(nativeContext, { ...SINGLE_CHANNEL_OPTIONS, gain: 0 });\n // Bug #119: Safari does not fully support the WaveShaperNode.\n const rightInputForRightOutputWaveShaperNode = createNativeWaveShaperNode(nativeContext, {\n ...SINGLE_CHANNEL_WAVE_SHAPER_OPTIONS,\n curve: rightInputForRightOutputWaveShaperCurve\n });\n return {\n connectGraph() {\n inputGainNode.connect(channelSplitterNode);\n inputGainNode.connect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n channelSplitterNode.connect(leftInputForLeftOutputGainNode, 0);\n channelSplitterNode.connect(leftInputForRightOutputGainNode, 0);\n channelSplitterNode.connect(rightInputForLeftOutputGainNode, 1);\n channelSplitterNode.connect(rightInputForRightOutputGainNode, 1);\n panWaveShaperNode.connect(panGainNode);\n panGainNode.connect(leftInputForLeftOutputWaveShaperNode.inputs === undefined\n ? leftInputForLeftOutputWaveShaperNode\n : leftInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(leftInputForRightOutputWaveShaperNode.inputs === undefined\n ? leftInputForRightOutputWaveShaperNode\n : leftInputForRightOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(rightInputForLeftOutputWaveShaperNode.inputs === undefined\n ? rightInputForLeftOutputWaveShaperNode\n : rightInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.connect(rightInputForRightOutputWaveShaperNode.inputs === undefined\n ? rightInputForRightOutputWaveShaperNode\n : rightInputForRightOutputWaveShaperNode.inputs[0]);\n leftInputForLeftOutputWaveShaperNode.connect(leftInputForLeftOutputGainNode.gain);\n leftInputForRightOutputWaveShaperNode.connect(leftInputForRightOutputGainNode.gain);\n rightInputForLeftOutputWaveShaperNode.connect(rightInputForLeftOutputGainNode.gain);\n rightInputForRightOutputWaveShaperNode.connect(rightInputForRightOutputGainNode.gain);\n leftInputForLeftOutputGainNode.connect(channelMergerNode, 0, 0);\n rightInputForLeftOutputGainNode.connect(channelMergerNode, 0, 0);\n leftInputForRightOutputGainNode.connect(channelMergerNode, 0, 1);\n rightInputForRightOutputGainNode.connect(channelMergerNode, 0, 1);\n },\n disconnectGraph() {\n inputGainNode.disconnect(channelSplitterNode);\n inputGainNode.disconnect(panWaveShaperNode.inputs === undefined ? panWaveShaperNode : panWaveShaperNode.inputs[0]);\n channelSplitterNode.disconnect(leftInputForLeftOutputGainNode, 0);\n channelSplitterNode.disconnect(leftInputForRightOutputGainNode, 0);\n channelSplitterNode.disconnect(rightInputForLeftOutputGainNode, 1);\n channelSplitterNode.disconnect(rightInputForRightOutputGainNode, 1);\n panWaveShaperNode.disconnect(panGainNode);\n panGainNode.disconnect(leftInputForLeftOutputWaveShaperNode.inputs === undefined\n ? leftInputForLeftOutputWaveShaperNode\n : leftInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(leftInputForRightOutputWaveShaperNode.inputs === undefined\n ? leftInputForRightOutputWaveShaperNode\n : leftInputForRightOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightInputForLeftOutputWaveShaperNode.inputs === undefined\n ? rightInputForLeftOutputWaveShaperNode\n : rightInputForLeftOutputWaveShaperNode.inputs[0]);\n panGainNode.disconnect(rightInputForRightOutputWaveShaperNode.inputs === undefined\n ? rightInputForRightOutputWaveShaperNode\n : rightInputForRightOutputWaveShaperNode.inputs[0]);\n leftInputForLeftOutputWaveShaperNode.disconnect(leftInputForLeftOutputGainNode.gain);\n leftInputForRightOutputWaveShaperNode.disconnect(leftInputForRightOutputGainNode.gain);\n rightInputForLeftOutputWaveShaperNode.disconnect(rightInputForLeftOutputGainNode.gain);\n rightInputForRightOutputWaveShaperNode.disconnect(rightInputForRightOutputGainNode.gain);\n leftInputForLeftOutputGainNode.disconnect(channelMergerNode, 0, 0);\n rightInputForLeftOutputGainNode.disconnect(channelMergerNode, 0, 0);\n leftInputForRightOutputGainNode.disconnect(channelMergerNode, 0, 1);\n rightInputForRightOutputGainNode.disconnect(channelMergerNode, 0, 1);\n }\n };\n };\n const buildInternalGraph = (nativeContext, channelCount, inputGainNode, panGainNode, channelMergerNode) => {\n if (channelCount === 1) {\n return buildInternalGraphForMono(nativeContext, inputGainNode, panGainNode, channelMergerNode);\n }\n if (channelCount === 2) {\n return buildInternalGraphForStereo(nativeContext, inputGainNode, panGainNode, channelMergerNode);\n }\n throw createNotSupportedError();\n };\n return (nativeContext, { channelCount, channelCountMode, pan, ...audioNodeOptions }) => {\n if (channelCountMode === \'max\') {\n throw createNotSupportedError();\n }\n const channelMergerNode = createNativeChannelMergerNode(nativeContext, {\n ...audioNodeOptions,\n channelCount: 1,\n channelCountMode,\n numberOfInputs: 2\n });\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, channelCount, channelCountMode, gain: 1 });\n const panGainNode = createNativeGainNode(nativeContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: pan\n });\n let { connectGraph, disconnectGraph } = buildInternalGraph(nativeContext, channelCount, inputGainNode, panGainNode, channelMergerNode);\n Object.defineProperty(panGainNode.gain, \'defaultValue\', { get: () => 0 });\n Object.defineProperty(panGainNode.gain, \'maxValue\', { get: () => 1 });\n Object.defineProperty(panGainNode.gain, \'minValue\', { get: () => -1 });\n const nativeStereoPannerNodeFakerFactory = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return inputGainNode.channelCount;\n },\n set channelCount(value) {\n if (inputGainNode.channelCount !== value) {\n if (isConnected) {\n disconnectGraph();\n }\n ({ connectGraph, disconnectGraph } = buildInternalGraph(nativeContext, value, inputGainNode, panGainNode, channelMergerNode));\n if (isConnected) {\n connectGraph();\n }\n }\n inputGainNode.channelCount = value;\n },\n get channelCountMode() {\n return inputGainNode.channelCountMode;\n },\n set channelCountMode(value) {\n if (value === \'clamped-max\' || value === \'max\') {\n throw createNotSupportedError();\n }\n inputGainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return inputGainNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n },\n get context() {\n return inputGainNode.context;\n },\n get inputs() {\n return [inputGainNode];\n },\n get numberOfInputs() {\n return inputGainNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return inputGainNode.numberOfOutputs;\n },\n get pan() {\n return panGainNode.gain;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n let isConnected = false;\n const whenConnected = () => {\n connectGraph();\n isConnected = true;\n };\n const whenDisconnected = () => {\n disconnectGraph();\n isConnected = false;\n };\n return monitorConnections(interceptConnections(nativeStereoPannerNodeFakerFactory, channelMergerNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-stereo-panner-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-wave-shaper-node-factory.js\n\n\nconst createNativeWaveShaperNodeFactory = (createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeWaveShaperNodeFaker, isDCCurve, monitorConnections, nativeAudioContextConstructor, overwriteAccessors) => {\n return (nativeContext, options) => {\n const nativeWaveShaperNode = nativeContext.createWaveShaper();\n /*\n * Bug #119: Safari does not correctly map the values.\n * @todo Unfortunately there is no way to test for this behavior in a synchronous fashion which is why testing for the existence of\n * the webkitAudioContext is used as a workaround here. Testing for the automationRate property is necessary because this workaround\n * isn\'t necessary anymore since v14.0.2 of Safari.\n */\n if (nativeAudioContextConstructor !== null &&\n nativeAudioContextConstructor.name === \'webkitAudioContext\' &&\n nativeContext.createGain().gain.automationRate === undefined) {\n return createNativeWaveShaperNodeFaker(nativeContext, options);\n }\n assignNativeAudioNodeOptions(nativeWaveShaperNode, options);\n const curve = options.curve === null || options.curve instanceof Float32Array ? options.curve : new Float32Array(options.curve);\n // Bug #104: Chrome and Edge will throw an InvalidAccessError when the curve has less than two samples.\n if (curve !== null && curve.length < 2) {\n throw createInvalidStateError();\n }\n // Only values of type Float32Array can be assigned to the curve property.\n assignNativeAudioNodeOption(nativeWaveShaperNode, { curve }, \'curve\');\n assignNativeAudioNodeOption(nativeWaveShaperNode, options, \'oversample\');\n let disconnectNativeAudioBufferSourceNode = null;\n let isConnected = false;\n overwriteAccessors(nativeWaveShaperNode, \'curve\', (get) => () => get.call(nativeWaveShaperNode), (set) => (value) => {\n set.call(nativeWaveShaperNode, value);\n if (isConnected) {\n if (isDCCurve(value) && disconnectNativeAudioBufferSourceNode === null) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, nativeWaveShaperNode);\n }\n else if (!isDCCurve(value) && disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n }\n return value;\n });\n const whenConnected = () => {\n isConnected = true;\n if (isDCCurve(nativeWaveShaperNode.curve)) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, nativeWaveShaperNode);\n }\n };\n const whenDisconnected = () => {\n isConnected = false;\n if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n };\n return monitorConnections(nativeWaveShaperNode, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-wave-shaper-node-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/native-wave-shaper-node-faker-factory.js\n\n\nconst createNativeWaveShaperNodeFakerFactory = (createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeGainNode, isDCCurve, monitorConnections) => {\n return (nativeContext, { curve, oversample, ...audioNodeOptions }) => {\n const negativeWaveShaperNode = nativeContext.createWaveShaper();\n const positiveWaveShaperNode = nativeContext.createWaveShaper();\n assignNativeAudioNodeOptions(negativeWaveShaperNode, audioNodeOptions);\n assignNativeAudioNodeOptions(positiveWaveShaperNode, audioNodeOptions);\n const inputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const invertGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: -1 });\n const outputGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: 1 });\n const revertGainNode = createNativeGainNode(nativeContext, { ...audioNodeOptions, gain: -1 });\n let disconnectNativeAudioBufferSourceNode = null;\n let isConnected = false;\n let unmodifiedCurve = null;\n const nativeWaveShaperNodeFaker = {\n get bufferSize() {\n return undefined;\n },\n get channelCount() {\n return negativeWaveShaperNode.channelCount;\n },\n set channelCount(value) {\n inputGainNode.channelCount = value;\n invertGainNode.channelCount = value;\n negativeWaveShaperNode.channelCount = value;\n outputGainNode.channelCount = value;\n positiveWaveShaperNode.channelCount = value;\n revertGainNode.channelCount = value;\n },\n get channelCountMode() {\n return negativeWaveShaperNode.channelCountMode;\n },\n set channelCountMode(value) {\n inputGainNode.channelCountMode = value;\n invertGainNode.channelCountMode = value;\n negativeWaveShaperNode.channelCountMode = value;\n outputGainNode.channelCountMode = value;\n positiveWaveShaperNode.channelCountMode = value;\n revertGainNode.channelCountMode = value;\n },\n get channelInterpretation() {\n return negativeWaveShaperNode.channelInterpretation;\n },\n set channelInterpretation(value) {\n inputGainNode.channelInterpretation = value;\n invertGainNode.channelInterpretation = value;\n negativeWaveShaperNode.channelInterpretation = value;\n outputGainNode.channelInterpretation = value;\n positiveWaveShaperNode.channelInterpretation = value;\n revertGainNode.channelInterpretation = value;\n },\n get context() {\n return negativeWaveShaperNode.context;\n },\n get curve() {\n return unmodifiedCurve;\n },\n set curve(value) {\n // Bug #102: Safari does not throw an InvalidStateError when the curve has less than two samples.\n if (value !== null && value.length < 2) {\n throw createInvalidStateError();\n }\n if (value === null) {\n negativeWaveShaperNode.curve = value;\n positiveWaveShaperNode.curve = value;\n }\n else {\n const curveLength = value.length;\n const negativeCurve = new Float32Array(curveLength + 2 - (curveLength % 2));\n const positiveCurve = new Float32Array(curveLength + 2 - (curveLength % 2));\n negativeCurve[0] = value[0];\n positiveCurve[0] = -value[curveLength - 1];\n const length = Math.ceil((curveLength + 1) / 2);\n const centerIndex = (curveLength + 1) / 2 - 1;\n for (let i = 1; i < length; i += 1) {\n const theoreticIndex = (i / length) * centerIndex;\n const lowerIndex = Math.floor(theoreticIndex);\n const upperIndex = Math.ceil(theoreticIndex);\n negativeCurve[i] =\n lowerIndex === upperIndex\n ? value[lowerIndex]\n : (1 - (theoreticIndex - lowerIndex)) * value[lowerIndex] +\n (1 - (upperIndex - theoreticIndex)) * value[upperIndex];\n positiveCurve[i] =\n lowerIndex === upperIndex\n ? -value[curveLength - 1 - lowerIndex]\n : -((1 - (theoreticIndex - lowerIndex)) * value[curveLength - 1 - lowerIndex]) -\n (1 - (upperIndex - theoreticIndex)) * value[curveLength - 1 - upperIndex];\n }\n negativeCurve[length] = curveLength % 2 === 1 ? value[length - 1] : (value[length - 2] + value[length - 1]) / 2;\n negativeWaveShaperNode.curve = negativeCurve;\n positiveWaveShaperNode.curve = positiveCurve;\n }\n unmodifiedCurve = value;\n if (isConnected) {\n if (isDCCurve(unmodifiedCurve) && disconnectNativeAudioBufferSourceNode === null) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, inputGainNode);\n }\n else if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n }\n },\n get inputs() {\n return [inputGainNode];\n },\n get numberOfInputs() {\n return negativeWaveShaperNode.numberOfInputs;\n },\n get numberOfOutputs() {\n return negativeWaveShaperNode.numberOfOutputs;\n },\n get oversample() {\n return negativeWaveShaperNode.oversample;\n },\n set oversample(value) {\n negativeWaveShaperNode.oversample = value;\n positiveWaveShaperNode.oversample = value;\n },\n addEventListener(...args) {\n return inputGainNode.addEventListener(args[0], args[1], args[2]);\n },\n dispatchEvent(...args) {\n return inputGainNode.dispatchEvent(args[0]);\n },\n removeEventListener(...args) {\n return inputGainNode.removeEventListener(args[0], args[1], args[2]);\n }\n };\n if (curve !== null) {\n // Only values of type Float32Array can be assigned to the curve property.\n nativeWaveShaperNodeFaker.curve = curve instanceof Float32Array ? curve : new Float32Array(curve);\n }\n if (oversample !== nativeWaveShaperNodeFaker.oversample) {\n nativeWaveShaperNodeFaker.oversample = oversample;\n }\n const whenConnected = () => {\n inputGainNode.connect(negativeWaveShaperNode).connect(outputGainNode);\n inputGainNode.connect(invertGainNode).connect(positiveWaveShaperNode).connect(revertGainNode).connect(outputGainNode);\n isConnected = true;\n if (isDCCurve(unmodifiedCurve)) {\n disconnectNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNode(nativeContext, inputGainNode);\n }\n };\n const whenDisconnected = () => {\n inputGainNode.disconnect(negativeWaveShaperNode);\n negativeWaveShaperNode.disconnect(outputGainNode);\n inputGainNode.disconnect(invertGainNode);\n invertGainNode.disconnect(positiveWaveShaperNode);\n positiveWaveShaperNode.disconnect(revertGainNode);\n revertGainNode.disconnect(outputGainNode);\n isConnected = false;\n if (disconnectNativeAudioBufferSourceNode !== null) {\n disconnectNativeAudioBufferSourceNode();\n disconnectNativeAudioBufferSourceNode = null;\n }\n };\n return monitorConnections(interceptConnections(nativeWaveShaperNodeFaker, outputGainNode), whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=native-wave-shaper-node-faker-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/not-supported-error.js\nconst createNotSupportedError = () => new DOMException(\'\', \'NotSupportedError\');\n//# sourceMappingURL=not-supported-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/offline-audio-context-constructor.js\n\n\nconst offline_audio_context_constructor_DEFAULT_OPTIONS = {\n numberOfChannels: 1\n};\nconst createOfflineAudioContextConstructor = (baseAudioContextConstructor, cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, startRendering) => {\n return class OfflineAudioContext extends baseAudioContextConstructor {\n constructor(a, b, c) {\n let options;\n if (typeof a === \'number\' && b !== undefined && c !== undefined) {\n options = { length: b, numberOfChannels: a, sampleRate: c };\n }\n else if (typeof a === \'object\') {\n options = a;\n }\n else {\n throw new Error(\'The given parameters are not valid.\');\n }\n const { length, numberOfChannels, sampleRate } = { ...offline_audio_context_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOfflineAudioContext = createNativeOfflineAudioContext(numberOfChannels, length, sampleRate);\n // #21 Safari does not support promises and therefore would fire the statechange event before the promise can be resolved.\n if (!cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n nativeOfflineAudioContext.addEventListener(\'statechange\', (() => {\n let i = 0;\n const delayStateChangeEvent = (event) => {\n if (this._state === \'running\') {\n if (i > 0) {\n nativeOfflineAudioContext.removeEventListener(\'statechange\', delayStateChangeEvent);\n event.stopImmediatePropagation();\n this._waitForThePromiseToSettle(event);\n }\n else {\n i += 1;\n }\n }\n };\n return delayStateChangeEvent;\n })());\n }\n super(nativeOfflineAudioContext, numberOfChannels);\n this._length = length;\n this._nativeOfflineAudioContext = nativeOfflineAudioContext;\n this._state = null;\n }\n get length() {\n // Bug #17: Safari does not yet expose the length.\n if (this._nativeOfflineAudioContext.length === undefined) {\n return this._length;\n }\n return this._nativeOfflineAudioContext.length;\n }\n get state() {\n return this._state === null ? this._nativeOfflineAudioContext.state : this._state;\n }\n startRendering() {\n /*\n * Bug #9 & #59: It is theoretically possible that startRendering() will first render a partialOfflineAudioContext. Therefore\n * the state of the nativeOfflineAudioContext might no transition to running immediately.\n */\n if (this._state === \'running\') {\n return Promise.reject(createInvalidStateError());\n }\n this._state = \'running\';\n return startRendering(this.destination, this._nativeOfflineAudioContext).finally(() => {\n this._state = null;\n deactivateAudioGraph(this);\n });\n }\n _waitForThePromiseToSettle(event) {\n if (this._state === null) {\n this._nativeOfflineAudioContext.dispatchEvent(event);\n }\n else {\n setTimeout(() => this._waitForThePromiseToSettle(event));\n }\n }\n };\n};\n//# sourceMappingURL=offline-audio-context-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/oscillator-node-constructor.js\n\n\n\nconst oscillator_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n detune: 0,\n frequency: 440,\n periodicWave: undefined,\n type: \'sine\'\n};\nconst createOscillatorNodeConstructor = (audioNodeConstructor, createAudioParam, createNativeOscillatorNode, createOscillatorNodeRenderer, getNativeContext, isNativeOfflineAudioContext, wrapEventListener) => {\n return class OscillatorNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...oscillator_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeOscillatorNode = createNativeOscillatorNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const oscillatorNodeRenderer = (isOffline ? createOscillatorNodeRenderer() : null);\n const nyquist = context.sampleRate / 2;\n super(context, false, nativeOscillatorNode, oscillatorNodeRenderer);\n // Bug #81: Firefox & Safari do not export the correct values for maxValue and minValue.\n this._detune = createAudioParam(this, isOffline, nativeOscillatorNode.detune, 153600, -153600);\n // Bug #76: Safari does not export the correct values for maxValue and minValue.\n this._frequency = createAudioParam(this, isOffline, nativeOscillatorNode.frequency, nyquist, -nyquist);\n this._nativeOscillatorNode = nativeOscillatorNode;\n this._onended = null;\n this._oscillatorNodeRenderer = oscillatorNodeRenderer;\n if (this._oscillatorNodeRenderer !== null && mergedOptions.periodicWave !== undefined) {\n this._oscillatorNodeRenderer.periodicWave =\n mergedOptions.periodicWave;\n }\n }\n get detune() {\n return this._detune;\n }\n get frequency() {\n return this._frequency;\n }\n get onended() {\n return this._onended;\n }\n set onended(value) {\n const wrappedListener = typeof value === \'function\' ? wrapEventListener(this, value) : null;\n this._nativeOscillatorNode.onended = wrappedListener;\n const nativeOnEnded = this._nativeOscillatorNode.onended;\n this._onended = nativeOnEnded !== null && nativeOnEnded === wrappedListener ? value : nativeOnEnded;\n }\n get type() {\n return this._nativeOscillatorNode.type;\n }\n set type(value) {\n this._nativeOscillatorNode.type = value;\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.periodicWave = null;\n }\n }\n setPeriodicWave(periodicWave) {\n this._nativeOscillatorNode.setPeriodicWave(periodicWave);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.periodicWave = periodicWave;\n }\n }\n start(when = 0) {\n this._nativeOscillatorNode.start(when);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.start = when;\n }\n if (this.context.state !== \'closed\') {\n setInternalStateToActive(this);\n const resetInternalStateToPassive = () => {\n this._nativeOscillatorNode.removeEventListener(\'ended\', resetInternalStateToPassive);\n if (isActiveAudioNode(this)) {\n setInternalStateToPassive(this);\n }\n };\n this._nativeOscillatorNode.addEventListener(\'ended\', resetInternalStateToPassive);\n }\n }\n stop(when = 0) {\n this._nativeOscillatorNode.stop(when);\n if (this._oscillatorNodeRenderer !== null) {\n this._oscillatorNodeRenderer.stop = when;\n }\n }\n };\n};\n//# sourceMappingURL=oscillator-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/oscillator-node-renderer-factory.js\n\nconst createOscillatorNodeRendererFactory = (connectAudioParam, createNativeOscillatorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeOscillatorNodes = new WeakMap();\n let periodicWave = null;\n let start = null;\n let stop = null;\n const createOscillatorNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeOscillatorNode = getNativeAudioNode(proxy);\n // If the initially used nativeOscillatorNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeOscillatorNodeIsOwnedByContext = isOwnedByContext(nativeOscillatorNode, nativeOfflineAudioContext);\n if (!nativeOscillatorNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeOscillatorNode.channelCount,\n channelCountMode: nativeOscillatorNode.channelCountMode,\n channelInterpretation: nativeOscillatorNode.channelInterpretation,\n detune: nativeOscillatorNode.detune.value,\n frequency: nativeOscillatorNode.frequency.value,\n periodicWave: periodicWave === null ? undefined : periodicWave,\n type: nativeOscillatorNode.type\n };\n nativeOscillatorNode = createNativeOscillatorNode(nativeOfflineAudioContext, options);\n if (start !== null) {\n nativeOscillatorNode.start(start);\n }\n if (stop !== null) {\n nativeOscillatorNode.stop(stop);\n }\n }\n renderedNativeOscillatorNodes.set(nativeOfflineAudioContext, nativeOscillatorNode);\n if (!nativeOscillatorNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.detune, nativeOscillatorNode.detune);\n await renderAutomation(nativeOfflineAudioContext, proxy.frequency, nativeOscillatorNode.frequency);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.detune, nativeOscillatorNode.detune);\n await connectAudioParam(nativeOfflineAudioContext, proxy.frequency, nativeOscillatorNode.frequency);\n }\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeOscillatorNode);\n return nativeOscillatorNode;\n };\n return {\n set periodicWave(value) {\n periodicWave = value;\n },\n set start(value) {\n start = value;\n },\n set stop(value) {\n stop = value;\n },\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeOscillatorNode = renderedNativeOscillatorNodes.get(nativeOfflineAudioContext);\n if (renderedNativeOscillatorNode !== undefined) {\n return Promise.resolve(renderedNativeOscillatorNode);\n }\n return createOscillatorNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=oscillator-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/panner-node-constructor.js\n\nconst panner_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'clamped-max\',\n channelInterpretation: \'speakers\',\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: \'inverse\',\n maxDistance: 10000,\n orientationX: 1,\n orientationY: 0,\n orientationZ: 0,\n panningModel: \'equalpower\',\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n refDistance: 1,\n rolloffFactor: 1\n};\nconst createPannerNodeConstructor = (audioNodeConstructor, createAudioParam, createNativePannerNode, createPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class PannerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...panner_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativePannerNode = createNativePannerNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const pannerNodeRenderer = (isOffline ? createPannerNodeRenderer() : null);\n super(context, false, nativePannerNode, pannerNodeRenderer);\n this._nativePannerNode = nativePannerNode;\n // Bug #74: Safari does not export the correct values for maxValue and minValue.\n this._orientationX = createAudioParam(this, isOffline, nativePannerNode.orientationX, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._orientationY = createAudioParam(this, isOffline, nativePannerNode.orientationY, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._orientationZ = createAudioParam(this, isOffline, nativePannerNode.orientationZ, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionX = createAudioParam(this, isOffline, nativePannerNode.positionX, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionY = createAudioParam(this, isOffline, nativePannerNode.positionY, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n this._positionZ = createAudioParam(this, isOffline, nativePannerNode.positionZ, MOST_POSITIVE_SINGLE_FLOAT, MOST_NEGATIVE_SINGLE_FLOAT);\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get coneInnerAngle() {\n return this._nativePannerNode.coneInnerAngle;\n }\n set coneInnerAngle(value) {\n this._nativePannerNode.coneInnerAngle = value;\n }\n get coneOuterAngle() {\n return this._nativePannerNode.coneOuterAngle;\n }\n set coneOuterAngle(value) {\n this._nativePannerNode.coneOuterAngle = value;\n }\n get coneOuterGain() {\n return this._nativePannerNode.coneOuterGain;\n }\n set coneOuterGain(value) {\n this._nativePannerNode.coneOuterGain = value;\n }\n get distanceModel() {\n return this._nativePannerNode.distanceModel;\n }\n set distanceModel(value) {\n this._nativePannerNode.distanceModel = value;\n }\n get maxDistance() {\n return this._nativePannerNode.maxDistance;\n }\n set maxDistance(value) {\n this._nativePannerNode.maxDistance = value;\n }\n get orientationX() {\n return this._orientationX;\n }\n get orientationY() {\n return this._orientationY;\n }\n get orientationZ() {\n return this._orientationZ;\n }\n get panningModel() {\n return this._nativePannerNode.panningModel;\n }\n set panningModel(value) {\n this._nativePannerNode.panningModel = value;\n }\n get positionX() {\n return this._positionX;\n }\n get positionY() {\n return this._positionY;\n }\n get positionZ() {\n return this._positionZ;\n }\n get refDistance() {\n return this._nativePannerNode.refDistance;\n }\n set refDistance(value) {\n this._nativePannerNode.refDistance = value;\n }\n get rolloffFactor() {\n return this._nativePannerNode.rolloffFactor;\n }\n set rolloffFactor(value) {\n this._nativePannerNode.rolloffFactor = value;\n }\n };\n};\n//# sourceMappingURL=panner-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/panner-node-renderer-factory.js\n\n\nconst createPannerNodeRendererFactory = (connectAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeGainNode, createNativePannerNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext) => {\n return () => {\n const renderedNativeAudioNodes = new WeakMap();\n let renderedBufferPromise = null;\n const createAudioNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeGainNode = null;\n let nativePannerNode = getNativeAudioNode(proxy);\n const commonAudioNodeOptions = {\n channelCount: nativePannerNode.channelCount,\n channelCountMode: nativePannerNode.channelCountMode,\n channelInterpretation: nativePannerNode.channelInterpretation\n };\n const commonNativePannerNodeOptions = {\n ...commonAudioNodeOptions,\n coneInnerAngle: nativePannerNode.coneInnerAngle,\n coneOuterAngle: nativePannerNode.coneOuterAngle,\n coneOuterGain: nativePannerNode.coneOuterGain,\n distanceModel: nativePannerNode.distanceModel,\n maxDistance: nativePannerNode.maxDistance,\n panningModel: nativePannerNode.panningModel,\n refDistance: nativePannerNode.refDistance,\n rolloffFactor: nativePannerNode.rolloffFactor\n };\n // If the initially used nativePannerNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativePannerNodeIsOwnedByContext = isOwnedByContext(nativePannerNode, nativeOfflineAudioContext);\n // Bug #124: Safari does not support modifying the orientation and the position with AudioParams.\n if (\'bufferSize\' in nativePannerNode) {\n nativeGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n }\n else if (!nativePannerNodeIsOwnedByContext) {\n const options = {\n ...commonNativePannerNodeOptions,\n orientationX: nativePannerNode.orientationX.value,\n orientationY: nativePannerNode.orientationY.value,\n orientationZ: nativePannerNode.orientationZ.value,\n positionX: nativePannerNode.positionX.value,\n positionY: nativePannerNode.positionY.value,\n positionZ: nativePannerNode.positionZ.value\n };\n nativePannerNode = createNativePannerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeAudioNodes.set(nativeOfflineAudioContext, nativeGainNode === null ? nativePannerNode : nativeGainNode);\n if (nativeGainNode !== null) {\n if (renderedBufferPromise === null) {\n if (nativeOfflineAudioContextConstructor === null) {\n throw new Error(\'Missing the native OfflineAudioContext constructor.\');\n }\n const partialOfflineAudioContext = new nativeOfflineAudioContextConstructor(6, \n // Bug #17: Safari does not yet expose the length.\n proxy.context.length, nativeOfflineAudioContext.sampleRate);\n const nativeChannelMergerNode = createNativeChannelMergerNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n numberOfInputs: 6\n });\n nativeChannelMergerNode.connect(partialOfflineAudioContext.destination);\n renderedBufferPromise = (async () => {\n const nativeConstantSourceNodes = await Promise.all([\n proxy.orientationX,\n proxy.orientationY,\n proxy.orientationZ,\n proxy.positionX,\n proxy.positionY,\n proxy.positionZ\n ].map(async (audioParam, index) => {\n const nativeConstantSourceNode = createNativeConstantSourceNode(partialOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n offset: index === 0 ? 1 : 0\n });\n await renderAutomation(partialOfflineAudioContext, audioParam, nativeConstantSourceNode.offset);\n return nativeConstantSourceNode;\n }));\n for (let i = 0; i < 6; i += 1) {\n nativeConstantSourceNodes[i].connect(nativeChannelMergerNode, 0, i);\n nativeConstantSourceNodes[i].start(0);\n }\n return renderNativeOfflineAudioContext(partialOfflineAudioContext);\n })();\n }\n const renderedBuffer = await renderedBufferPromise;\n const inputGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, inputGainNode);\n const channelDatas = [];\n for (let i = 0; i < renderedBuffer.numberOfChannels; i += 1) {\n channelDatas.push(renderedBuffer.getChannelData(i));\n }\n let lastOrientation = [channelDatas[0][0], channelDatas[1][0], channelDatas[2][0]];\n let lastPosition = [channelDatas[3][0], channelDatas[4][0], channelDatas[5][0]];\n let gateGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 1 });\n let partialPannerNode = createNativePannerNode(nativeOfflineAudioContext, {\n ...commonNativePannerNodeOptions,\n orientationX: lastOrientation[0],\n orientationY: lastOrientation[1],\n orientationZ: lastOrientation[2],\n positionX: lastPosition[0],\n positionY: lastPosition[1],\n positionZ: lastPosition[2]\n });\n inputGainNode.connect(gateGainNode).connect(partialPannerNode.inputs[0]);\n partialPannerNode.connect(nativeGainNode);\n for (let i = 128; i < renderedBuffer.length; i += 128) {\n const orientation = [channelDatas[0][i], channelDatas[1][i], channelDatas[2][i]];\n const positon = [channelDatas[3][i], channelDatas[4][i], channelDatas[5][i]];\n if (orientation.some((value, index) => value !== lastOrientation[index]) ||\n positon.some((value, index) => value !== lastPosition[index])) {\n lastOrientation = orientation;\n lastPosition = positon;\n const currentTime = i / nativeOfflineAudioContext.sampleRate;\n gateGainNode.gain.setValueAtTime(0, currentTime);\n gateGainNode = createNativeGainNode(nativeOfflineAudioContext, { ...commonAudioNodeOptions, gain: 0 });\n partialPannerNode = createNativePannerNode(nativeOfflineAudioContext, {\n ...commonNativePannerNodeOptions,\n orientationX: lastOrientation[0],\n orientationY: lastOrientation[1],\n orientationZ: lastOrientation[2],\n positionX: lastPosition[0],\n positionY: lastPosition[1],\n positionZ: lastPosition[2]\n });\n gateGainNode.gain.setValueAtTime(1, currentTime);\n inputGainNode.connect(gateGainNode).connect(partialPannerNode.inputs[0]);\n partialPannerNode.connect(nativeGainNode);\n }\n }\n return nativeGainNode;\n }\n if (!nativePannerNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationX, nativePannerNode.orientationX);\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationY, nativePannerNode.orientationY);\n await renderAutomation(nativeOfflineAudioContext, proxy.orientationZ, nativePannerNode.orientationZ);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionX, nativePannerNode.positionX);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionY, nativePannerNode.positionY);\n await renderAutomation(nativeOfflineAudioContext, proxy.positionZ, nativePannerNode.positionZ);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationX, nativePannerNode.orientationX);\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationY, nativePannerNode.orientationY);\n await connectAudioParam(nativeOfflineAudioContext, proxy.orientationZ, nativePannerNode.orientationZ);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionX, nativePannerNode.positionX);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionY, nativePannerNode.positionY);\n await connectAudioParam(nativeOfflineAudioContext, proxy.positionZ, nativePannerNode.positionZ);\n }\n if (isNativeAudioNodeFaker(nativePannerNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativePannerNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativePannerNode);\n }\n return nativePannerNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeGainNodeOrNativePannerNode = renderedNativeAudioNodes.get(nativeOfflineAudioContext);\n if (renderedNativeGainNodeOrNativePannerNode !== undefined) {\n return Promise.resolve(renderedNativeGainNodeOrNativePannerNode);\n }\n return createAudioNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=panner-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/periodic-wave-constructor.js\nconst periodic_wave_constructor_DEFAULT_OPTIONS = {\n disableNormalization: false\n};\nconst createPeriodicWaveConstructor = (createNativePeriodicWave, getNativeContext, periodicWaveStore, sanitizePeriodicWaveOptions) => {\n return class PeriodicWave {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = sanitizePeriodicWaveOptions({ ...periodic_wave_constructor_DEFAULT_OPTIONS, ...options });\n const periodicWave = createNativePeriodicWave(nativeContext, mergedOptions);\n periodicWaveStore.add(periodicWave);\n // This does violate all good pratices but it is used here to simplify the handling of periodic waves.\n return periodicWave;\n }\n static [Symbol.hasInstance](instance) {\n return ((instance !== null && typeof instance === \'object\' && Object.getPrototypeOf(instance) === PeriodicWave.prototype) ||\n periodicWaveStore.has(instance));\n }\n };\n};\n//# sourceMappingURL=periodic-wave-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-automation.js\nconst createRenderAutomation = (getAudioParamRenderer, renderInputsOfAudioParam) => {\n return (nativeOfflineAudioContext, audioParam, nativeAudioParam) => {\n const audioParamRenderer = getAudioParamRenderer(audioParam);\n audioParamRenderer.replay(nativeAudioParam);\n return renderInputsOfAudioParam(audioParam, nativeOfflineAudioContext, nativeAudioParam);\n };\n};\n//# sourceMappingURL=render-automation.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-inputs-of-audio-node.js\nconst createRenderInputsOfAudioNode = (getAudioNodeConnections, getAudioNodeRenderer, isPartOfACycle) => {\n return async (audioNode, nativeOfflineAudioContext, nativeAudioNode) => {\n const audioNodeConnections = getAudioNodeConnections(audioNode);\n await Promise.all(audioNodeConnections.activeInputs\n .map((connections, input) => Array.from(connections).map(async ([source, output]) => {\n const audioNodeRenderer = getAudioNodeRenderer(source);\n const renderedNativeAudioNode = await audioNodeRenderer.render(source, nativeOfflineAudioContext);\n const destination = audioNode.context.destination;\n if (!isPartOfACycle(source) && (audioNode !== destination || !isPartOfACycle(audioNode))) {\n renderedNativeAudioNode.connect(nativeAudioNode, output, input);\n }\n }))\n .reduce((allRenderingPromises, renderingPromises) => [...allRenderingPromises, ...renderingPromises], []));\n };\n};\n//# sourceMappingURL=render-inputs-of-audio-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-inputs-of-audio-param.js\nconst createRenderInputsOfAudioParam = (getAudioNodeRenderer, getAudioParamConnections, isPartOfACycle) => {\n return async (audioParam, nativeOfflineAudioContext, nativeAudioParam) => {\n const audioParamConnections = getAudioParamConnections(audioParam);\n await Promise.all(Array.from(audioParamConnections.activeInputs).map(async ([source, output]) => {\n const audioNodeRenderer = getAudioNodeRenderer(source);\n const renderedNativeAudioNode = await audioNodeRenderer.render(source, nativeOfflineAudioContext);\n if (!isPartOfACycle(source)) {\n renderedNativeAudioNode.connect(nativeAudioParam, output);\n }\n }));\n };\n};\n//# sourceMappingURL=render-inputs-of-audio-param.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/render-native-offline-audio-context.js\n\nconst createRenderNativeOfflineAudioContext = (cacheTestResult, createNativeGainNode, createNativeScriptProcessorNode, testOfflineAudioContextCurrentTimeSupport) => {\n return (nativeOfflineAudioContext) => {\n // Bug #21: Safari does not support promises yet.\n if (cacheTestResult(testPromiseSupport, () => testPromiseSupport(nativeOfflineAudioContext))) {\n // Bug #158: Chrome and Edge do not advance currentTime if it is not accessed while rendering the audio.\n return Promise.resolve(cacheTestResult(testOfflineAudioContextCurrentTimeSupport, testOfflineAudioContextCurrentTimeSupport)).then((isOfflineAudioContextCurrentTimeSupported) => {\n if (!isOfflineAudioContextCurrentTimeSupported) {\n const scriptProcessorNode = createNativeScriptProcessorNode(nativeOfflineAudioContext, 512, 0, 1);\n nativeOfflineAudioContext.oncomplete = () => {\n scriptProcessorNode.onaudioprocess = null; // tslint:disable-line:deprecation\n scriptProcessorNode.disconnect();\n };\n scriptProcessorNode.onaudioprocess = () => nativeOfflineAudioContext.currentTime; // tslint:disable-line:deprecation\n scriptProcessorNode.connect(nativeOfflineAudioContext.destination);\n }\n return nativeOfflineAudioContext.startRendering();\n });\n }\n return new Promise((resolve) => {\n // Bug #48: Safari does not render an OfflineAudioContext without any connected node.\n const gainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n nativeOfflineAudioContext.oncomplete = (event) => {\n gainNode.disconnect();\n resolve(event.renderedBuffer);\n };\n gainNode.connect(nativeOfflineAudioContext.destination);\n nativeOfflineAudioContext.startRendering();\n });\n };\n};\n//# sourceMappingURL=render-native-offline-audio-context.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/set-active-audio-worklet-node-inputs.js\nconst createSetActiveAudioWorkletNodeInputs = (activeAudioWorkletNodeInputsStore) => {\n return (nativeAudioWorkletNode, activeInputs) => {\n activeAudioWorkletNodeInputsStore.set(nativeAudioWorkletNode, activeInputs);\n };\n};\n//# sourceMappingURL=set-active-audio-worklet-node-inputs.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/set-audio-node-tail-time.js\nconst createSetAudioNodeTailTime = (audioNodeTailTimeStore) => {\n return (audioNode, tailTime) => audioNodeTailTimeStore.set(audioNode, tailTime);\n};\n//# sourceMappingURL=set-audio-node-tail-time.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/start-rendering.js\n\nconst createStartRendering = (audioBufferStore, cacheTestResult, getAudioNodeRenderer, getUnrenderedAudioWorkletNodes, renderNativeOfflineAudioContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds) => {\n return (destination, nativeOfflineAudioContext) => getAudioNodeRenderer(destination)\n .render(destination, nativeOfflineAudioContext)\n /*\n * Bug #86 & #87: Invoking the renderer of an AudioWorkletNode might be necessary if it has no direct or indirect connection to the\n * destination.\n */\n .then(() => Promise.all(Array.from(getUnrenderedAudioWorkletNodes(nativeOfflineAudioContext)).map((audioWorkletNode) => getAudioNodeRenderer(audioWorkletNode).render(audioWorkletNode, nativeOfflineAudioContext))))\n .then(() => renderNativeOfflineAudioContext(nativeOfflineAudioContext))\n .then((audioBuffer) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n // Bug #100: Safari does throw a wrong error when calling getChannelData() with an out-of-bounds value.\n if (typeof audioBuffer.copyFromChannel !== \'function\') {\n wrapAudioBufferCopyChannelMethods(audioBuffer);\n wrapAudioBufferGetChannelDataMethod(audioBuffer);\n // Bug #157: Firefox does not allow the bufferOffset to be out-of-bounds.\n }\n else if (!cacheTestResult(testAudioBufferCopyChannelMethodsOutOfBoundsSupport, () => testAudioBufferCopyChannelMethodsOutOfBoundsSupport(audioBuffer))) {\n wrapAudioBufferCopyChannelMethodsOutOfBounds(audioBuffer);\n }\n audioBufferStore.add(audioBuffer);\n return audioBuffer;\n });\n};\n//# sourceMappingURL=start-rendering.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/stereo-panner-node-constructor.js\nconst stereo_panner_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n /*\n * Bug #105: The channelCountMode should be \'clamped-max\' according to the spec but is set to \'explicit\' to achieve consistent\n * behavior.\n */\n channelCountMode: \'explicit\',\n channelInterpretation: \'speakers\',\n pan: 0\n};\nconst createStereoPannerNodeConstructor = (audioNodeConstructor, createAudioParam, createNativeStereoPannerNode, createStereoPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext) => {\n return class StereoPannerNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...stereo_panner_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeStereoPannerNode = createNativeStereoPannerNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const stereoPannerNodeRenderer = (isOffline ? createStereoPannerNodeRenderer() : null);\n super(context, false, nativeStereoPannerNode, stereoPannerNodeRenderer);\n this._pan = createAudioParam(this, isOffline, nativeStereoPannerNode.pan);\n }\n get pan() {\n return this._pan;\n }\n };\n};\n//# sourceMappingURL=stereo-panner-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/stereo-panner-node-renderer-factory.js\n\n\nconst createStereoPannerNodeRendererFactory = (connectAudioParam, createNativeStereoPannerNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeStereoPannerNodes = new WeakMap();\n const createStereoPannerNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeStereoPannerNode = getNativeAudioNode(proxy);\n /*\n * If the initially used nativeStereoPannerNode was not constructed on the same OfflineAudioContext it needs to be created\n * again.\n */\n const nativeStereoPannerNodeIsOwnedByContext = isOwnedByContext(nativeStereoPannerNode, nativeOfflineAudioContext);\n if (!nativeStereoPannerNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeStereoPannerNode.channelCount,\n channelCountMode: nativeStereoPannerNode.channelCountMode,\n channelInterpretation: nativeStereoPannerNode.channelInterpretation,\n pan: nativeStereoPannerNode.pan.value\n };\n nativeStereoPannerNode = createNativeStereoPannerNode(nativeOfflineAudioContext, options);\n }\n renderedNativeStereoPannerNodes.set(nativeOfflineAudioContext, nativeStereoPannerNode);\n if (!nativeStereoPannerNodeIsOwnedByContext) {\n await renderAutomation(nativeOfflineAudioContext, proxy.pan, nativeStereoPannerNode.pan);\n }\n else {\n await connectAudioParam(nativeOfflineAudioContext, proxy.pan, nativeStereoPannerNode.pan);\n }\n if (isNativeAudioNodeFaker(nativeStereoPannerNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeStereoPannerNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeStereoPannerNode);\n }\n return nativeStereoPannerNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeStereoPannerNode = renderedNativeStereoPannerNodes.get(nativeOfflineAudioContext);\n if (renderedNativeStereoPannerNode !== undefined) {\n return Promise.resolve(renderedNativeStereoPannerNode);\n }\n return createStereoPannerNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=stereo-panner-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-audio-buffer-constructor-support.js\n// Bug #33: Safari exposes an AudioBuffer but it can\'t be used as a constructor.\nconst createTestAudioBufferConstructorSupport = (nativeAudioBufferConstructor) => {\n return () => {\n if (nativeAudioBufferConstructor === null) {\n return false;\n }\n try {\n new nativeAudioBufferConstructor({ length: 1, sampleRate: 44100 }); // tslint:disable-line:no-unused-expression\n }\n catch {\n return false;\n }\n return true;\n };\n};\n//# sourceMappingURL=test-audio-buffer-constructor-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-audio-worklet-processor-post-message-support.js\n// Bug #179: Firefox does not allow to transfer any buffer which has been passed to the process() method as an argument.\nconst createTestAudioWorkletProcessorPostMessageSupport = (nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor) => {\n return async () => {\n // Bug #61: If there is no native AudioWorkletNode it gets faked and therefore it is no problem if the it doesn\'t exist.\n if (nativeAudioWorkletNodeConstructor === null) {\n return true;\n }\n if (nativeOfflineAudioContextConstructor === null) {\n return false;\n }\n const blob = new Blob([\'class A extends AudioWorkletProcessor{process(i){this.port.postMessage(i,[i[0][0].buffer])}}registerProcessor("a",A)\'], {\n type: \'application/javascript; charset=utf-8\'\n });\n // Bug #141: Safari does not support creating an OfflineAudioContext with less than 44100 Hz.\n const offlineAudioContext = new nativeOfflineAudioContextConstructor(1, 128, 44100);\n const url = URL.createObjectURL(blob);\n let isEmittingMessageEvents = false;\n let isEmittingProcessorErrorEvents = false;\n try {\n await offlineAudioContext.audioWorklet.addModule(url);\n const audioWorkletNode = new nativeAudioWorkletNodeConstructor(offlineAudioContext, \'a\', { numberOfOutputs: 0 });\n const oscillator = offlineAudioContext.createOscillator();\n audioWorkletNode.port.onmessage = () => (isEmittingMessageEvents = true);\n audioWorkletNode.onprocessorerror = () => (isEmittingProcessorErrorEvents = true);\n oscillator.connect(audioWorkletNode);\n oscillator.start(0);\n await offlineAudioContext.startRendering();\n }\n catch {\n // Ignore errors.\n }\n finally {\n URL.revokeObjectURL(url);\n }\n return isEmittingMessageEvents && !isEmittingProcessorErrorEvents;\n };\n};\n//# sourceMappingURL=test-audio-worklet-processor-post-message-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/test-offline-audio-context-current-time-support.js\nconst createTestOfflineAudioContextCurrentTimeSupport = (createNativeGainNode, nativeOfflineAudioContextConstructor) => {\n return () => {\n if (nativeOfflineAudioContextConstructor === null) {\n return Promise.resolve(false);\n }\n const nativeOfflineAudioContext = new nativeOfflineAudioContextConstructor(1, 1, 44100);\n // Bug #48: Safari does not render an OfflineAudioContext without any connected node.\n const gainNode = createNativeGainNode(nativeOfflineAudioContext, {\n channelCount: 1,\n channelCountMode: \'explicit\',\n channelInterpretation: \'discrete\',\n gain: 0\n });\n // Bug #21: Safari does not support promises yet.\n return new Promise((resolve) => {\n nativeOfflineAudioContext.oncomplete = () => {\n gainNode.disconnect();\n resolve(nativeOfflineAudioContext.currentTime !== 0);\n };\n nativeOfflineAudioContext.startRendering();\n });\n };\n};\n//# sourceMappingURL=test-offline-audio-context-current-time-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/unknown-error.js\nconst createUnknownError = () => new DOMException(\'\', \'UnknownError\');\n//# sourceMappingURL=unknown-error.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wave-shaper-node-constructor.js\nconst wave_shaper_node_constructor_DEFAULT_OPTIONS = {\n channelCount: 2,\n channelCountMode: \'max\',\n channelInterpretation: \'speakers\',\n curve: null,\n oversample: \'none\'\n};\nconst createWaveShaperNodeConstructor = (audioNodeConstructor, createInvalidStateError, createNativeWaveShaperNode, createWaveShaperNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime) => {\n return class WaveShaperNode extends audioNodeConstructor {\n constructor(context, options) {\n const nativeContext = getNativeContext(context);\n const mergedOptions = { ...wave_shaper_node_constructor_DEFAULT_OPTIONS, ...options };\n const nativeWaveShaperNode = createNativeWaveShaperNode(nativeContext, mergedOptions);\n const isOffline = isNativeOfflineAudioContext(nativeContext);\n const waveShaperNodeRenderer = (isOffline ? createWaveShaperNodeRenderer() : null);\n // @todo Add a mechanism to only switch a WaveShaperNode to active while it is connected.\n super(context, true, nativeWaveShaperNode, waveShaperNodeRenderer);\n this._isCurveNullified = false;\n this._nativeWaveShaperNode = nativeWaveShaperNode;\n // @todo Determine a meaningful tail-time instead of just using one second.\n setAudioNodeTailTime(this, 1);\n }\n get curve() {\n if (this._isCurveNullified) {\n return null;\n }\n return this._nativeWaveShaperNode.curve;\n }\n set curve(value) {\n // Bug #103: Safari does not allow to set the curve to null.\n if (value === null) {\n this._isCurveNullified = true;\n this._nativeWaveShaperNode.curve = new Float32Array([0, 0]);\n }\n else {\n // Bug #102: Safari does not throw an InvalidStateError when the curve has less than two samples.\n // Bug #104: Chrome and Edge will throw an InvalidAccessError when the curve has less than two samples.\n if (value.length < 2) {\n throw createInvalidStateError();\n }\n this._isCurveNullified = false;\n this._nativeWaveShaperNode.curve = value;\n }\n }\n get oversample() {\n return this._nativeWaveShaperNode.oversample;\n }\n set oversample(value) {\n this._nativeWaveShaperNode.oversample = value;\n }\n };\n};\n//# sourceMappingURL=wave-shaper-node-constructor.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wave-shaper-node-renderer-factory.js\n\n\nconst createWaveShaperNodeRendererFactory = (createNativeWaveShaperNode, getNativeAudioNode, renderInputsOfAudioNode) => {\n return () => {\n const renderedNativeWaveShaperNodes = new WeakMap();\n const createWaveShaperNode = async (proxy, nativeOfflineAudioContext) => {\n let nativeWaveShaperNode = getNativeAudioNode(proxy);\n // If the initially used nativeWaveShaperNode was not constructed on the same OfflineAudioContext it needs to be created again.\n const nativeWaveShaperNodeIsOwnedByContext = isOwnedByContext(nativeWaveShaperNode, nativeOfflineAudioContext);\n if (!nativeWaveShaperNodeIsOwnedByContext) {\n const options = {\n channelCount: nativeWaveShaperNode.channelCount,\n channelCountMode: nativeWaveShaperNode.channelCountMode,\n channelInterpretation: nativeWaveShaperNode.channelInterpretation,\n curve: nativeWaveShaperNode.curve,\n oversample: nativeWaveShaperNode.oversample\n };\n nativeWaveShaperNode = createNativeWaveShaperNode(nativeOfflineAudioContext, options);\n }\n renderedNativeWaveShaperNodes.set(nativeOfflineAudioContext, nativeWaveShaperNode);\n if (isNativeAudioNodeFaker(nativeWaveShaperNode)) {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeWaveShaperNode.inputs[0]);\n }\n else {\n await renderInputsOfAudioNode(proxy, nativeOfflineAudioContext, nativeWaveShaperNode);\n }\n return nativeWaveShaperNode;\n };\n return {\n render(proxy, nativeOfflineAudioContext) {\n const renderedNativeWaveShaperNode = renderedNativeWaveShaperNodes.get(nativeOfflineAudioContext);\n if (renderedNativeWaveShaperNode !== undefined) {\n return Promise.resolve(renderedNativeWaveShaperNode);\n }\n return createWaveShaperNode(proxy, nativeOfflineAudioContext);\n }\n };\n };\n};\n//# sourceMappingURL=wave-shaper-node-renderer-factory.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/window.js\nconst createWindow = () => (typeof window === \'undefined\' ? null : window);\n//# sourceMappingURL=window.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-copy-channel-methods.js\nconst createWrapAudioBufferCopyChannelMethods = (convertNumberToUnsignedLong, createIndexSizeError) => {\n return (audioBuffer) => {\n audioBuffer.copyFromChannel = (destination, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (channelNumber >= audioBuffer.numberOfChannels) {\n throw createIndexSizeError();\n }\n const audioBufferLength = audioBuffer.length;\n const channelData = audioBuffer.getChannelData(channelNumber);\n const destinationLength = destination.length;\n for (let i = bufferOffset < 0 ? -bufferOffset : 0; i + bufferOffset < audioBufferLength && i < destinationLength; i += 1) {\n destination[i] = channelData[i + bufferOffset];\n }\n };\n audioBuffer.copyToChannel = (source, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (channelNumber >= audioBuffer.numberOfChannels) {\n throw createIndexSizeError();\n }\n const audioBufferLength = audioBuffer.length;\n const channelData = audioBuffer.getChannelData(channelNumber);\n const sourceLength = source.length;\n for (let i = bufferOffset < 0 ? -bufferOffset : 0; i + bufferOffset < audioBufferLength && i < sourceLength; i += 1) {\n channelData[i + bufferOffset] = source[i];\n }\n };\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-copy-channel-methods.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-copy-channel-methods-out-of-bounds.js\nconst createWrapAudioBufferCopyChannelMethodsOutOfBounds = (convertNumberToUnsignedLong) => {\n return (audioBuffer) => {\n audioBuffer.copyFromChannel = ((copyFromChannel) => {\n return (destination, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (bufferOffset < audioBuffer.length) {\n return copyFromChannel.call(audioBuffer, destination, channelNumber, bufferOffset);\n }\n };\n })(audioBuffer.copyFromChannel);\n audioBuffer.copyToChannel = ((copyToChannel) => {\n return (source, channelNumberAsNumber, bufferOffsetAsNumber = 0) => {\n const bufferOffset = convertNumberToUnsignedLong(bufferOffsetAsNumber);\n const channelNumber = convertNumberToUnsignedLong(channelNumberAsNumber);\n if (bufferOffset < audioBuffer.length) {\n return copyToChannel.call(audioBuffer, source, channelNumber, bufferOffset);\n }\n };\n })(audioBuffer.copyToChannel);\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-copy-channel-methods-out-of-bounds.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-audio-buffer-source-node-stop-method-nullified-buffer.js\nconst createWrapAudioBufferSourceNodeStopMethodNullifiedBuffer = (overwriteAccessors) => {\n return (nativeAudioBufferSourceNode, nativeContext) => {\n const nullifiedBuffer = nativeContext.createBuffer(1, 1, 44100);\n if (nativeAudioBufferSourceNode.buffer === null) {\n nativeAudioBufferSourceNode.buffer = nullifiedBuffer;\n }\n overwriteAccessors(nativeAudioBufferSourceNode, \'buffer\', (get) => () => {\n const value = get.call(nativeAudioBufferSourceNode);\n return value === nullifiedBuffer ? null : value;\n }, (set) => (value) => {\n return set.call(nativeAudioBufferSourceNode, value === null ? nullifiedBuffer : value);\n });\n };\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-stop-method-nullified-buffer.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/factories/wrap-channel-merger-node.js\nconst createWrapChannelMergerNode = (createInvalidStateError, monitorConnections) => {\n return (nativeContext, channelMergerNode) => {\n // Bug #15: Safari does not return the default properties.\n channelMergerNode.channelCount = 1;\n channelMergerNode.channelCountMode = \'explicit\';\n // Bug #16: Safari does not throw an error when setting a different channelCount or channelCountMode.\n Object.defineProperty(channelMergerNode, \'channelCount\', {\n get: () => 1,\n set: () => {\n throw createInvalidStateError();\n }\n });\n Object.defineProperty(channelMergerNode, \'channelCountMode\', {\n get: () => \'explicit\',\n set: () => {\n throw createInvalidStateError();\n }\n });\n // Bug #20: Safari requires a connection of any kind to treat the input signal correctly.\n const audioBufferSourceNode = nativeContext.createBufferSource();\n const whenConnected = () => {\n const length = channelMergerNode.numberOfInputs;\n for (let i = 0; i < length; i += 1) {\n audioBufferSourceNode.connect(channelMergerNode, 0, i);\n }\n };\n const whenDisconnected = () => audioBufferSourceNode.disconnect(channelMergerNode);\n monitorConnections(channelMergerNode, whenConnected, whenDisconnected);\n };\n};\n//# sourceMappingURL=wrap-channel-merger-node.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/get-first-sample.js\nconst getFirstSample = (audioBuffer, buffer, channelNumber) => {\n // Bug #5: Safari does not support copyFromChannel() and copyToChannel().\n if (audioBuffer.copyFromChannel === undefined) {\n return audioBuffer.getChannelData(channelNumber)[0];\n }\n audioBuffer.copyFromChannel(buffer, channelNumber);\n return buffer[0];\n};\n//# sourceMappingURL=get-first-sample.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/is-dc-curve.js\nconst isDCCurve = (curve) => {\n if (curve === null) {\n return false;\n }\n const length = curve.length;\n if (length % 2 !== 0) {\n return curve[Math.floor(length / 2)] !== 0;\n }\n return curve[length / 2 - 1] + curve[length / 2] !== 0;\n};\n//# sourceMappingURL=is-dc-curve.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/overwrite-accessors.js\nconst overwriteAccessors = (object, property, createGetter, createSetter) => {\n let prototype = object;\n while (!prototype.hasOwnProperty(property)) {\n prototype = Object.getPrototypeOf(prototype);\n }\n const { get, set } = Object.getOwnPropertyDescriptor(prototype, property);\n Object.defineProperty(object, property, { get: createGetter(get), set: createSetter(set) });\n};\n//# sourceMappingURL=overwrite-accessors.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-audio-worklet-node-options.js\nconst sanitizeAudioWorkletNodeOptions = (options) => {\n return {\n ...options,\n outputChannelCount: options.outputChannelCount !== undefined\n ? options.outputChannelCount\n : options.numberOfInputs === 1 && options.numberOfOutputs === 1\n ? /*\n * Bug #61: This should be the computedNumberOfChannels, but unfortunately that is almost impossible to fake. That\'s why\n * the channelCountMode is required to be \'explicit\' as long as there is not a native implementation in every browser. That\n * makes sure the computedNumberOfChannels is equivilant to the channelCount which makes it much easier to compute.\n */\n [options.channelCount]\n : Array.from({ length: options.numberOfOutputs }, () => 1)\n };\n};\n//# sourceMappingURL=sanitize-audio-worklet-node-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-channel-splitter-options.js\nconst sanitizeChannelSplitterOptions = (options) => {\n return { ...options, channelCount: options.numberOfOutputs };\n};\n//# sourceMappingURL=sanitize-channel-splitter-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/sanitize-periodic-wave-options.js\nconst sanitizePeriodicWaveOptions = (options) => {\n const { imag, real } = options;\n if (imag === undefined) {\n if (real === undefined) {\n return { ...options, imag: [0, 0], real: [0, 0] };\n }\n return { ...options, imag: Array.from(real, () => 0), real };\n }\n if (real === undefined) {\n return { ...options, imag, real: Array.from(imag, () => 0) };\n }\n return { ...options, imag, real };\n};\n//# sourceMappingURL=sanitize-periodic-wave-options.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/set-value-at-time-until-possible.js\nconst setValueAtTimeUntilPossible = (audioParam, value, startTime) => {\n try {\n audioParam.setValueAtTime(value, startTime);\n }\n catch (err) {\n if (err.code !== 9) {\n throw err;\n }\n setValueAtTimeUntilPossible(audioParam, value, startTime + 1e-7);\n }\n};\n//# sourceMappingURL=set-value-at-time-until-possible.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-start-method-consecutive-calls-support.js\nconst testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.start();\n try {\n nativeAudioBufferSourceNode.start();\n }\n catch {\n return true;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-start-method-consecutive-calls-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-start-method-offset-clamping-support.js\nconst testAudioBufferSourceNodeStartMethodOffsetClampingSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n const nativeAudioBuffer = nativeContext.createBuffer(1, 1, 44100);\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n try {\n nativeAudioBufferSourceNode.start(0, 1);\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-start-method-offset-clamping-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-buffer-source-node-stop-method-nullified-buffer-support.js\nconst testAudioBufferSourceNodeStopMethodNullifiedBufferSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.start();\n try {\n nativeAudioBufferSourceNode.stop();\n }\n catch {\n return false;\n }\n return true;\n};\n//# sourceMappingURL=test-audio-buffer-source-node-stop-method-nullified-buffer-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-start-method-negative-parameters-support.js\nconst testAudioScheduledSourceNodeStartMethodNegativeParametersSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createOscillator();\n try {\n nativeAudioBufferSourceNode.start(-1);\n }\n catch (err) {\n return err instanceof RangeError;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-start-method-negative-parameters-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-stop-method-consecutive-calls-support.js\nconst testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport = (nativeContext) => {\n const nativeAudioBuffer = nativeContext.createBuffer(1, 1, 44100);\n const nativeAudioBufferSourceNode = nativeContext.createBufferSource();\n nativeAudioBufferSourceNode.buffer = nativeAudioBuffer;\n nativeAudioBufferSourceNode.start();\n nativeAudioBufferSourceNode.stop();\n try {\n nativeAudioBufferSourceNode.stop();\n return true;\n }\n catch {\n return false;\n }\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-stop-method-consecutive-calls-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-scheduled-source-node-stop-method-negative-parameters-support.js\nconst testAudioScheduledSourceNodeStopMethodNegativeParametersSupport = (nativeContext) => {\n const nativeAudioBufferSourceNode = nativeContext.createOscillator();\n try {\n nativeAudioBufferSourceNode.stop(-1);\n }\n catch (err) {\n return err instanceof RangeError;\n }\n return false;\n};\n//# sourceMappingURL=test-audio-scheduled-source-node-stop-method-negative-parameters-support.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/test-audio-worklet-node-options-clonability.js\nconst testAudioWorkletNodeOptionsClonability = (audioWorkletNodeOptions) => {\n const { port1, port2 } = new MessageChannel();\n try {\n // This will throw an error if the audioWorkletNodeOptions are not clonable.\n port1.postMessage(audioWorkletNodeOptions);\n }\n finally {\n port1.close();\n port2.close();\n }\n};\n//# sourceMappingURL=test-audio-worklet-node-options-clonability.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-buffer-source-node-start-method-offset-clamping.js\nconst wrapAudioBufferSourceNodeStartMethodOffsetClamping = (nativeAudioBufferSourceNode) => {\n nativeAudioBufferSourceNode.start = ((start) => {\n return (when = 0, offset = 0, duration) => {\n const buffer = nativeAudioBufferSourceNode.buffer;\n // Bug #154: Safari does not clamp the offset if it is equal to or greater than the duration of the buffer.\n const clampedOffset = buffer === null ? offset : Math.min(buffer.duration, offset);\n // Bug #155: Safari does not handle the offset correctly if it would cause the buffer to be not be played at all.\n if (buffer !== null && clampedOffset > buffer.duration - 0.5 / nativeAudioBufferSourceNode.context.sampleRate) {\n start.call(nativeAudioBufferSourceNode, when, 0, 0);\n }\n else {\n start.call(nativeAudioBufferSourceNode, when, clampedOffset, duration);\n }\n };\n })(nativeAudioBufferSourceNode.start);\n};\n//# sourceMappingURL=wrap-audio-buffer-source-node-start-method-offset-clamping.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-audio-scheduled-source-node-stop-method-consecutive-calls.js\n\nconst wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls = (nativeAudioScheduledSourceNode, nativeContext) => {\n const nativeGainNode = nativeContext.createGain();\n nativeAudioScheduledSourceNode.connect(nativeGainNode);\n const disconnectGainNode = ((disconnect) => {\n return () => {\n // @todo TypeScript cannot infer the overloaded signature with 1 argument yet.\n disconnect.call(nativeAudioScheduledSourceNode, nativeGainNode);\n nativeAudioScheduledSourceNode.removeEventListener(\'ended\', disconnectGainNode);\n };\n })(nativeAudioScheduledSourceNode.disconnect);\n nativeAudioScheduledSourceNode.addEventListener(\'ended\', disconnectGainNode);\n interceptConnections(nativeAudioScheduledSourceNode, nativeGainNode);\n nativeAudioScheduledSourceNode.stop = ((stop) => {\n let isStopped = false;\n return (when = 0) => {\n if (isStopped) {\n try {\n stop.call(nativeAudioScheduledSourceNode, when);\n }\n catch {\n nativeGainNode.gain.setValueAtTime(0, when);\n }\n }\n else {\n stop.call(nativeAudioScheduledSourceNode, when);\n isStopped = true;\n }\n };\n })(nativeAudioScheduledSourceNode.stop);\n};\n//# sourceMappingURL=wrap-audio-scheduled-source-node-stop-method-consecutive-calls.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/helpers/wrap-event-listener.js\nconst wrapEventListener = (target, eventListener) => {\n return (event) => {\n const descriptor = { value: target };\n Object.defineProperties(event, {\n currentTarget: descriptor,\n target: descriptor\n });\n if (typeof eventListener === \'function\') {\n return eventListener.call(target, event);\n }\n return eventListener.handleEvent.call(target, event);\n };\n};\n//# sourceMappingURL=wrap-event-listener.js.map\n;// CONCATENATED MODULE: ./node_modules/standardized-audio-context/build/es2019/module.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/*\n * @todo Explicitly referencing the barrel file seems to be necessary when enabling the\n * isolatedModules compiler option.\n */\n\n\nconst addActiveInputConnectionToAudioNode = createAddActiveInputConnectionToAudioNode(insertElementInSet);\nconst addPassiveInputConnectionToAudioNode = createAddPassiveInputConnectionToAudioNode(insertElementInSet);\nconst deleteActiveInputConnectionToAudioNode = createDeleteActiveInputConnectionToAudioNode(pickElementFromSet);\nconst audioNodeTailTimeStore = new WeakMap();\nconst getAudioNodeTailTime = createGetAudioNodeTailTime(audioNodeTailTimeStore);\nconst cacheTestResult = createCacheTestResult(new Map(), new WeakMap());\nconst module_window = createWindow();\nconst createNativeAnalyserNode = createNativeAnalyserNodeFactory(cacheTestResult, createIndexSizeError);\nconst getAudioNodeRenderer = createGetAudioNodeRenderer(getAudioNodeConnections);\nconst renderInputsOfAudioNode = createRenderInputsOfAudioNode(getAudioNodeConnections, getAudioNodeRenderer, isPartOfACycle);\nconst createAnalyserNodeRenderer = createAnalyserNodeRendererFactory(createNativeAnalyserNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst getNativeContext = createGetNativeContext(CONTEXT_STORE);\nconst nativeOfflineAudioContextConstructor = createNativeOfflineAudioContextConstructor(module_window);\nconst isNativeOfflineAudioContext = createIsNativeOfflineAudioContext(nativeOfflineAudioContextConstructor);\nconst audioParamAudioNodeStore = new WeakMap();\nconst eventTargetConstructor = createEventTargetConstructor(wrapEventListener);\nconst nativeAudioContextConstructor = createNativeAudioContextConstructor(module_window);\nconst isNativeAudioContext = createIsNativeAudioContext(nativeAudioContextConstructor);\nconst module_isNativeAudioNode = createIsNativeAudioNode(module_window);\nconst isNativeAudioParam = createIsNativeAudioParam(module_window);\nconst nativeAudioWorkletNodeConstructor = createNativeAudioWorkletNodeConstructor(module_window);\nconst audioNodeConstructor = createAudioNodeConstructor(createAddAudioNodeConnections(AUDIO_NODE_CONNECTIONS_STORE), createAddConnectionToAudioNode(addActiveInputConnectionToAudioNode, addPassiveInputConnectionToAudioNode, connectNativeAudioNodeToNativeAudioNode, deleteActiveInputConnectionToAudioNode, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getAudioNodeTailTime, getEventListenersOfAudioNode, getNativeAudioNode, insertElementInSet, isActiveAudioNode, isPartOfACycle, isPassiveAudioNode), cacheTestResult, createIncrementCycleCounterFactory(CYCLE_COUNTERS, disconnectNativeAudioNodeFromNativeAudioNode, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, isActiveAudioNode), createIndexSizeError, createInvalidAccessError, createNotSupportedError, createDecrementCycleCounter(connectNativeAudioNodeToNativeAudioNode, CYCLE_COUNTERS, getAudioNodeConnections, getNativeAudioNode, getNativeAudioParam, getNativeContext, isActiveAudioNode, isNativeOfflineAudioContext), createDetectCycles(audioParamAudioNodeStore, getAudioNodeConnections, getValueForKey), eventTargetConstructor, getNativeContext, isNativeAudioContext, module_isNativeAudioNode, isNativeAudioParam, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor);\nconst analyserNodeConstructor = createAnalyserNodeConstructor(audioNodeConstructor, createAnalyserNodeRenderer, createIndexSizeError, createNativeAnalyserNode, getNativeContext, isNativeOfflineAudioContext);\n\nconst audioBufferStore = new WeakSet();\nconst nativeAudioBufferConstructor = createNativeAudioBufferConstructor(module_window);\nconst convertNumberToUnsignedLong = createConvertNumberToUnsignedLong(new Uint32Array(1));\nconst wrapAudioBufferCopyChannelMethods = createWrapAudioBufferCopyChannelMethods(convertNumberToUnsignedLong, createIndexSizeError);\nconst wrapAudioBufferCopyChannelMethodsOutOfBounds = createWrapAudioBufferCopyChannelMethodsOutOfBounds(convertNumberToUnsignedLong);\nconst audioBufferConstructor = createAudioBufferConstructor(audioBufferStore, cacheTestResult, createNotSupportedError, nativeAudioBufferConstructor, nativeOfflineAudioContextConstructor, createTestAudioBufferConstructorSupport(nativeAudioBufferConstructor), wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\n\nconst addSilentConnection = createAddSilentConnection(createNativeGainNode);\nconst renderInputsOfAudioParam = createRenderInputsOfAudioParam(getAudioNodeRenderer, getAudioParamConnections, isPartOfACycle);\nconst connectAudioParam = createConnectAudioParam(renderInputsOfAudioParam);\nconst createNativeAudioBufferSourceNode = createNativeAudioBufferSourceNodeFactory(addSilentConnection, cacheTestResult, testAudioBufferSourceNodeStartMethodConsecutiveCallsSupport, testAudioBufferSourceNodeStartMethodOffsetClampingSupport, testAudioBufferSourceNodeStopMethodNullifiedBufferSupport, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioBufferSourceNodeStartMethodOffsetClamping, createWrapAudioBufferSourceNodeStopMethodNullifiedBuffer(overwriteAccessors), wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls);\nconst renderAutomation = createRenderAutomation(createGetAudioParamRenderer(getAudioParamConnections), renderInputsOfAudioParam);\nconst createAudioBufferSourceNodeRenderer = createAudioBufferSourceNodeRendererFactory(connectAudioParam, createNativeAudioBufferSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst createAudioParam = createAudioParamFactory(createAddAudioParamConnections(AUDIO_PARAM_CONNECTIONS_STORE), audioParamAudioNodeStore, AUDIO_PARAM_STORE, createAudioParamRenderer, bundle.createCancelAndHoldAutomationEvent, bundle.createCancelScheduledValuesAutomationEvent, bundle.createExponentialRampToValueAutomationEvent, bundle.createLinearRampToValueAutomationEvent, bundle.createSetTargetAutomationEvent, bundle.createSetValueAutomationEvent, bundle.createSetValueCurveAutomationEvent, nativeAudioContextConstructor, setValueAtTimeUntilPossible);\nconst audioBufferSourceNodeConstructor = createAudioBufferSourceNodeConstructor(audioNodeConstructor, createAudioBufferSourceNodeRenderer, createAudioParam, createInvalidStateError, createNativeAudioBufferSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\n\nconst audioDestinationNodeConstructor = createAudioDestinationNodeConstructor(audioNodeConstructor, createAudioDestinationNodeRenderer, createIndexSizeError, createInvalidStateError, createNativeAudioDestinationNodeFactory(createNativeGainNode, overwriteAccessors), getNativeContext, isNativeOfflineAudioContext, renderInputsOfAudioNode);\nconst createBiquadFilterNodeRenderer = createBiquadFilterNodeRendererFactory(connectAudioParam, createNativeBiquadFilterNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst setAudioNodeTailTime = createSetAudioNodeTailTime(audioNodeTailTimeStore);\nconst biquadFilterNodeConstructor = createBiquadFilterNodeConstructor(audioNodeConstructor, createAudioParam, createBiquadFilterNodeRenderer, createInvalidAccessError, createNativeBiquadFilterNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst monitorConnections = createMonitorConnections(insertElementInSet, module_isNativeAudioNode);\nconst wrapChannelMergerNode = createWrapChannelMergerNode(createInvalidStateError, monitorConnections);\nconst createNativeChannelMergerNode = createNativeChannelMergerNodeFactory(nativeAudioContextConstructor, wrapChannelMergerNode);\nconst createChannelMergerNodeRenderer = createChannelMergerNodeRendererFactory(createNativeChannelMergerNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst channelMergerNodeConstructor = createChannelMergerNodeConstructor(audioNodeConstructor, createChannelMergerNodeRenderer, createNativeChannelMergerNode, getNativeContext, isNativeOfflineAudioContext);\nconst createChannelSplitterNodeRenderer = createChannelSplitterNodeRendererFactory(createNativeChannelSplitterNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst channelSplitterNodeConstructor = createChannelSplitterNodeConstructor(audioNodeConstructor, createChannelSplitterNodeRenderer, createNativeChannelSplitterNode, getNativeContext, isNativeOfflineAudioContext, sanitizeChannelSplitterOptions);\nconst createNativeConstantSourceNodeFaker = createNativeConstantSourceNodeFakerFactory(addSilentConnection, createNativeAudioBufferSourceNode, createNativeGainNode, monitorConnections);\nconst createNativeConstantSourceNode = createNativeConstantSourceNodeFactory(addSilentConnection, cacheTestResult, createNativeConstantSourceNodeFaker, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport);\nconst createConstantSourceNodeRenderer = createConstantSourceNodeRendererFactory(connectAudioParam, createNativeConstantSourceNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst constantSourceNodeConstructor = createConstantSourceNodeConstructor(audioNodeConstructor, createAudioParam, createConstantSourceNodeRenderer, createNativeConstantSourceNode, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\nconst createNativeConvolverNode = createNativeConvolverNodeFactory(createNotSupportedError, overwriteAccessors);\nconst createConvolverNodeRenderer = createConvolverNodeRendererFactory(createNativeConvolverNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst convolverNodeConstructor = createConvolverNodeConstructor(audioNodeConstructor, createConvolverNodeRenderer, createNativeConvolverNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createDelayNodeRenderer = createDelayNodeRendererFactory(connectAudioParam, createNativeDelayNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst delayNodeConstructor = createDelayNodeConstructor(audioNodeConstructor, createAudioParam, createDelayNodeRenderer, createNativeDelayNode, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createNativeDynamicsCompressorNode = createNativeDynamicsCompressorNodeFactory(createNotSupportedError);\nconst createDynamicsCompressorNodeRenderer = createDynamicsCompressorNodeRendererFactory(connectAudioParam, createNativeDynamicsCompressorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst dynamicsCompressorNodeConstructor = createDynamicsCompressorNodeConstructor(audioNodeConstructor, createAudioParam, createDynamicsCompressorNodeRenderer, createNativeDynamicsCompressorNode, createNotSupportedError, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createGainNodeRenderer = createGainNodeRendererFactory(connectAudioParam, createNativeGainNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst gainNodeConstructor = createGainNodeConstructor(audioNodeConstructor, createAudioParam, createGainNodeRenderer, createNativeGainNode, getNativeContext, isNativeOfflineAudioContext);\nconst createNativeIIRFilterNodeFaker = createNativeIIRFilterNodeFakerFactory(createInvalidAccessError, createInvalidStateError, createNativeScriptProcessorNode, createNotSupportedError);\nconst renderNativeOfflineAudioContext = createRenderNativeOfflineAudioContext(cacheTestResult, createNativeGainNode, createNativeScriptProcessorNode, createTestOfflineAudioContextCurrentTimeSupport(createNativeGainNode, nativeOfflineAudioContextConstructor));\nconst createIIRFilterNodeRenderer = createIIRFilterNodeRendererFactory(createNativeAudioBufferSourceNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst createNativeIIRFilterNode = createNativeIIRFilterNodeFactory(createNativeIIRFilterNodeFaker);\nconst iIRFilterNodeConstructor = createIIRFilterNodeConstructor(audioNodeConstructor, createNativeIIRFilterNode, createIIRFilterNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createAudioListener = createAudioListenerFactory(createAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeScriptProcessorNode, createNotSupportedError, getFirstSample, isNativeOfflineAudioContext, overwriteAccessors);\nconst unrenderedAudioWorkletNodeStore = new WeakMap();\nconst minimalBaseAudioContextConstructor = createMinimalBaseAudioContextConstructor(audioDestinationNodeConstructor, createAudioListener, eventTargetConstructor, isNativeOfflineAudioContext, unrenderedAudioWorkletNodeStore, wrapEventListener);\nconst createNativeOscillatorNode = createNativeOscillatorNodeFactory(addSilentConnection, cacheTestResult, testAudioScheduledSourceNodeStartMethodNegativeParametersSupport, testAudioScheduledSourceNodeStopMethodConsecutiveCallsSupport, testAudioScheduledSourceNodeStopMethodNegativeParametersSupport, wrapAudioScheduledSourceNodeStopMethodConsecutiveCalls);\nconst createOscillatorNodeRenderer = createOscillatorNodeRendererFactory(connectAudioParam, createNativeOscillatorNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst oscillatorNodeConstructor = createOscillatorNodeConstructor(audioNodeConstructor, createAudioParam, createNativeOscillatorNode, createOscillatorNodeRenderer, getNativeContext, isNativeOfflineAudioContext, wrapEventListener);\nconst createConnectedNativeAudioBufferSourceNode = createConnectedNativeAudioBufferSourceNodeFactory(createNativeAudioBufferSourceNode);\nconst createNativeWaveShaperNodeFaker = createNativeWaveShaperNodeFakerFactory(createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeGainNode, isDCCurve, monitorConnections);\nconst createNativeWaveShaperNode = createNativeWaveShaperNodeFactory(createConnectedNativeAudioBufferSourceNode, createInvalidStateError, createNativeWaveShaperNodeFaker, isDCCurve, monitorConnections, nativeAudioContextConstructor, overwriteAccessors);\nconst createNativePannerNodeFaker = createNativePannerNodeFakerFactory(connectNativeAudioNodeToNativeAudioNode, createInvalidStateError, createNativeChannelMergerNode, createNativeGainNode, createNativeScriptProcessorNode, createNativeWaveShaperNode, createNotSupportedError, disconnectNativeAudioNodeFromNativeAudioNode, getFirstSample, monitorConnections);\nconst createNativePannerNode = createNativePannerNodeFactory(createNativePannerNodeFaker);\nconst createPannerNodeRenderer = createPannerNodeRendererFactory(connectAudioParam, createNativeChannelMergerNode, createNativeConstantSourceNode, createNativeGainNode, createNativePannerNode, getNativeAudioNode, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst pannerNodeConstructor = createPannerNodeConstructor(audioNodeConstructor, createAudioParam, createNativePannerNode, createPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst createNativePeriodicWave = createNativePeriodicWaveFactory(createIndexSizeError);\nconst periodicWaveConstructor = createPeriodicWaveConstructor(createNativePeriodicWave, getNativeContext, new WeakSet(), sanitizePeriodicWaveOptions);\nconst nativeStereoPannerNodeFakerFactory = createNativeStereoPannerNodeFakerFactory(createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeGainNode, createNativeWaveShaperNode, createNotSupportedError, monitorConnections);\nconst createNativeStereoPannerNode = createNativeStereoPannerNodeFactory(nativeStereoPannerNodeFakerFactory, createNotSupportedError);\nconst createStereoPannerNodeRenderer = createStereoPannerNodeRendererFactory(connectAudioParam, createNativeStereoPannerNode, getNativeAudioNode, renderAutomation, renderInputsOfAudioNode);\nconst stereoPannerNodeConstructor = createStereoPannerNodeConstructor(audioNodeConstructor, createAudioParam, createNativeStereoPannerNode, createStereoPannerNodeRenderer, getNativeContext, isNativeOfflineAudioContext);\nconst createWaveShaperNodeRenderer = createWaveShaperNodeRendererFactory(createNativeWaveShaperNode, getNativeAudioNode, renderInputsOfAudioNode);\nconst waveShaperNodeConstructor = createWaveShaperNodeConstructor(audioNodeConstructor, createInvalidStateError, createNativeWaveShaperNode, createWaveShaperNodeRenderer, getNativeContext, isNativeOfflineAudioContext, setAudioNodeTailTime);\nconst isSecureContext = createIsSecureContext(module_window);\nconst exposeCurrentFrameAndCurrentTime = createExposeCurrentFrameAndCurrentTime(module_window);\nconst backupOfflineAudioContextStore = new WeakMap();\nconst getOrCreateBackupOfflineAudioContext = createGetOrCreateBackupOfflineAudioContext(backupOfflineAudioContextStore, nativeOfflineAudioContextConstructor);\n// The addAudioWorkletModule() function is only available in a SecureContext.\nconst addAudioWorkletModule = isSecureContext\n ? createAddAudioWorkletModule(cacheTestResult, createNotSupportedError, createEvaluateSource(module_window), exposeCurrentFrameAndCurrentTime, createFetchSource(createAbortError), getNativeContext, getOrCreateBackupOfflineAudioContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, new WeakMap(), new WeakMap(), createTestAudioWorkletProcessorPostMessageSupport(nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor), \n // @todo window is guaranteed to be defined because isSecureContext checks that as well.\n module_window)\n : undefined;\nconst isNativeContext = createIsNativeContext(isNativeAudioContext, isNativeOfflineAudioContext);\nconst decodeAudioData = createDecodeAudioData(audioBufferStore, cacheTestResult, createDataCloneError, createEncodingError, new WeakSet(), getNativeContext, isNativeContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, testPromiseSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\nconst baseAudioContextConstructor = createBaseAudioContextConstructor(addAudioWorkletModule, analyserNodeConstructor, audioBufferConstructor, audioBufferSourceNodeConstructor, biquadFilterNodeConstructor, channelMergerNodeConstructor, channelSplitterNodeConstructor, constantSourceNodeConstructor, convolverNodeConstructor, decodeAudioData, delayNodeConstructor, dynamicsCompressorNodeConstructor, gainNodeConstructor, iIRFilterNodeConstructor, minimalBaseAudioContextConstructor, oscillatorNodeConstructor, pannerNodeConstructor, periodicWaveConstructor, stereoPannerNodeConstructor, waveShaperNodeConstructor);\nconst mediaElementAudioSourceNodeConstructor = createMediaElementAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaElementAudioSourceNode, getNativeContext, isNativeOfflineAudioContext);\nconst mediaStreamAudioDestinationNodeConstructor = createMediaStreamAudioDestinationNodeConstructor(audioNodeConstructor, createNativeMediaStreamAudioDestinationNode, getNativeContext, isNativeOfflineAudioContext);\nconst mediaStreamAudioSourceNodeConstructor = createMediaStreamAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaStreamAudioSourceNode, getNativeContext, isNativeOfflineAudioContext);\nconst createNativeMediaStreamTrackAudioSourceNode = createNativeMediaStreamTrackAudioSourceNodeFactory(createInvalidStateError, isNativeOfflineAudioContext);\nconst mediaStreamTrackAudioSourceNodeConstructor = createMediaStreamTrackAudioSourceNodeConstructor(audioNodeConstructor, createNativeMediaStreamTrackAudioSourceNode, getNativeContext);\nconst audioContextConstructor = createAudioContextConstructor(baseAudioContextConstructor, createInvalidStateError, createNotSupportedError, createUnknownError, mediaElementAudioSourceNodeConstructor, mediaStreamAudioDestinationNodeConstructor, mediaStreamAudioSourceNodeConstructor, mediaStreamTrackAudioSourceNodeConstructor, nativeAudioContextConstructor);\n\nconst getUnrenderedAudioWorkletNodes = createGetUnrenderedAudioWorkletNodes(unrenderedAudioWorkletNodeStore);\nconst addUnrenderedAudioWorkletNode = createAddUnrenderedAudioWorkletNode(getUnrenderedAudioWorkletNodes);\nconst connectMultipleOutputs = createConnectMultipleOutputs(createIndexSizeError);\nconst deleteUnrenderedAudioWorkletNode = createDeleteUnrenderedAudioWorkletNode(getUnrenderedAudioWorkletNodes);\nconst disconnectMultipleOutputs = createDisconnectMultipleOutputs(createIndexSizeError);\nconst activeAudioWorkletNodeInputsStore = new WeakMap();\nconst getActiveAudioWorkletNodeInputs = createGetActiveAudioWorkletNodeInputs(activeAudioWorkletNodeInputsStore, getValueForKey);\nconst createNativeAudioWorkletNodeFaker = createNativeAudioWorkletNodeFakerFactory(connectMultipleOutputs, createIndexSizeError, createInvalidStateError, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, createNativeScriptProcessorNode, createNotSupportedError, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getActiveAudioWorkletNodeInputs, monitorConnections);\nconst createNativeAudioWorkletNode = createNativeAudioWorkletNodeFactory(createInvalidStateError, createNativeAudioWorkletNodeFaker, createNativeGainNode, createNotSupportedError, monitorConnections);\nconst createAudioWorkletNodeRenderer = createAudioWorkletNodeRendererFactory(connectAudioParam, connectMultipleOutputs, createNativeAudioBufferSourceNode, createNativeChannelMergerNode, createNativeChannelSplitterNode, createNativeConstantSourceNode, createNativeGainNode, deleteUnrenderedAudioWorkletNode, disconnectMultipleOutputs, exposeCurrentFrameAndCurrentTime, getNativeAudioNode, nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor, renderAutomation, renderInputsOfAudioNode, renderNativeOfflineAudioContext);\nconst getBackupOfflineAudioContext = createGetBackupOfflineAudioContext(backupOfflineAudioContextStore);\nconst setActiveAudioWorkletNodeInputs = createSetActiveAudioWorkletNodeInputs(activeAudioWorkletNodeInputsStore);\n// The AudioWorkletNode constructor is only available in a SecureContext.\nconst audioWorkletNodeConstructor = isSecureContext\n ? createAudioWorkletNodeConstructor(addUnrenderedAudioWorkletNode, audioNodeConstructor, createAudioParam, createAudioWorkletNodeRenderer, createNativeAudioWorkletNode, getAudioNodeConnections, getBackupOfflineAudioContext, getNativeContext, isNativeOfflineAudioContext, nativeAudioWorkletNodeConstructor, sanitizeAudioWorkletNodeOptions, setActiveAudioWorkletNodeInputs, testAudioWorkletNodeOptionsClonability, wrapEventListener)\n : undefined;\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst minimalAudioContextConstructor = createMinimalAudioContextConstructor(createInvalidStateError, createNotSupportedError, createUnknownError, minimalBaseAudioContextConstructor, nativeAudioContextConstructor);\n\nconst createNativeOfflineAudioContext = createCreateNativeOfflineAudioContext(createNotSupportedError, nativeOfflineAudioContextConstructor);\nconst startRendering = createStartRendering(audioBufferStore, cacheTestResult, getAudioNodeRenderer, getUnrenderedAudioWorkletNodes, renderNativeOfflineAudioContext, testAudioBufferCopyChannelMethodsOutOfBoundsSupport, wrapAudioBufferCopyChannelMethods, wrapAudioBufferCopyChannelMethodsOutOfBounds);\nconst minimalOfflineAudioContextConstructor = createMinimalOfflineAudioContextConstructor(cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, minimalBaseAudioContextConstructor, startRendering);\n\nconst offlineAudioContextConstructor = createOfflineAudioContextConstructor(baseAudioContextConstructor, cacheTestResult, createInvalidStateError, createNativeOfflineAudioContext, startRendering);\n\n\n\n\n\n\nconst isAnyAudioContext = createIsAnyAudioContext(CONTEXT_STORE, isNativeAudioContext);\nconst isAnyAudioNode = createIsAnyAudioNode(AUDIO_NODE_STORE, module_isNativeAudioNode);\nconst isAnyAudioParam = createIsAnyAudioParam(AUDIO_PARAM_STORE, isNativeAudioParam);\nconst isAnyOfflineAudioContext = createIsAnyOfflineAudioContext(CONTEXT_STORE, isNativeOfflineAudioContext);\nconst isSupported = () => createIsSupportedPromise(cacheTestResult, createTestAudioBufferCopyChannelMethodsSubarraySupport(nativeOfflineAudioContextConstructor), createTestAudioContextCloseMethodSupport(nativeAudioContextConstructor), createTestAudioContextDecodeAudioDataMethodTypeErrorSupport(nativeOfflineAudioContextConstructor), createTestAudioContextOptionsSupport(nativeAudioContextConstructor), createTestAudioNodeConnectMethodSupport(nativeOfflineAudioContextConstructor), createTestAudioWorkletProcessorNoOutputsSupport(nativeAudioWorkletNodeConstructor, nativeOfflineAudioContextConstructor), createTestChannelMergerNodeChannelCountSupport(nativeOfflineAudioContextConstructor), createTestConstantSourceNodeAccurateSchedulingSupport(nativeOfflineAudioContextConstructor), createTestConvolverNodeBufferReassignabilitySupport(nativeOfflineAudioContextConstructor), createTestConvolverNodeChannelCountSupport(nativeOfflineAudioContextConstructor), testDomExceptionConstructorSupport, createTestIsSecureContextSupport(module_window), createTestMediaStreamAudioSourceNodeMediaStreamWithoutAudioTrackSupport(nativeAudioContextConstructor), createTestStereoPannerNodeDefaultValueSupport(nativeOfflineAudioContextConstructor), testTransferablesSupport);\n//# sourceMappingURL=module.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Debug.js\n/**\n * Assert that the statement is true, otherwise invoke the error.\n * @param statement\n * @param error The message which is passed into an Error\n */\nfunction Debug_assert(statement, error) {\n if (!statement) {\n throw new Error(error);\n }\n}\n/**\n * Make sure that the given value is within the range\n */\nfunction Debug_assertRange(value, gte, lte = Infinity) {\n if (!(gte <= value && value <= lte)) {\n throw new RangeError(`Value must be within [${gte}, ${lte}], got: ${value}`);\n }\n}\n/**\n * Make sure that the given value is within the range\n */\nfunction assertContextRunning(context) {\n // add a warning if the context is not started\n if (!context.isOffline && context.state !== "running") {\n Debug_warn("The AudioContext is \\"suspended\\". Invoke Tone.start() from a user action to start the audio.");\n }\n}\n/**\n * The default logger is the console\n */\nlet defaultLogger = console;\n/**\n * Set the logging interface\n */\nfunction setLogger(logger) {\n defaultLogger = logger;\n}\n/**\n * Log anything\n */\nfunction log(...args) {\n defaultLogger.log(...args);\n}\n/**\n * Warn anything\n */\nfunction Debug_warn(...args) {\n defaultLogger.warn(...args);\n}\n//# sourceMappingURL=Debug.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/TypeCheck.js\n/**\n * Test if the arg is undefined\n */\nfunction TypeCheck_isUndef(arg) {\n return typeof arg === "undefined";\n}\n/**\n * Test if the arg is not undefined\n */\nfunction TypeCheck_isDefined(arg) {\n return !TypeCheck_isUndef(arg);\n}\n/**\n * Test if the arg is a function\n */\nfunction isFunction(arg) {\n return typeof arg === "function";\n}\n/**\n * Test if the argument is a number.\n */\nfunction TypeCheck_isNumber(arg) {\n return (typeof arg === "number");\n}\n/**\n * Test if the given argument is an object literal (i.e. `{}`);\n */\nfunction TypeCheck_isObject(arg) {\n return (Object.prototype.toString.call(arg) === "[object Object]" && arg.constructor === Object);\n}\n/**\n * Test if the argument is a boolean.\n */\nfunction TypeCheck_isBoolean(arg) {\n return (typeof arg === "boolean");\n}\n/**\n * Test if the argument is an Array\n */\nfunction TypeCheck_isArray(arg) {\n return (Array.isArray(arg));\n}\n/**\n * Test if the argument is a string.\n */\nfunction TypeCheck_isString(arg) {\n return (typeof arg === "string");\n}\n/**\n * Test if the argument is in the form of a note in scientific pitch notation.\n * e.g. "C4"\n */\nfunction isNote(arg) {\n return TypeCheck_isString(arg) && /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i.test(arg);\n}\n//# sourceMappingURL=TypeCheck.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/AudioContext.js\n\n\n\n/**\n * Create a new AudioContext\n */\nfunction createAudioContext(options) {\n return new audioContextConstructor(options);\n}\n/**\n * Create a new OfflineAudioContext\n */\nfunction createOfflineAudioContext(channels, length, sampleRate) {\n return new offlineAudioContextConstructor(channels, length, sampleRate);\n}\n/**\n * A reference to the window object\n * @hidden\n */\nconst AudioContext_theWindow = typeof self === "object" ? self : null;\n/**\n * If the browser has a window object which has an AudioContext\n * @hidden\n */\nconst hasAudioContext = AudioContext_theWindow &&\n (AudioContext_theWindow.hasOwnProperty("AudioContext") || AudioContext_theWindow.hasOwnProperty("webkitAudioContext"));\nfunction createAudioWorkletNode(context, name, options) {\n Debug_assert(TypeCheck_isDefined(audioWorkletNodeConstructor), "This node only works in a secure context (https or localhost)");\n // @ts-ignore\n return new audioWorkletNodeConstructor(context, name, options);\n}\n/**\n * This promise resolves to a boolean which indicates if the\n * functionality is supported within the currently used browse.\n * Taken from [standardized-audio-context](https://github.com/chrisguttandin/standardized-audio-context#issupported)\n */\n\n//# sourceMappingURL=AudioContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tslib/tslib.es6.js\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nfunction __extends(d, b) {\r\n if (typeof b !== "function" && b !== null)\r\n throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nfunction __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === "function")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nfunction __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nfunction __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nfunction __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }\r\n var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";\r\n var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === "accessor") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== "object") throw new TypeError("Object expected");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.push(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === "field") initializers.push(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nfunction __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nfunction __propKey(x) {\r\n return typeof x === "symbol" ? x : "".concat(x);\r\n};\r\n\r\nfunction __setFunctionName(f, name, prefix) {\r\n if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";\r\n return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });\r\n};\r\n\r\nfunction __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nfunction tslib_es6_awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nfunction __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError("Generator is already executing.");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n 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;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nvar __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nfunction __exportStar(m, o) {\r\n for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nfunction __values(o) {\r\n var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === "number") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");\r\n}\r\n\r\nfunction __read(o, n) {\r\n var m = typeof Symbol === "function" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i["return"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nfunction __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nfunction __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nfunction __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume("next", value); }\r\n function reject(value) { resume("throw", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nfunction __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nfunction __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nfunction __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, "default", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o["default"] = v;\r\n};\r\n\r\nfunction __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nfunction __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nfunction __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");\r\n return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nfunction __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === "m") throw new TypeError("Private method is not writable");\r\n if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");\r\n if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");\r\n return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nfunction __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use \'in\' operator on non-object");\r\n return typeof state === "function" ? receiver === state : state.has(receiver);\r\n}\r\n\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Ticker.js\n/**\n * A class which provides a reliable callback using either\n * a Web Worker, or if that isn\'t supported, falls back to setTimeout.\n */\nclass Ticker {\n constructor(callback, type, updateInterval) {\n this._callback = callback;\n this._type = type;\n this._updateInterval = updateInterval;\n // create the clock source for the first time\n this._createClock();\n }\n /**\n * Generate a web worker\n */\n _createWorker() {\n const blob = new Blob([\n /* javascript */ `\n\t\t\t// the initial timeout time\n\t\t\tlet timeoutTime = ${(this._updateInterval * 1000).toFixed(1)};\n\t\t\t// onmessage callback\n\t\t\tself.onmessage = function(msg){\n\t\t\t\ttimeoutTime = parseInt(msg.data);\n\t\t\t};\n\t\t\t// the tick function which posts a message\n\t\t\t// and schedules a new tick\n\t\t\tfunction tick(){\n\t\t\t\tsetTimeout(tick, timeoutTime);\n\t\t\t\tself.postMessage(\'tick\');\n\t\t\t}\n\t\t\t// call tick initially\n\t\t\ttick();\n\t\t\t`\n ], { type: "text/javascript" });\n const blobUrl = URL.createObjectURL(blob);\n const worker = new Worker(blobUrl);\n worker.onmessage = this._callback.bind(this);\n this._worker = worker;\n }\n /**\n * Create a timeout loop\n */\n _createTimeout() {\n this._timeout = setTimeout(() => {\n this._createTimeout();\n this._callback();\n }, this._updateInterval * 1000);\n }\n /**\n * Create the clock source.\n */\n _createClock() {\n if (this._type === "worker") {\n try {\n this._createWorker();\n }\n catch (e) {\n // workers not supported, fallback to timeout\n this._type = "timeout";\n this._createClock();\n }\n }\n else if (this._type === "timeout") {\n this._createTimeout();\n }\n }\n /**\n * Clean up the current clock source\n */\n _disposeClock() {\n if (this._timeout) {\n clearTimeout(this._timeout);\n this._timeout = 0;\n }\n if (this._worker) {\n this._worker.terminate();\n this._worker.onmessage = null;\n }\n }\n /**\n * The rate in seconds the ticker will update\n */\n get updateInterval() {\n return this._updateInterval;\n }\n set updateInterval(interval) {\n this._updateInterval = Math.max(interval, 128 / 44100);\n if (this._type === "worker") {\n this._worker.postMessage(Math.max(interval * 1000, 1));\n }\n }\n /**\n * The type of the ticker, either a worker or a timeout\n */\n get type() {\n return this._type;\n }\n set type(type) {\n this._disposeClock();\n this._type = type;\n this._createClock();\n }\n /**\n * Clean up\n */\n dispose() {\n this._disposeClock();\n }\n}\n//# sourceMappingURL=Ticker.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/AdvancedTypeCheck.js\n\n/**\n * Test if the given value is an instanceof AudioParam\n */\nfunction isAudioParam(arg) {\n return isAnyAudioParam(arg);\n}\n/**\n * Test if the given value is an instanceof AudioNode\n */\nfunction AdvancedTypeCheck_isAudioNode(arg) {\n return isAnyAudioNode(arg);\n}\n/**\n * Test if the arg is instanceof an OfflineAudioContext\n */\nfunction isOfflineAudioContext(arg) {\n return isAnyOfflineAudioContext(arg);\n}\n/**\n * Test if the arg is an instanceof AudioContext\n */\nfunction isAudioContext(arg) {\n return isAnyAudioContext(arg);\n}\n/**\n * Test if the arg is instanceof an AudioBuffer\n */\nfunction isAudioBuffer(arg) {\n return arg instanceof AudioBuffer;\n}\n//# sourceMappingURL=AdvancedTypeCheck.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Defaults.js\n\n\n/**\n * Some objects should not be merged\n */\nfunction noCopy(key, arg) {\n return key === "value" || isAudioParam(arg) || AdvancedTypeCheck_isAudioNode(arg) || isAudioBuffer(arg);\n}\nfunction Defaults_deepMerge(target, ...sources) {\n if (!sources.length) {\n return target;\n }\n const source = sources.shift();\n if (TypeCheck_isObject(target) && TypeCheck_isObject(source)) {\n for (const key in source) {\n if (noCopy(key, source[key])) {\n target[key] = source[key];\n }\n else if (TypeCheck_isObject(source[key])) {\n if (!target[key]) {\n Object.assign(target, { [key]: {} });\n }\n Defaults_deepMerge(target[key], source[key]);\n }\n else {\n Object.assign(target, { [key]: source[key] });\n }\n }\n }\n // @ts-ignore\n return Defaults_deepMerge(target, ...sources);\n}\n/**\n * Returns true if the two arrays have the same value for each of the elements\n */\nfunction deepEquals(arrayA, arrayB) {\n return arrayA.length === arrayB.length && arrayA.every((element, index) => arrayB[index] === element);\n}\n/**\n * Convert an args array into an object.\n */\nfunction Defaults_optionsFromArguments(defaults, argsArray, keys = [], objKey) {\n const opts = {};\n const args = Array.from(argsArray);\n // if the first argument is an object and has an object key\n if (TypeCheck_isObject(args[0]) && objKey && !Reflect.has(args[0], objKey)) {\n // if it\'s not part of the defaults\n const partOfDefaults = Object.keys(args[0]).some(key => Reflect.has(defaults, key));\n if (!partOfDefaults) {\n // merge that key\n Defaults_deepMerge(opts, { [objKey]: args[0] });\n // remove the obj key from the keys\n keys.splice(keys.indexOf(objKey), 1);\n // shift the first argument off\n args.shift();\n }\n }\n if (args.length === 1 && TypeCheck_isObject(args[0])) {\n Defaults_deepMerge(opts, args[0]);\n }\n else {\n for (let i = 0; i < keys.length; i++) {\n if (TypeCheck_isDefined(args[i])) {\n opts[keys[i]] = args[i];\n }\n }\n }\n return Defaults_deepMerge(defaults, opts);\n}\n/**\n * Return this instances default values by calling Constructor.getDefaults()\n */\nfunction getDefaultsFromInstance(instance) {\n return instance.constructor.getDefaults();\n}\n/**\n * Returns the fallback if the given object is undefined.\n * Take an array of arguments and return a formatted options object.\n */\nfunction Defaults_defaultArg(given, fallback) {\n if (TypeCheck_isUndef(given)) {\n return fallback;\n }\n else {\n return given;\n }\n}\n/**\n * Remove all of the properties belonging to omit from obj.\n */\nfunction Defaults_omitFromObject(obj, omit) {\n omit.forEach(prop => {\n if (Reflect.has(obj, prop)) {\n delete obj[prop];\n }\n });\n return obj;\n}\n//# sourceMappingURL=Defaults.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/Tone.js\n/**\n * Tone.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2014-2019 Yotam Mann\n */\n\n\n\n/**\n * @class Tone is the base class of all other classes.\n * @category Core\n * @constructor\n */\nclass Tone {\n constructor() {\n //-------------------------------------\n // \tDEBUGGING\n //-------------------------------------\n /**\n * Set this debug flag to log all events that happen in this class.\n */\n this.debug = false;\n //-------------------------------------\n // \tDISPOSING\n //-------------------------------------\n /**\n * Indicates if the instance was disposed\n */\n this._wasDisposed = false;\n }\n /**\n * Returns all of the default options belonging to the class.\n */\n static getDefaults() {\n return {};\n }\n /**\n * Prints the outputs to the console log for debugging purposes.\n * Prints the contents only if either the object has a property\n * called `debug` set to true, or a variable called TONE_DEBUG_CLASS\n * is set to the name of the class.\n * @example\n * const osc = new Tone.Oscillator();\n * // prints all logs originating from this oscillator\n * osc.debug = true;\n * // calls to start/stop will print in the console\n * osc.start();\n */\n log(...args) {\n // if the object is either set to debug = true\n // or if there is a string on the Tone.global.with the class name\n if (this.debug || (AudioContext_theWindow && this.toString() === AudioContext_theWindow.TONE_DEBUG_CLASS)) {\n log(this, ...args);\n }\n }\n /**\n * disconnect and dispose.\n */\n dispose() {\n this._wasDisposed = true;\n return this;\n }\n /**\n * Indicates if the instance was disposed. \'Disposing\' an\n * instance means that all of the Web Audio nodes that were\n * created for the instance are disconnected and freed for garbage collection.\n */\n get disposed() {\n return this._wasDisposed;\n }\n /**\n * Convert the class to a string\n * @example\n * const osc = new Tone.Oscillator();\n * console.log(osc.toString());\n */\n toString() {\n return this.name;\n }\n}\n/**\n * The version number semver\n */\nTone.version = version;\n//# sourceMappingURL=Tone.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Math.js\n/**\n * The threshold for correctness for operators. Less than one sample even\n * at very high sampling rates (e.g. `1e-6 < 1 / 192000`).\n */\nconst EPSILON = 1e-6;\n/**\n * Test if A is greater than B\n */\nfunction GT(a, b) {\n return a > b + EPSILON;\n}\n/**\n * Test if A is greater than or equal to B\n */\nfunction GTE(a, b) {\n return GT(a, b) || EQ(a, b);\n}\n/**\n * Test if A is less than B\n */\nfunction LT(a, b) {\n return a + EPSILON < b;\n}\n/**\n * Test if A is less than B\n */\nfunction EQ(a, b) {\n return Math.abs(a - b) < EPSILON;\n}\n/**\n * Clamp the value within the given range\n */\nfunction Math_clamp(value, min, max) {\n return Math.max(Math.min(value, max), min);\n}\n//# sourceMappingURL=Math.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Timeline.js\n\n\n\n\n/**\n * A Timeline class for scheduling and maintaining state\n * along a timeline. All events must have a "time" property.\n * Internally, events are stored in time order for fast\n * retrieval.\n */\nclass Timeline extends Tone {\n constructor() {\n super();\n this.name = "Timeline";\n /**\n * The array of scheduled timeline events\n */\n this._timeline = [];\n const options = Defaults_optionsFromArguments(Timeline.getDefaults(), arguments, ["memory"]);\n this.memory = options.memory;\n this.increasing = options.increasing;\n }\n static getDefaults() {\n return {\n memory: Infinity,\n increasing: false,\n };\n }\n /**\n * The number of items in the timeline.\n */\n get length() {\n return this._timeline.length;\n }\n /**\n * Insert an event object onto the timeline. Events must have a "time" attribute.\n * @param event The event object to insert into the timeline.\n */\n add(event) {\n // the event needs to have a time attribute\n Debug_assert(Reflect.has(event, "time"), "Timeline: events must have a time attribute");\n event.time = event.time.valueOf();\n if (this.increasing && this.length) {\n const lastValue = this._timeline[this.length - 1];\n Debug_assert(GTE(event.time, lastValue.time), "The time must be greater than or equal to the last scheduled time");\n this._timeline.push(event);\n }\n else {\n const index = this._search(event.time);\n this._timeline.splice(index + 1, 0, event);\n }\n // if the length is more than the memory, remove the previous ones\n if (this.length > this.memory) {\n const diff = this.length - this.memory;\n this._timeline.splice(0, diff);\n }\n return this;\n }\n /**\n * Remove an event from the timeline.\n * @param {Object} event The event object to remove from the list.\n * @returns {Timeline} this\n */\n remove(event) {\n const index = this._timeline.indexOf(event);\n if (index !== -1) {\n this._timeline.splice(index, 1);\n }\n return this;\n }\n /**\n * Get the nearest event whose time is less than or equal to the given time.\n * @param time The time to query.\n */\n get(time, param = "time") {\n const index = this._search(time, param);\n if (index !== -1) {\n return this._timeline[index];\n }\n else {\n return null;\n }\n }\n /**\n * Return the first event in the timeline without removing it\n * @returns {Object} The first event object\n */\n peek() {\n return this._timeline[0];\n }\n /**\n * Return the first event in the timeline and remove it\n */\n shift() {\n return this._timeline.shift();\n }\n /**\n * Get the event which is scheduled after the given time.\n * @param time The time to query.\n */\n getAfter(time, param = "time") {\n const index = this._search(time, param);\n if (index + 1 < this._timeline.length) {\n return this._timeline[index + 1];\n }\n else {\n return null;\n }\n }\n /**\n * Get the event before the event at the given time.\n * @param time The time to query.\n */\n getBefore(time) {\n const len = this._timeline.length;\n // if it\'s after the last item, return the last item\n if (len > 0 && this._timeline[len - 1].time < time) {\n return this._timeline[len - 1];\n }\n const index = this._search(time);\n if (index - 1 >= 0) {\n return this._timeline[index - 1];\n }\n else {\n return null;\n }\n }\n /**\n * Cancel events at and after the given time\n * @param after The time to query.\n */\n cancel(after) {\n if (this._timeline.length > 1) {\n let index = this._search(after);\n if (index >= 0) {\n if (EQ(this._timeline[index].time, after)) {\n // get the first item with that time\n for (let i = index; i >= 0; i--) {\n if (EQ(this._timeline[i].time, after)) {\n index = i;\n }\n else {\n break;\n }\n }\n this._timeline = this._timeline.slice(0, index);\n }\n else {\n this._timeline = this._timeline.slice(0, index + 1);\n }\n }\n else {\n this._timeline = [];\n }\n }\n else if (this._timeline.length === 1) {\n // the first item\'s time\n if (GTE(this._timeline[0].time, after)) {\n this._timeline = [];\n }\n }\n return this;\n }\n /**\n * Cancel events before or equal to the given time.\n * @param time The time to cancel before.\n */\n cancelBefore(time) {\n const index = this._search(time);\n if (index >= 0) {\n this._timeline = this._timeline.slice(index + 1);\n }\n return this;\n }\n /**\n * Returns the previous event if there is one. null otherwise\n * @param event The event to find the previous one of\n * @return The event right before the given event\n */\n previousEvent(event) {\n const index = this._timeline.indexOf(event);\n if (index > 0) {\n return this._timeline[index - 1];\n }\n else {\n return null;\n }\n }\n /**\n * Does a binary search on the timeline array and returns the\n * nearest event index whose time is after or equal to the given time.\n * If a time is searched before the first index in the timeline, -1 is returned.\n * If the time is after the end, the index of the last item is returned.\n */\n _search(time, param = "time") {\n if (this._timeline.length === 0) {\n return -1;\n }\n let beginning = 0;\n const len = this._timeline.length;\n let end = len;\n if (len > 0 && this._timeline[len - 1][param] <= time) {\n return len - 1;\n }\n while (beginning < end) {\n // calculate the midpoint for roughly equal partition\n let midPoint = Math.floor(beginning + (end - beginning) / 2);\n const event = this._timeline[midPoint];\n const nextEvent = this._timeline[midPoint + 1];\n if (EQ(event[param], time)) {\n // choose the last one that has the same time\n for (let i = midPoint; i < this._timeline.length; i++) {\n const testEvent = this._timeline[i];\n if (EQ(testEvent[param], time)) {\n midPoint = i;\n }\n else {\n break;\n }\n }\n return midPoint;\n }\n else if (LT(event[param], time) && GT(nextEvent[param], time)) {\n return midPoint;\n }\n else if (GT(event[param], time)) {\n // search lower\n end = midPoint;\n }\n else {\n // search upper\n beginning = midPoint + 1;\n }\n }\n return -1;\n }\n /**\n * Internal iterator. Applies extra safety checks for\n * removing items from the array.\n */\n _iterate(callback, lowerBound = 0, upperBound = this._timeline.length - 1) {\n this._timeline.slice(lowerBound, upperBound + 1).forEach(callback);\n }\n /**\n * Iterate over everything in the array\n * @param callback The callback to invoke with every item\n */\n forEach(callback) {\n this._iterate(callback);\n return this;\n }\n /**\n * Iterate over everything in the array at or before the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachBefore(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const upperBound = this._search(time);\n if (upperBound !== -1) {\n this._iterate(callback, 0, upperBound);\n }\n return this;\n }\n /**\n * Iterate over everything in the array after the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachAfter(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const lowerBound = this._search(time);\n this._iterate(callback, lowerBound + 1);\n return this;\n }\n /**\n * Iterate over everything in the array between the startTime and endTime.\n * The timerange is inclusive of the startTime, but exclusive of the endTime.\n * range = [startTime, endTime).\n * @param startTime The time to check if items are before\n * @param endTime The end of the test interval.\n * @param callback The callback to invoke with every item\n */\n forEachBetween(startTime, endTime, callback) {\n let lowerBound = this._search(startTime);\n let upperBound = this._search(endTime);\n if (lowerBound !== -1 && upperBound !== -1) {\n if (this._timeline[lowerBound].time !== startTime) {\n lowerBound += 1;\n }\n // exclusive of the end time\n if (this._timeline[upperBound].time === endTime) {\n upperBound -= 1;\n }\n this._iterate(callback, lowerBound, upperBound);\n }\n else if (lowerBound === -1) {\n this._iterate(callback, 0, upperBound);\n }\n return this;\n }\n /**\n * Iterate over everything in the array at or after the given time. Similar to\n * forEachAfter, but includes the item(s) at the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachFrom(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n let lowerBound = this._search(time);\n // work backwards until the event time is less than time\n while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) {\n lowerBound--;\n }\n this._iterate(callback, lowerBound + 1);\n return this;\n }\n /**\n * Iterate over everything in the array at the given time\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachAtTime(time, callback) {\n // iterate over the items in reverse so that removing an item doesn\'t break things\n const upperBound = this._search(time);\n if (upperBound !== -1 && EQ(this._timeline[upperBound].time, time)) {\n let lowerBound = upperBound;\n for (let i = upperBound; i >= 0; i--) {\n if (EQ(this._timeline[i].time, time)) {\n lowerBound = i;\n }\n else {\n break;\n }\n }\n this._iterate(event => {\n callback(event);\n }, lowerBound, upperBound);\n }\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._timeline = [];\n return this;\n }\n}\n//# sourceMappingURL=Timeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ContextInitialization.js\n//-------------------------------------\n// INITIALIZING NEW CONTEXT\n//-------------------------------------\n/**\n * Array of callbacks to invoke when a new context is created\n */\nconst notifyNewContext = [];\n/**\n * Used internally to setup a new Context\n */\nfunction onContextInit(cb) {\n notifyNewContext.push(cb);\n}\n/**\n * Invoke any classes which need to also be initialized when a new context is created.\n */\nfunction initializeContext(ctx) {\n // add any additional modules\n notifyNewContext.forEach(cb => cb(ctx));\n}\n/**\n * Array of callbacks to invoke when a new context is created\n */\nconst notifyCloseContext = [];\n/**\n * Used internally to tear down a Context\n */\nfunction onContextClose(cb) {\n notifyCloseContext.push(cb);\n}\nfunction closeContext(ctx) {\n // add any additional modules\n notifyCloseContext.forEach(cb => cb(ctx));\n}\n//# sourceMappingURL=ContextInitialization.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Emitter.js\n\n\n/**\n * Emitter gives classes which extend it\n * the ability to listen for and emit events.\n * Inspiration and reference from Jerome Etienne\'s [MicroEvent](https://github.com/jeromeetienne/microevent.js).\n * MIT (c) 2011 Jerome Etienne.\n * @category Core\n */\nclass Emitter extends Tone {\n constructor() {\n super(...arguments);\n this.name = "Emitter";\n }\n /**\n * Bind a callback to a specific event.\n * @param event The name of the event to listen for.\n * @param callback The callback to invoke when the event is emitted\n */\n on(event, callback) {\n // split the event\n const events = event.split(/\\W+/);\n events.forEach(eventName => {\n if (TypeCheck_isUndef(this._events)) {\n this._events = {};\n }\n if (!this._events.hasOwnProperty(eventName)) {\n this._events[eventName] = [];\n }\n this._events[eventName].push(callback);\n });\n return this;\n }\n /**\n * Bind a callback which is only invoked once\n * @param event The name of the event to listen for.\n * @param callback The callback to invoke when the event is emitted\n */\n once(event, callback) {\n const boundCallback = (...args) => {\n // invoke the callback\n callback(...args);\n // remove the event\n this.off(event, boundCallback);\n };\n this.on(event, boundCallback);\n return this;\n }\n /**\n * Remove the event listener.\n * @param event The event to stop listening to.\n * @param callback The callback which was bound to the event with Emitter.on.\n * If no callback is given, all callbacks events are removed.\n */\n off(event, callback) {\n const events = event.split(/\\W+/);\n events.forEach(eventName => {\n if (TypeCheck_isUndef(this._events)) {\n this._events = {};\n }\n if (this._events.hasOwnProperty(event)) {\n if (TypeCheck_isUndef(callback)) {\n this._events[event] = [];\n }\n else {\n const eventList = this._events[event];\n for (let i = eventList.length - 1; i >= 0; i--) {\n if (eventList[i] === callback) {\n eventList.splice(i, 1);\n }\n }\n }\n }\n });\n return this;\n }\n /**\n * Invoke all of the callbacks bound to the event\n * with any arguments passed in.\n * @param event The name of the event.\n * @param args The arguments to pass to the functions listening.\n */\n emit(event, ...args) {\n if (this._events) {\n if (this._events.hasOwnProperty(event)) {\n const eventList = this._events[event].slice(0);\n for (let i = 0, len = eventList.length; i < len; i++) {\n eventList[i].apply(this, args);\n }\n }\n }\n return this;\n }\n /**\n * Add Emitter functions (on/off/emit) to the object\n */\n static mixin(constr) {\n // instance._events = {};\n ["on", "once", "off", "emit"].forEach(name => {\n const property = Object.getOwnPropertyDescriptor(Emitter.prototype, name);\n Object.defineProperty(constr.prototype, name, property);\n });\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._events = undefined;\n return this;\n }\n}\n//# sourceMappingURL=Emitter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/BaseContext.js\n\nclass BaseContext extends Emitter {\n constructor() {\n super(...arguments);\n this.isOffline = false;\n }\n /*\n * This is a placeholder so that JSON.stringify does not throw an error\n * This matches what JSON.stringify(audioContext) returns on a native\n * audioContext instance.\n */\n toJSON() {\n return {};\n }\n}\n//# sourceMappingURL=BaseContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Context.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Wrapper around the native AudioContext.\n * @category Core\n */\nclass Context extends BaseContext {\n constructor() {\n super();\n this.name = "Context";\n /**\n * An object containing all of the constants AudioBufferSourceNodes\n */\n this._constants = new Map();\n /**\n * All of the setTimeout events.\n */\n this._timeouts = new Timeline();\n /**\n * The timeout id counter\n */\n this._timeoutIds = 0;\n /**\n * Private indicator if the context has been initialized\n */\n this._initialized = false;\n /**\n * Indicates if the context is an OfflineAudioContext or an AudioContext\n */\n this.isOffline = false;\n //--------------------------------------------\n // AUDIO WORKLET\n //--------------------------------------------\n /**\n * Maps a module name to promise of the addModule method\n */\n this._workletModules = new Map();\n const options = Defaults_optionsFromArguments(Context.getDefaults(), arguments, [\n "context",\n ]);\n if (options.context) {\n this._context = options.context;\n }\n else {\n this._context = createAudioContext({\n latencyHint: options.latencyHint,\n });\n }\n this._ticker = new Ticker(this.emit.bind(this, "tick"), options.clockSource, options.updateInterval);\n this.on("tick", this._timeoutLoop.bind(this));\n // fwd events from the context\n this._context.onstatechange = () => {\n this.emit("statechange", this.state);\n };\n this._setLatencyHint(options.latencyHint);\n this.lookAhead = options.lookAhead;\n }\n static getDefaults() {\n return {\n clockSource: "worker",\n latencyHint: "interactive",\n lookAhead: 0.1,\n updateInterval: 0.05,\n };\n }\n /**\n * Finish setting up the context. **You usually do not need to do this manually.**\n */\n initialize() {\n if (!this._initialized) {\n // add any additional modules\n initializeContext(this);\n this._initialized = true;\n }\n return this;\n }\n //---------------------------\n // BASE AUDIO CONTEXT METHODS\n //---------------------------\n createAnalyser() {\n return this._context.createAnalyser();\n }\n createOscillator() {\n return this._context.createOscillator();\n }\n createBufferSource() {\n return this._context.createBufferSource();\n }\n createBiquadFilter() {\n return this._context.createBiquadFilter();\n }\n createBuffer(numberOfChannels, length, sampleRate) {\n return this._context.createBuffer(numberOfChannels, length, sampleRate);\n }\n createChannelMerger(numberOfInputs) {\n return this._context.createChannelMerger(numberOfInputs);\n }\n createChannelSplitter(numberOfOutputs) {\n return this._context.createChannelSplitter(numberOfOutputs);\n }\n createConstantSource() {\n return this._context.createConstantSource();\n }\n createConvolver() {\n return this._context.createConvolver();\n }\n createDelay(maxDelayTime) {\n return this._context.createDelay(maxDelayTime);\n }\n createDynamicsCompressor() {\n return this._context.createDynamicsCompressor();\n }\n createGain() {\n return this._context.createGain();\n }\n createIIRFilter(feedForward, feedback) {\n // @ts-ignore\n return this._context.createIIRFilter(feedForward, feedback);\n }\n createPanner() {\n return this._context.createPanner();\n }\n createPeriodicWave(real, imag, constraints) {\n return this._context.createPeriodicWave(real, imag, constraints);\n }\n createStereoPanner() {\n return this._context.createStereoPanner();\n }\n createWaveShaper() {\n return this._context.createWaveShaper();\n }\n createMediaStreamSource(stream) {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaStreamSource(stream);\n }\n createMediaElementSource(element) {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaElementSource(element);\n }\n createMediaStreamDestination() {\n Debug_assert(isAudioContext(this._context), "Not available if OfflineAudioContext");\n const context = this._context;\n return context.createMediaStreamDestination();\n }\n decodeAudioData(audioData) {\n return this._context.decodeAudioData(audioData);\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get currentTime() {\n return this._context.currentTime;\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get state() {\n return this._context.state;\n }\n /**\n * The current time in seconds of the AudioContext.\n */\n get sampleRate() {\n return this._context.sampleRate;\n }\n /**\n * The listener\n */\n get listener() {\n this.initialize();\n return this._listener;\n }\n set listener(l) {\n Debug_assert(!this._initialized, "The listener cannot be set after initialization.");\n this._listener = l;\n }\n /**\n * There is only one Transport per Context. It is created on initialization.\n */\n get transport() {\n this.initialize();\n return this._transport;\n }\n set transport(t) {\n Debug_assert(!this._initialized, "The transport cannot be set after initialization.");\n this._transport = t;\n }\n /**\n * This is the Draw object for the context which is useful for synchronizing the draw frame with the Tone.js clock.\n */\n get draw() {\n this.initialize();\n return this._draw;\n }\n set draw(d) {\n Debug_assert(!this._initialized, "Draw cannot be set after initialization.");\n this._draw = d;\n }\n /**\n * A reference to the Context\'s destination node.\n */\n get destination() {\n this.initialize();\n return this._destination;\n }\n set destination(d) {\n Debug_assert(!this._initialized, "The destination cannot be set after initialization.");\n this._destination = d;\n }\n /**\n * Create an audio worklet node from a name and options. The module\n * must first be loaded using [[addAudioWorkletModule]].\n */\n createAudioWorkletNode(name, options) {\n return createAudioWorkletNode(this.rawContext, name, options);\n }\n /**\n * Add an AudioWorkletProcessor module\n * @param url The url of the module\n * @param name The name of the module\n */\n addAudioWorkletModule(url, name) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n Debug_assert(TypeCheck_isDefined(this.rawContext.audioWorklet), "AudioWorkletNode is only available in a secure context (https or localhost)");\n if (!this._workletModules.has(name)) {\n this._workletModules.set(name, this.rawContext.audioWorklet.addModule(url));\n }\n yield this._workletModules.get(name);\n });\n }\n /**\n * Returns a promise which resolves when all of the worklets have been loaded on this context\n */\n workletsAreReady() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const promises = [];\n this._workletModules.forEach((promise) => promises.push(promise));\n yield Promise.all(promises);\n });\n }\n //---------------------------\n // TICKER\n //---------------------------\n /**\n * How often the interval callback is invoked.\n * This number corresponds to how responsive the scheduling\n * can be. context.updateInterval + context.lookAhead gives you the\n * total latency between scheduling an event and hearing it.\n */\n get updateInterval() {\n return this._ticker.updateInterval;\n }\n set updateInterval(interval) {\n this._ticker.updateInterval = interval;\n }\n /**\n * What the source of the clock is, either "worker" (default),\n * "timeout", or "offline" (none).\n */\n get clockSource() {\n return this._ticker.type;\n }\n set clockSource(type) {\n this._ticker.type = type;\n }\n /**\n * The type of playback, which affects tradeoffs between audio\n * output latency and responsiveness.\n * In addition to setting the value in seconds, the latencyHint also\n * accepts the strings "interactive" (prioritizes low latency),\n * "playback" (prioritizes sustained playback), "balanced" (balances\n * latency and performance).\n * @example\n * // prioritize sustained playback\n * const context = new Tone.Context({ latencyHint: "playback" });\n * // set this context as the global Context\n * Tone.setContext(context);\n * // the global context is gettable with Tone.getContext()\n * console.log(Tone.getContext().latencyHint);\n */\n get latencyHint() {\n return this._latencyHint;\n }\n /**\n * Update the lookAhead and updateInterval based on the latencyHint\n */\n _setLatencyHint(hint) {\n let lookAheadValue = 0;\n this._latencyHint = hint;\n if (TypeCheck_isString(hint)) {\n switch (hint) {\n case "interactive":\n lookAheadValue = 0.1;\n break;\n case "playback":\n lookAheadValue = 0.5;\n break;\n case "balanced":\n lookAheadValue = 0.25;\n break;\n }\n }\n this.lookAhead = lookAheadValue;\n this.updateInterval = lookAheadValue / 2;\n }\n /**\n * The unwrapped AudioContext or OfflineAudioContext\n */\n get rawContext() {\n return this._context;\n }\n /**\n * The current audio context time plus a short [[lookAhead]].\n */\n now() {\n return this._context.currentTime + this.lookAhead;\n }\n /**\n * The current audio context time without the [[lookAhead]].\n * In most cases it is better to use [[now]] instead of [[immediate]] since\n * with [[now]] the [[lookAhead]] is applied equally to _all_ components including internal components,\n * to making sure that everything is scheduled in sync. Mixing [[now]] and [[immediate]]\n * can cause some timing issues. If no lookAhead is desired, you can set the [[lookAhead]] to `0`.\n */\n immediate() {\n return this._context.currentTime;\n }\n /**\n * Starts the audio context from a suspended state. This is required\n * to initially start the AudioContext. See [[Tone.start]]\n */\n resume() {\n if (isAudioContext(this._context)) {\n return this._context.resume();\n }\n else {\n return Promise.resolve();\n }\n }\n /**\n * Close the context. Once closed, the context can no longer be used and\n * any AudioNodes created from the context will be silent.\n */\n close() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n if (isAudioContext(this._context)) {\n yield this._context.close();\n }\n if (this._initialized) {\n closeContext(this);\n }\n });\n }\n /**\n * **Internal** Generate a looped buffer at some constant value.\n */\n getConstant(val) {\n if (this._constants.has(val)) {\n return this._constants.get(val);\n }\n else {\n const buffer = this._context.createBuffer(1, 128, this._context.sampleRate);\n const arr = buffer.getChannelData(0);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = val;\n }\n const constant = this._context.createBufferSource();\n constant.channelCount = 1;\n constant.channelCountMode = "explicit";\n constant.buffer = buffer;\n constant.loop = true;\n constant.start(0);\n this._constants.set(val, constant);\n return constant;\n }\n }\n /**\n * Clean up. Also closes the audio context.\n */\n dispose() {\n super.dispose();\n this._ticker.dispose();\n this._timeouts.dispose();\n Object.keys(this._constants).map((val) => this._constants[val].disconnect());\n return this;\n }\n //---------------------------\n // TIMEOUTS\n //---------------------------\n /**\n * The private loop which keeps track of the context scheduled timeouts\n * Is invoked from the clock source\n */\n _timeoutLoop() {\n const now = this.now();\n let firstEvent = this._timeouts.peek();\n while (this._timeouts.length && firstEvent && firstEvent.time <= now) {\n // invoke the callback\n firstEvent.callback();\n // shift the first event off\n this._timeouts.shift();\n // get the next one\n firstEvent = this._timeouts.peek();\n }\n }\n /**\n * A setTimeout which is guaranteed by the clock source.\n * Also runs in the offline context.\n * @param fn The callback to invoke\n * @param timeout The timeout in seconds\n * @returns ID to use when invoking Context.clearTimeout\n */\n setTimeout(fn, timeout) {\n this._timeoutIds++;\n const now = this.now();\n this._timeouts.add({\n callback: fn,\n id: this._timeoutIds,\n time: now + timeout,\n });\n return this._timeoutIds;\n }\n /**\n * Clears a previously scheduled timeout with Tone.context.setTimeout\n * @param id The ID returned from setTimeout\n */\n clearTimeout(id) {\n this._timeouts.forEach((event) => {\n if (event.id === id) {\n this._timeouts.remove(event);\n }\n });\n return this;\n }\n /**\n * Clear the function scheduled by [[setInterval]]\n */\n clearInterval(id) {\n return this.clearTimeout(id);\n }\n /**\n * Adds a repeating event to the context\'s callback clock\n */\n setInterval(fn, interval) {\n const id = ++this._timeoutIds;\n const intervalFn = () => {\n const now = this.now();\n this._timeouts.add({\n callback: () => {\n // invoke the callback\n fn();\n // invoke the event to repeat it\n intervalFn();\n },\n id,\n time: now + interval,\n });\n };\n // kick it off\n intervalFn();\n return id;\n }\n}\n//# sourceMappingURL=Context.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/DummyContext.js\n\n\nclass DummyContext extends BaseContext {\n constructor() {\n super(...arguments);\n this.lookAhead = 0;\n this.latencyHint = 0;\n this.isOffline = false;\n }\n //---------------------------\n // BASE AUDIO CONTEXT METHODS\n //---------------------------\n createAnalyser() {\n return {};\n }\n createOscillator() {\n return {};\n }\n createBufferSource() {\n return {};\n }\n createBiquadFilter() {\n return {};\n }\n createBuffer(_numberOfChannels, _length, _sampleRate) {\n return {};\n }\n createChannelMerger(_numberOfInputs) {\n return {};\n }\n createChannelSplitter(_numberOfOutputs) {\n return {};\n }\n createConstantSource() {\n return {};\n }\n createConvolver() {\n return {};\n }\n createDelay(_maxDelayTime) {\n return {};\n }\n createDynamicsCompressor() {\n return {};\n }\n createGain() {\n return {};\n }\n createIIRFilter(_feedForward, _feedback) {\n return {};\n }\n createPanner() {\n return {};\n }\n createPeriodicWave(_real, _imag, _constraints) {\n return {};\n }\n createStereoPanner() {\n return {};\n }\n createWaveShaper() {\n return {};\n }\n createMediaStreamSource(_stream) {\n return {};\n }\n createMediaElementSource(_element) {\n return {};\n }\n createMediaStreamDestination() {\n return {};\n }\n decodeAudioData(_audioData) {\n return Promise.resolve({});\n }\n //---------------------------\n // TONE AUDIO CONTEXT METHODS\n //---------------------------\n createAudioWorkletNode(_name, _options) {\n return {};\n }\n get rawContext() {\n return {};\n }\n addAudioWorkletModule(_url, _name) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return Promise.resolve();\n });\n }\n resume() {\n return Promise.resolve();\n }\n setTimeout(_fn, _timeout) {\n return 0;\n }\n clearTimeout(_id) {\n return this;\n }\n setInterval(_fn, _interval) {\n return 0;\n }\n clearInterval(_id) {\n return this;\n }\n getConstant(_val) {\n return {};\n }\n get currentTime() {\n return 0;\n }\n get state() {\n return {};\n }\n get sampleRate() {\n return 0;\n }\n get listener() {\n return {};\n }\n get transport() {\n return {};\n }\n get draw() {\n return {};\n }\n set draw(_d) { }\n get destination() {\n return {};\n }\n set destination(_d) { }\n now() {\n return 0;\n }\n immediate() {\n return 0;\n }\n}\n//# sourceMappingURL=DummyContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Interface.js\n\n/**\n * Make the property not writable using `defineProperty`. Internal use only.\n */\nfunction Interface_readOnly(target, property) {\n if (TypeCheck_isArray(property)) {\n property.forEach(str => Interface_readOnly(target, str));\n }\n else {\n Object.defineProperty(target, property, {\n enumerable: true,\n writable: false,\n });\n }\n}\n/**\n * Make an attribute writeable. Internal use only.\n */\nfunction Interface_writable(target, property) {\n if (TypeCheck_isArray(property)) {\n property.forEach(str => Interface_writable(target, str));\n }\n else {\n Object.defineProperty(target, property, {\n writable: true,\n });\n }\n}\nconst Interface_noOp = () => {\n // no operation here!\n};\n//# sourceMappingURL=Interface.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioBuffer.js\n\n\n\n\n\n\n\n\n/**\n * AudioBuffer loading and storage. ToneAudioBuffer is used internally by all\n * classes that make requests for audio files such as Tone.Player,\n * Tone.Sampler and Tone.Convolver.\n * @example\n * const buffer = new Tone.ToneAudioBuffer("https://tonejs.github.io/audio/casio/A1.mp3", () => {\n * \tconsole.log("loaded");\n * });\n * @category Core\n */\nclass ToneAudioBuffer_ToneAudioBuffer extends Tone {\n constructor() {\n super();\n this.name = "ToneAudioBuffer";\n /**\n * Callback when the buffer is loaded.\n */\n this.onload = Interface_noOp;\n const options = Defaults_optionsFromArguments(ToneAudioBuffer_ToneAudioBuffer.getDefaults(), arguments, ["url", "onload", "onerror"]);\n this.reverse = options.reverse;\n this.onload = options.onload;\n if (options.url && isAudioBuffer(options.url) || options.url instanceof ToneAudioBuffer_ToneAudioBuffer) {\n this.set(options.url);\n }\n else if (TypeCheck_isString(options.url)) {\n // initiate the download\n this.load(options.url).catch(options.onerror);\n }\n }\n static getDefaults() {\n return {\n onerror: Interface_noOp,\n onload: Interface_noOp,\n reverse: false,\n };\n }\n /**\n * The sample rate of the AudioBuffer\n */\n get sampleRate() {\n if (this._buffer) {\n return this._buffer.sampleRate;\n }\n else {\n return Global_getContext().sampleRate;\n }\n }\n /**\n * Pass in an AudioBuffer or ToneAudioBuffer to set the value of this buffer.\n */\n set(buffer) {\n if (buffer instanceof ToneAudioBuffer_ToneAudioBuffer) {\n // if it\'s loaded, set it\n if (buffer.loaded) {\n this._buffer = buffer.get();\n }\n else {\n // otherwise when it\'s loaded, invoke it\'s callback\n buffer.onload = () => {\n this.set(buffer);\n this.onload(this);\n };\n }\n }\n else {\n this._buffer = buffer;\n }\n // reverse it initially\n if (this._reversed) {\n this._reverse();\n }\n return this;\n }\n /**\n * The audio buffer stored in the object.\n */\n get() {\n return this._buffer;\n }\n /**\n * Makes an fetch request for the selected url then decodes the file as an audio buffer.\n * Invokes the callback once the audio buffer loads.\n * @param url The url of the buffer to load. filetype support depends on the browser.\n * @returns A Promise which resolves with this ToneAudioBuffer\n */\n load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const doneLoading = ToneAudioBuffer_ToneAudioBuffer.load(url).then(audioBuffer => {\n this.set(audioBuffer);\n // invoke the onload method\n this.onload(this);\n });\n ToneAudioBuffer_ToneAudioBuffer.downloads.push(doneLoading);\n try {\n yield doneLoading;\n }\n finally {\n // remove the downloaded file\n const index = ToneAudioBuffer_ToneAudioBuffer.downloads.indexOf(doneLoading);\n ToneAudioBuffer_ToneAudioBuffer.downloads.splice(index, 1);\n }\n return this;\n });\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._buffer = undefined;\n return this;\n }\n /**\n * Set the audio buffer from the array.\n * To create a multichannel AudioBuffer, pass in a multidimensional array.\n * @param array The array to fill the audio buffer\n */\n fromArray(array) {\n const isMultidimensional = TypeCheck_isArray(array) && array[0].length > 0;\n const channels = isMultidimensional ? array.length : 1;\n const len = isMultidimensional ? array[0].length : array.length;\n const context = Global_getContext();\n const buffer = context.createBuffer(channels, len, context.sampleRate);\n const multiChannelArray = !isMultidimensional && channels === 1 ?\n [array] : array;\n for (let c = 0; c < channels; c++) {\n buffer.copyToChannel(multiChannelArray[c], c);\n }\n this._buffer = buffer;\n return this;\n }\n /**\n * Sums multiple channels into 1 channel\n * @param chanNum Optionally only copy a single channel from the array.\n */\n toMono(chanNum) {\n if (TypeCheck_isNumber(chanNum)) {\n this.fromArray(this.toArray(chanNum));\n }\n else {\n let outputArray = new Float32Array(this.length);\n const numChannels = this.numberOfChannels;\n for (let channel = 0; channel < numChannels; channel++) {\n const channelArray = this.toArray(channel);\n for (let i = 0; i < channelArray.length; i++) {\n outputArray[i] += channelArray[i];\n }\n }\n // divide by the number of channels\n outputArray = outputArray.map(sample => sample / numChannels);\n this.fromArray(outputArray);\n }\n return this;\n }\n /**\n * Get the buffer as an array. Single channel buffers will return a 1-dimensional\n * Float32Array, and multichannel buffers will return multidimensional arrays.\n * @param channel Optionally only copy a single channel from the array.\n */\n toArray(channel) {\n if (TypeCheck_isNumber(channel)) {\n return this.getChannelData(channel);\n }\n else if (this.numberOfChannels === 1) {\n return this.toArray(0);\n }\n else {\n const ret = [];\n for (let c = 0; c < this.numberOfChannels; c++) {\n ret[c] = this.getChannelData(c);\n }\n return ret;\n }\n }\n /**\n * Returns the Float32Array representing the PCM audio data for the specific channel.\n * @param channel The channel number to return\n * @return The audio as a TypedArray\n */\n getChannelData(channel) {\n if (this._buffer) {\n return this._buffer.getChannelData(channel);\n }\n else {\n return new Float32Array(0);\n }\n }\n /**\n * Cut a subsection of the array and return a buffer of the\n * subsection. Does not modify the original buffer\n * @param start The time to start the slice\n * @param end The end time to slice. If none is given will default to the end of the buffer\n */\n slice(start, end = this.duration) {\n const startSamples = Math.floor(start * this.sampleRate);\n const endSamples = Math.floor(end * this.sampleRate);\n Debug_assert(startSamples < endSamples, "The start time must be less than the end time");\n const length = endSamples - startSamples;\n const retBuffer = Global_getContext().createBuffer(this.numberOfChannels, length, this.sampleRate);\n for (let channel = 0; channel < this.numberOfChannels; channel++) {\n retBuffer.copyToChannel(this.getChannelData(channel).subarray(startSamples, endSamples), channel);\n }\n return new ToneAudioBuffer_ToneAudioBuffer(retBuffer);\n }\n /**\n * Reverse the buffer.\n */\n _reverse() {\n if (this.loaded) {\n for (let i = 0; i < this.numberOfChannels; i++) {\n this.getChannelData(i).reverse();\n }\n }\n return this;\n }\n /**\n * If the buffer is loaded or not\n */\n get loaded() {\n return this.length > 0;\n }\n /**\n * The duration of the buffer in seconds.\n */\n get duration() {\n if (this._buffer) {\n return this._buffer.duration;\n }\n else {\n return 0;\n }\n }\n /**\n * The length of the buffer in samples\n */\n get length() {\n if (this._buffer) {\n return this._buffer.length;\n }\n else {\n return 0;\n }\n }\n /**\n * The number of discrete audio channels. Returns 0 if no buffer is loaded.\n */\n get numberOfChannels() {\n if (this._buffer) {\n return this._buffer.numberOfChannels;\n }\n else {\n return 0;\n }\n }\n /**\n * Reverse the buffer.\n */\n get reverse() {\n return this._reversed;\n }\n set reverse(rev) {\n if (this._reversed !== rev) {\n this._reversed = rev;\n this._reverse();\n }\n }\n /**\n * Create a ToneAudioBuffer from the array. To create a multichannel AudioBuffer,\n * pass in a multidimensional array.\n * @param array The array to fill the audio buffer\n * @return A ToneAudioBuffer created from the array\n */\n static fromArray(array) {\n return (new ToneAudioBuffer_ToneAudioBuffer()).fromArray(array);\n }\n /**\n * Creates a ToneAudioBuffer from a URL, returns a promise which resolves to a ToneAudioBuffer\n * @param url The url to load.\n * @return A promise which resolves to a ToneAudioBuffer\n */\n static fromUrl(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const buffer = new ToneAudioBuffer_ToneAudioBuffer();\n return yield buffer.load(url);\n });\n }\n /**\n * Loads a url using fetch and returns the AudioBuffer.\n */\n static load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n // test if the url contains multiple extensions\n const matches = url.match(/\\[([^\\]\\[]+\\|.+)\\]$/);\n if (matches) {\n const extensions = matches[1].split("|");\n let extension = extensions[0];\n for (const ext of extensions) {\n if (ToneAudioBuffer_ToneAudioBuffer.supportsType(ext)) {\n extension = ext;\n break;\n }\n }\n url = url.replace(matches[0], extension);\n }\n // make sure there is a slash between the baseUrl and the url\n const baseUrl = ToneAudioBuffer_ToneAudioBuffer.baseUrl === "" || ToneAudioBuffer_ToneAudioBuffer.baseUrl.endsWith("/") ? ToneAudioBuffer_ToneAudioBuffer.baseUrl : ToneAudioBuffer_ToneAudioBuffer.baseUrl + "/";\n const response = yield fetch(baseUrl + url);\n if (!response.ok) {\n throw new Error(`could not load url: ${url}`);\n }\n const arrayBuffer = yield response.arrayBuffer();\n const audioBuffer = yield Global_getContext().decodeAudioData(arrayBuffer);\n return audioBuffer;\n });\n }\n /**\n * Checks a url\'s extension to see if the current browser can play that file type.\n * @param url The url/extension to test\n * @return If the file extension can be played\n * @static\n * @example\n * Tone.ToneAudioBuffer.supportsType("wav"); // returns true\n * Tone.ToneAudioBuffer.supportsType("path/to/file.wav"); // returns true\n */\n static supportsType(url) {\n const extensions = url.split(".");\n const extension = extensions[extensions.length - 1];\n const response = document.createElement("audio").canPlayType("audio/" + extension);\n return response !== "";\n }\n /**\n * Returns a Promise which resolves when all of the buffers have loaded\n */\n static loaded() {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n // this makes sure that the function is always async\n yield Promise.resolve();\n while (ToneAudioBuffer_ToneAudioBuffer.downloads.length) {\n yield ToneAudioBuffer_ToneAudioBuffer.downloads[0];\n }\n });\n }\n}\n//-------------------------------------\n// STATIC METHODS\n//-------------------------------------\n/**\n * A path which is prefixed before every url.\n */\nToneAudioBuffer_ToneAudioBuffer.baseUrl = "";\n/**\n * All of the downloads\n */\nToneAudioBuffer_ToneAudioBuffer.downloads = [];\n//# sourceMappingURL=ToneAudioBuffer.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/OfflineContext.js\n\n\n\n\n\n/**\n * Wrapper around the OfflineAudioContext\n * @category Core\n * @example\n * // generate a single channel, 0.5 second buffer\n * const context = new Tone.OfflineContext(1, 0.5, 44100);\n * const osc = new Tone.Oscillator({ context });\n * context.render().then(buffer => {\n * \tconsole.log(buffer.numberOfChannels, buffer.duration);\n * });\n */\nclass OfflineContext_OfflineContext extends Context {\n constructor() {\n super({\n clockSource: "offline",\n context: isOfflineAudioContext(arguments[0]) ?\n arguments[0] : createOfflineAudioContext(arguments[0], arguments[1] * arguments[2], arguments[2]),\n lookAhead: 0,\n updateInterval: isOfflineAudioContext(arguments[0]) ?\n 128 / arguments[0].sampleRate : 128 / arguments[2],\n });\n this.name = "OfflineContext";\n /**\n * An artificial clock source\n */\n this._currentTime = 0;\n this.isOffline = true;\n this._duration = isOfflineAudioContext(arguments[0]) ?\n arguments[0].length / arguments[0].sampleRate : arguments[1];\n }\n /**\n * Override the now method to point to the internal clock time\n */\n now() {\n return this._currentTime;\n }\n /**\n * Same as this.now()\n */\n get currentTime() {\n return this._currentTime;\n }\n /**\n * Render just the clock portion of the audio context.\n */\n _renderClock(asynchronous) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n let index = 0;\n while (this._duration - this._currentTime >= 0) {\n // invoke all the callbacks on that time\n this.emit("tick");\n // increment the clock in block-sized chunks\n this._currentTime += 128 / this.sampleRate;\n // yield once a second of audio\n index++;\n const yieldEvery = Math.floor(this.sampleRate / 128);\n if (asynchronous && index % yieldEvery === 0) {\n yield new Promise(done => setTimeout(done, 1));\n }\n }\n });\n }\n /**\n * Render the output of the OfflineContext\n * @param asynchronous If the clock should be rendered asynchronously, which will not block the main thread, but be slightly slower.\n */\n render(asynchronous = true) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n yield this.workletsAreReady();\n yield this._renderClock(asynchronous);\n const buffer = yield this._context.startRendering();\n return new ToneAudioBuffer_ToneAudioBuffer(buffer);\n });\n }\n /**\n * Close the context\n */\n close() {\n return Promise.resolve();\n }\n}\n//# sourceMappingURL=OfflineContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/Global.js\n\n\n\n\n\n\n/**\n * This dummy context is used to avoid throwing immediate errors when importing in Node.js\n */\nconst dummyContext = new DummyContext();\n/**\n * The global audio context which is getable and assignable through\n * getContext and setContext\n */\nlet globalContext = dummyContext;\n/**\n * Returns the default system-wide [[Context]]\n * @category Core\n */\nfunction Global_getContext() {\n if (globalContext === dummyContext && hasAudioContext) {\n Global_setContext(new Context());\n }\n return globalContext;\n}\n/**\n * Set the default audio context\n * @category Core\n */\nfunction Global_setContext(context) {\n if (isAudioContext(context)) {\n globalContext = new Context(context);\n }\n else if (isOfflineAudioContext(context)) {\n globalContext = new OfflineContext_OfflineContext(context);\n }\n else {\n globalContext = context;\n }\n}\n/**\n * Most browsers will not play _any_ audio until a user\n * clicks something (like a play button). Invoke this method\n * on a click or keypress event handler to start the audio context.\n * More about the Autoplay policy\n * [here](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#webaudio)\n * @example\n * document.querySelector("button").addEventListener("click", async () => {\n * \tawait Tone.start();\n * \tconsole.log("context started");\n * });\n * @category Core\n */\nfunction start() {\n return globalContext.resume();\n}\n/**\n * Log Tone.js + version in the console.\n */\nif (AudioContext_theWindow && !AudioContext_theWindow.TONE_SILENCE_LOGGING) {\n let prefix = "v";\n if (version === "dev") {\n prefix = "";\n }\n const printString = ` * Tone.js ${prefix}${version} * `;\n // eslint-disable-next-line no-console\n console.log(`%c${printString}`, "background: #000; color: #fff");\n}\n//# sourceMappingURL=Global.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Conversions.js\n/**\n * Equal power gain scale. Good for cross-fading.\n * @param percent (0-1)\n */\nfunction equalPowerScale(percent) {\n const piFactor = 0.5 * Math.PI;\n return Math.sin(percent * piFactor);\n}\n/**\n * Convert decibels into gain.\n */\nfunction Conversions_dbToGain(db) {\n return Math.pow(10, db / 20);\n}\n/**\n * Convert gain to decibels.\n */\nfunction Conversions_gainToDb(gain) {\n return 20 * (Math.log(gain) / Math.LN10);\n}\n/**\n * Convert an interval (in semitones) to a frequency ratio.\n * @param interval the number of semitones above the base note\n * @example\n * Tone.intervalToFrequencyRatio(0); // 1\n * Tone.intervalToFrequencyRatio(12); // 2\n * Tone.intervalToFrequencyRatio(-12); // 0.5\n */\nfunction Conversions_intervalToFrequencyRatio(interval) {\n return Math.pow(2, (interval / 12));\n}\n/**\n * The Global [concert tuning pitch](https://en.wikipedia.org/wiki/Concert_pitch) which is used\n * to generate all the other pitch values from notes. A4\'s values in Hertz.\n */\nlet A4 = 440;\nfunction getA4() {\n return A4;\n}\nfunction setA4(freq) {\n A4 = freq;\n}\n/**\n * Convert a frequency value to a MIDI note.\n * @param frequency The value to frequency value to convert.\n * @example\n * Tone.ftom(440); // returns 69\n */\nfunction Conversions_ftom(frequency) {\n return Math.round(ftomf(frequency));\n}\n/**\n * Convert a frequency to a floating point midi value\n */\nfunction ftomf(frequency) {\n return 69 + 12 * Math.log2(frequency / A4);\n}\n/**\n * Convert a MIDI note to frequency value.\n * @param midi The midi number to convert.\n * @return The corresponding frequency value\n * @example\n * Tone.mtof(69); // 440\n */\nfunction Conversions_mtof(midi) {\n return A4 * Math.pow(2, (midi - 69) / 12);\n}\n//# sourceMappingURL=Conversions.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/TimeBase.js\n\n\n/**\n * TimeBase is a flexible encoding of time which can be evaluated to and from a string.\n */\nclass TimeBaseClass extends Tone {\n /**\n * @param context The context associated with the time value. Used to compute\n * Transport and context-relative timing.\n * @param value The time value as a number, string or object\n * @param units Unit values\n */\n constructor(context, value, units) {\n super();\n /**\n * The default units\n */\n this.defaultUnits = "s";\n this._val = value;\n this._units = units;\n this.context = context;\n this._expressions = this._getExpressions();\n }\n /**\n * All of the time encoding expressions\n */\n _getExpressions() {\n return {\n hz: {\n method: (value) => {\n return this._frequencyToUnits(parseFloat(value));\n },\n regexp: /^(\\d+(?:\\.\\d+)?)hz$/i,\n },\n i: {\n method: (value) => {\n return this._ticksToUnits(parseInt(value, 10));\n },\n regexp: /^(\\d+)i$/i,\n },\n m: {\n method: (value) => {\n return this._beatsToUnits(parseInt(value, 10) * this._getTimeSignature());\n },\n regexp: /^(\\d+)m$/i,\n },\n n: {\n method: (value, dot) => {\n const numericValue = parseInt(value, 10);\n const scalar = dot === "." ? 1.5 : 1;\n if (numericValue === 1) {\n return this._beatsToUnits(this._getTimeSignature()) * scalar;\n }\n else {\n return this._beatsToUnits(4 / numericValue) * scalar;\n }\n },\n regexp: /^(\\d+)n(\\.?)$/i,\n },\n number: {\n method: (value) => {\n return this._expressions[this.defaultUnits].method.call(this, value);\n },\n regexp: /^(\\d+(?:\\.\\d+)?)$/,\n },\n s: {\n method: (value) => {\n return this._secondsToUnits(parseFloat(value));\n },\n regexp: /^(\\d+(?:\\.\\d+)?)s$/,\n },\n samples: {\n method: (value) => {\n return parseInt(value, 10) / this.context.sampleRate;\n },\n regexp: /^(\\d+)samples$/,\n },\n t: {\n method: (value) => {\n const numericValue = parseInt(value, 10);\n return this._beatsToUnits(8 / (Math.floor(numericValue) * 3));\n },\n regexp: /^(\\d+)t$/i,\n },\n tr: {\n method: (m, q, s) => {\n let total = 0;\n if (m && m !== "0") {\n total += this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n }\n if (q && q !== "0") {\n total += this._beatsToUnits(parseFloat(q));\n }\n if (s && s !== "0") {\n total += this._beatsToUnits(parseFloat(s) / 4);\n }\n return total;\n },\n regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?$/,\n },\n };\n }\n //-------------------------------------\n // \tVALUE OF\n //-------------------------------------\n /**\n * Evaluate the time value. Returns the time in seconds.\n */\n valueOf() {\n if (this._val instanceof TimeBaseClass) {\n this.fromType(this._val);\n }\n if (TypeCheck_isUndef(this._val)) {\n return this._noArg();\n }\n else if (TypeCheck_isString(this._val) && TypeCheck_isUndef(this._units)) {\n for (const units in this._expressions) {\n if (this._expressions[units].regexp.test(this._val.trim())) {\n this._units = units;\n break;\n }\n }\n }\n else if (TypeCheck_isObject(this._val)) {\n let total = 0;\n for (const typeName in this._val) {\n if (TypeCheck_isDefined(this._val[typeName])) {\n const quantity = this._val[typeName];\n // @ts-ignore\n const time = (new this.constructor(this.context, typeName)).valueOf() * quantity;\n total += time;\n }\n }\n return total;\n }\n if (TypeCheck_isDefined(this._units)) {\n const expr = this._expressions[this._units];\n const matching = this._val.toString().trim().match(expr.regexp);\n if (matching) {\n return expr.method.apply(this, matching.slice(1));\n }\n else {\n return expr.method.call(this, this._val);\n }\n }\n else if (TypeCheck_isString(this._val)) {\n return parseFloat(this._val);\n }\n else {\n return this._val;\n }\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS\n //-------------------------------------\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return 1 / freq;\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return (60 / this._getBpm()) * beats;\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return seconds;\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return (ticks * (this._beatsToUnits(1)) / this._getPPQ());\n }\n /**\n * With no arguments, return \'now\'\n */\n _noArg() {\n return this._now();\n }\n //-------------------------------------\n // \tTEMPO CONVERSIONS\n //-------------------------------------\n /**\n * Return the bpm\n */\n _getBpm() {\n return this.context.transport.bpm.value;\n }\n /**\n * Return the timeSignature\n */\n _getTimeSignature() {\n return this.context.transport.timeSignature;\n }\n /**\n * Return the PPQ or 192 if Transport is not available\n */\n _getPPQ() {\n return this.context.transport.PPQ;\n }\n //-------------------------------------\n // \tCONVERSION INTERFACE\n //-------------------------------------\n /**\n * Coerce a time type into this units type.\n * @param type Any time type units\n */\n fromType(type) {\n this._units = undefined;\n switch (this.defaultUnits) {\n case "s":\n this._val = type.toSeconds();\n break;\n case "i":\n this._val = type.toTicks();\n break;\n case "hz":\n this._val = type.toFrequency();\n break;\n case "midi":\n this._val = type.toMidi();\n break;\n }\n return this;\n }\n /**\n * Return the value in hertz\n */\n toFrequency() {\n return 1 / this.toSeconds();\n }\n /**\n * Return the time in samples\n */\n toSamples() {\n return this.toSeconds() * this.context.sampleRate;\n }\n /**\n * Return the time in milliseconds.\n */\n toMilliseconds() {\n return this.toSeconds() * 1000;\n }\n}\n//# sourceMappingURL=TimeBase.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Time.js\n\n\n\n/**\n * TimeClass is a primitive type for encoding and decoding Time values.\n * TimeClass can be passed into the parameter of any method which takes time as an argument.\n * @param val The time value.\n * @param units The units of the value.\n * @example\n * const time = Tone.Time("4n"); // a quarter note\n * @category Unit\n */\nclass TimeClass extends TimeBaseClass {\n constructor() {\n super(...arguments);\n this.name = "TimeClass";\n }\n _getExpressions() {\n return Object.assign(super._getExpressions(), {\n now: {\n method: (capture) => {\n return this._now() + new this.constructor(this.context, capture).valueOf();\n },\n regexp: /^\\+(.+)/,\n },\n quantize: {\n method: (capture) => {\n const quantTo = new TimeClass(this.context, capture).valueOf();\n return this._secondsToUnits(this.context.transport.nextSubdivision(quantTo));\n },\n regexp: /^@(.+)/,\n },\n });\n }\n /**\n * Quantize the time by the given subdivision. Optionally add a\n * percentage which will move the time value towards the ideal\n * quantized value by that percentage.\n * @param subdiv The subdivision to quantize to\n * @param percent Move the time value towards the quantized value by a percentage.\n * @example\n * Tone.Time(21).quantize(2); // returns 22\n * Tone.Time(0.6).quantize("4n", 0.5); // returns 0.55\n */\n quantize(subdiv, percent = 1) {\n const subdivision = new this.constructor(this.context, subdiv).valueOf();\n const value = this.valueOf();\n const multiple = Math.round(value / subdivision);\n const ideal = multiple * subdivision;\n const diff = ideal - value;\n return value + diff * percent;\n }\n //-------------------------------------\n // CONVERSIONS\n //-------------------------------------\n /**\n * Convert a Time to Notation. The notation values are will be the\n * closest representation between 1m to 128th note.\n * @return {Notation}\n * @example\n * // if the Transport is at 120bpm:\n * Tone.Time(2).toNotation(); // returns "1m"\n */\n toNotation() {\n const time = this.toSeconds();\n const testNotations = ["1m"];\n for (let power = 1; power < 9; power++) {\n const subdiv = Math.pow(2, power);\n testNotations.push(subdiv + "n.");\n testNotations.push(subdiv + "n");\n testNotations.push(subdiv + "t");\n }\n testNotations.push("0");\n // find the closets notation representation\n let closest = testNotations[0];\n let closestSeconds = new TimeClass(this.context, testNotations[0]).toSeconds();\n testNotations.forEach(notation => {\n const notationSeconds = new TimeClass(this.context, notation).toSeconds();\n if (Math.abs(notationSeconds - time) < Math.abs(closestSeconds - time)) {\n closest = notation;\n closestSeconds = notationSeconds;\n }\n });\n return closest;\n }\n /**\n * Return the time encoded as Bars:Beats:Sixteenths.\n */\n toBarsBeatsSixteenths() {\n const quarterTime = this._beatsToUnits(1);\n let quarters = this.valueOf() / quarterTime;\n quarters = parseFloat(quarters.toFixed(4));\n const measures = Math.floor(quarters / this._getTimeSignature());\n let sixteenths = (quarters % 1) * 4;\n quarters = Math.floor(quarters) % this._getTimeSignature();\n const sixteenthString = sixteenths.toString();\n if (sixteenthString.length > 3) {\n // the additional parseFloat removes insignificant trailing zeroes\n sixteenths = parseFloat(parseFloat(sixteenthString).toFixed(3));\n }\n const progress = [measures, quarters, sixteenths];\n return progress.join(":");\n }\n /**\n * Return the time in ticks.\n */\n toTicks() {\n const quarterTime = this._beatsToUnits(1);\n const quarters = this.valueOf() / quarterTime;\n return Math.round(quarters * this._getPPQ());\n }\n /**\n * Return the time in seconds.\n */\n toSeconds() {\n return this.valueOf();\n }\n /**\n * Return the value as a midi note.\n */\n toMidi() {\n return Conversions_ftom(this.toFrequency());\n }\n _now() {\n return this.context.now();\n }\n}\n/**\n * Create a TimeClass from a time string or number. The time is computed against the\n * global Tone.Context. To use a specific context, use [[TimeClass]]\n * @param value A value which represents time\n * @param units The value\'s units if they can\'t be inferred by the value.\n * @category Unit\n * @example\n * const time = Tone.Time("4n").toSeconds();\n * console.log(time);\n * @example\n * const note = Tone.Time(1).toNotation();\n * console.log(note);\n * @example\n * const freq = Tone.Time(0.5).toFrequency();\n * console.log(freq);\n */\nfunction Time(value, units) {\n return new TimeClass(getContext(), value, units);\n}\n//# sourceMappingURL=Time.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Frequency.js\n\n\n\n\n/**\n * Frequency is a primitive type for encoding Frequency values.\n * Eventually all time values are evaluated to hertz using the `valueOf` method.\n * @example\n * Tone.Frequency("C3"); // 261\n * Tone.Frequency(38, "midi");\n * Tone.Frequency("C3").transpose(4);\n * @category Unit\n */\nclass Frequency_FrequencyClass extends TimeClass {\n constructor() {\n super(...arguments);\n this.name = "Frequency";\n this.defaultUnits = "hz";\n }\n /**\n * The [concert tuning pitch](https://en.wikipedia.org/wiki/Concert_pitch) which is used\n * to generate all the other pitch values from notes. A4\'s values in Hertz.\n */\n static get A4() {\n return getA4();\n }\n static set A4(freq) {\n setA4(freq);\n }\n //-------------------------------------\n // \tAUGMENT BASE EXPRESSIONS\n //-------------------------------------\n _getExpressions() {\n return Object.assign({}, super._getExpressions(), {\n midi: {\n regexp: /^(\\d+(?:\\.\\d+)?midi)/,\n method(value) {\n if (this.defaultUnits === "midi") {\n return value;\n }\n else {\n return Frequency_FrequencyClass.mtof(value);\n }\n },\n },\n note: {\n regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i,\n method(pitch, octave) {\n const index = noteToScaleIndex[pitch.toLowerCase()];\n const noteNumber = index + (parseInt(octave, 10) + 1) * 12;\n if (this.defaultUnits === "midi") {\n return noteNumber;\n }\n else {\n return Frequency_FrequencyClass.mtof(noteNumber);\n }\n },\n },\n tr: {\n regexp: /^(\\d+(?:\\.\\d+)?):(\\d+(?:\\.\\d+)?):?(\\d+(?:\\.\\d+)?)?/,\n method(m, q, s) {\n let total = 1;\n if (m && m !== "0") {\n total *= this._beatsToUnits(this._getTimeSignature() * parseFloat(m));\n }\n if (q && q !== "0") {\n total *= this._beatsToUnits(parseFloat(q));\n }\n if (s && s !== "0") {\n total *= this._beatsToUnits(parseFloat(s) / 4);\n }\n return total;\n },\n },\n });\n }\n //-------------------------------------\n // \tEXPRESSIONS\n //-------------------------------------\n /**\n * Transposes the frequency by the given number of semitones.\n * @return A new transposed frequency\n * @example\n * Tone.Frequency("A4").transpose(3); // "C5"\n */\n transpose(interval) {\n return new Frequency_FrequencyClass(this.context, this.valueOf() * Conversions_intervalToFrequencyRatio(interval));\n }\n /**\n * Takes an array of semitone intervals and returns\n * an array of frequencies transposed by those intervals.\n * @return Returns an array of Frequencies\n * @example\n * Tone.Frequency("A4").harmonize([0, 3, 7]); // ["A4", "C5", "E5"]\n */\n harmonize(intervals) {\n return intervals.map(interval => {\n return this.transpose(interval);\n });\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS\n //-------------------------------------\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Frequency("C4").toMidi(); // 60\n */\n toMidi() {\n return Conversions_ftom(this.valueOf());\n }\n /**\n * Return the value of the frequency in Scientific Pitch Notation\n * @example\n * Tone.Frequency(69, "midi").toNote(); // "A4"\n */\n toNote() {\n const freq = this.toFrequency();\n const log = Math.log2(freq / Frequency_FrequencyClass.A4);\n let noteNumber = Math.round(12 * log) + 57;\n const octave = Math.floor(noteNumber / 12);\n if (octave < 0) {\n noteNumber += -12 * octave;\n }\n const noteName = scaleIndexToNote[noteNumber % 12];\n return noteName + octave.toString();\n }\n /**\n * Return the duration of one cycle in seconds.\n */\n toSeconds() {\n return 1 / super.toSeconds();\n }\n /**\n * Return the duration of one cycle in ticks\n */\n toTicks() {\n const quarterTime = this._beatsToUnits(1);\n const quarters = this.valueOf() / quarterTime;\n return Math.floor(quarters * this._getPPQ());\n }\n //-------------------------------------\n // \tUNIT CONVERSIONS HELPERS\n //-------------------------------------\n /**\n * With no arguments, return 0\n */\n _noArg() {\n return 0;\n }\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return freq;\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return 1 / ((ticks * 60) / (this._getBpm() * this._getPPQ()));\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return 1 / super._beatsToUnits(beats);\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return 1 / seconds;\n }\n /**\n * Convert a MIDI note to frequency value.\n * @param midi The midi number to convert.\n * @return The corresponding frequency value\n */\n static mtof(midi) {\n return Conversions_mtof(midi);\n }\n /**\n * Convert a frequency value to a MIDI note.\n * @param frequency The value to frequency value to convert.\n */\n static ftom(frequency) {\n return Conversions_ftom(frequency);\n }\n}\n//-------------------------------------\n// \tFREQUENCY CONVERSIONS\n//-------------------------------------\n/**\n * Note to scale index.\n * @hidden\n */\nconst noteToScaleIndex = {\n cbb: -2, cb: -1, c: 0, "c#": 1, cx: 2,\n dbb: 0, db: 1, d: 2, "d#": 3, dx: 4,\n ebb: 2, eb: 3, e: 4, "e#": 5, ex: 6,\n fbb: 3, fb: 4, f: 5, "f#": 6, fx: 7,\n gbb: 5, gb: 6, g: 7, "g#": 8, gx: 9,\n abb: 7, ab: 8, a: 9, "a#": 10, ax: 11,\n bbb: 9, bb: 10, b: 11, "b#": 12, bx: 13,\n};\n/**\n * scale index to note (sharps)\n * @hidden\n */\nconst scaleIndexToNote = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];\n/**\n * Convert a value into a FrequencyClass object.\n * @category Unit\n * @example\n * const midi = Tone.Frequency("C3").toMidi();\n * console.log(midi);\n * @example\n * const hertz = Tone.Frequency(38, "midi").toFrequency();\n * console.log(hertz);\n */\nfunction Frequency(value, units) {\n return new Frequency_FrequencyClass(getContext(), value, units);\n}\n//# sourceMappingURL=Frequency.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/TransportTime.js\n\n\n/**\n * TransportTime is a the time along the Transport\'s\n * timeline. It is similar to Tone.Time, but instead of evaluating\n * against the AudioContext\'s clock, it is evaluated against\n * the Transport\'s position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n * @category Unit\n */\nclass TransportTime_TransportTimeClass extends TimeClass {\n constructor() {\n super(...arguments);\n this.name = "TransportTime";\n }\n /**\n * Return the current time in whichever context is relevant\n */\n _now() {\n return this.context.transport.seconds;\n }\n}\n/**\n * TransportTime is a the time along the Transport\'s\n * timeline. It is similar to [[Time]], but instead of evaluating\n * against the AudioContext\'s clock, it is evaluated against\n * the Transport\'s position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime).\n * @category Unit\n */\nfunction TransportTime(value, units) {\n return new TransportTime_TransportTimeClass(getContext(), value, units);\n}\n//# sourceMappingURL=TransportTime.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneWithContext.js\n\n\n\n\n\n\n\n/**\n * The Base class for all nodes that have an AudioContext.\n */\nclass ToneWithContext_ToneWithContext extends Tone {\n constructor() {\n super();\n const options = Defaults_optionsFromArguments(ToneWithContext_ToneWithContext.getDefaults(), arguments, ["context"]);\n if (this.defaultContext) {\n this.context = this.defaultContext;\n }\n else {\n this.context = options.context;\n }\n }\n static getDefaults() {\n return {\n context: Global_getContext(),\n };\n }\n /**\n * Return the current time of the Context clock plus the lookAhead.\n * @example\n * setInterval(() => {\n * \tconsole.log(Tone.now());\n * }, 100);\n */\n now() {\n return this.context.currentTime + this.context.lookAhead;\n }\n /**\n * Return the current time of the Context clock without any lookAhead.\n * @example\n * setInterval(() => {\n * \tconsole.log(Tone.immediate());\n * }, 100);\n */\n immediate() {\n return this.context.currentTime;\n }\n /**\n * The duration in seconds of one sample.\n * @example\n * console.log(Tone.Transport.sampleTime);\n */\n get sampleTime() {\n return 1 / this.context.sampleRate;\n }\n /**\n * The number of seconds of 1 processing block (128 samples)\n * @example\n * console.log(Tone.Destination.blockTime);\n */\n get blockTime() {\n return 128 / this.context.sampleRate;\n }\n /**\n * Convert the incoming time to seconds.\n * This is calculated against the current [[Tone.Transport]] bpm\n * @example\n * const gain = new Tone.Gain();\n * setInterval(() => console.log(gain.toSeconds("4n")), 100);\n * // ramp the tempo to 60 bpm over 30 seconds\n * Tone.getTransport().bpm.rampTo(60, 30);\n */\n toSeconds(time) {\n return new TimeClass(this.context, time).toSeconds();\n }\n /**\n * Convert the input to a frequency number\n * @example\n * const gain = new Tone.Gain();\n * console.log(gain.toFrequency("4n"));\n */\n toFrequency(freq) {\n return new Frequency_FrequencyClass(this.context, freq).toFrequency();\n }\n /**\n * Convert the input time into ticks\n * @example\n * const gain = new Tone.Gain();\n * console.log(gain.toTicks("4n"));\n */\n toTicks(time) {\n return new TransportTime_TransportTimeClass(this.context, time).toTicks();\n }\n //-------------------------------------\n // \tGET/SET\n //-------------------------------------\n /**\n * Get a subset of the properties which are in the partial props\n */\n _getPartialProperties(props) {\n const options = this.get();\n // remove attributes from the prop that are not in the partial\n Object.keys(options).forEach(name => {\n if (TypeCheck_isUndef(props[name])) {\n delete options[name];\n }\n });\n return options;\n }\n /**\n * Get the object\'s attributes.\n * @example\n * const osc = new Tone.Oscillator();\n * console.log(osc.get());\n */\n get() {\n const defaults = getDefaultsFromInstance(this);\n Object.keys(defaults).forEach(attribute => {\n if (Reflect.has(this, attribute)) {\n const member = this[attribute];\n if (TypeCheck_isDefined(member) && TypeCheck_isDefined(member.value) && TypeCheck_isDefined(member.setValueAtTime)) {\n defaults[attribute] = member.value;\n }\n else if (member instanceof ToneWithContext_ToneWithContext) {\n defaults[attribute] = member._getPartialProperties(defaults[attribute]);\n // otherwise make sure it\'s a serializable type\n }\n else if (TypeCheck_isArray(member) || TypeCheck_isNumber(member) || TypeCheck_isString(member) || TypeCheck_isBoolean(member)) {\n defaults[attribute] = member;\n }\n else {\n // remove all undefined and unserializable attributes\n delete defaults[attribute];\n }\n }\n });\n return defaults;\n }\n /**\n * Set multiple properties at once with an object.\n * @example\n * const filter = new Tone.Filter().toDestination();\n * // set values using an object\n * filter.set({\n * \tfrequency: "C6",\n * \ttype: "highpass"\n * });\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/Analogsynth_octaves_highmid.mp3").connect(filter);\n * player.autostart = true;\n */\n set(props) {\n Object.keys(props).forEach(attribute => {\n if (Reflect.has(this, attribute) && TypeCheck_isDefined(this[attribute])) {\n if (this[attribute] && TypeCheck_isDefined(this[attribute].value) && TypeCheck_isDefined(this[attribute].setValueAtTime)) {\n // small optimization\n if (this[attribute].value !== props[attribute]) {\n this[attribute].value = props[attribute];\n }\n }\n else if (this[attribute] instanceof ToneWithContext_ToneWithContext) {\n this[attribute].set(props[attribute]);\n }\n else {\n this[attribute] = props[attribute];\n }\n }\n });\n return this;\n }\n}\n//# sourceMappingURL=ToneWithContext.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/StateTimeline.js\n\n\n/**\n * A Timeline State. Provides the methods: `setStateAtTime("state", time)` and `getValueAtTime(time)`\n * @param initial The initial state of the StateTimeline. Defaults to `undefined`\n */\nclass StateTimeline_StateTimeline extends Timeline {\n constructor(initial = "stopped") {\n super();\n this.name = "StateTimeline";\n this._initial = initial;\n this.setStateAtTime(this._initial, 0);\n }\n /**\n * Returns the scheduled state scheduled before or at\n * the given time.\n * @param time The time to query.\n * @return The name of the state input in setStateAtTime.\n */\n getValueAtTime(time) {\n const event = this.get(time);\n if (event !== null) {\n return event.state;\n }\n else {\n return this._initial;\n }\n }\n /**\n * Add a state to the timeline.\n * @param state The name of the state to set.\n * @param time The time to query.\n * @param options Any additional options that are needed in the timeline.\n */\n setStateAtTime(state, time, options) {\n Debug_assertRange(time, 0);\n this.add(Object.assign({}, options, {\n state,\n time,\n }));\n return this;\n }\n /**\n * Return the event before the time with the given state\n * @param state The state to look for\n * @param time When to check before\n * @return The event with the given state before the time\n */\n getLastState(state, time) {\n // time = this.toSeconds(time);\n const index = this._search(time);\n for (let i = index; i >= 0; i--) {\n const event = this._timeline[i];\n if (event.state === state) {\n return event;\n }\n }\n }\n /**\n * Return the event after the time with the given state\n * @param state The state to look for\n * @param time When to check from\n * @return The event with the given state after the time\n */\n getNextState(state, time) {\n // time = this.toSeconds(time);\n const index = this._search(time);\n if (index !== -1) {\n for (let i = index; i < this._timeline.length; i++) {\n const event = this._timeline[i];\n if (event.state === state) {\n return event;\n }\n }\n }\n }\n}\n//# sourceMappingURL=StateTimeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Param.js\n\n\n\n\n\n\n\n\n/**\n * Param wraps the native Web Audio\'s AudioParam to provide\n * additional unit conversion functionality. It also\n * serves as a base-class for classes which have a single,\n * automatable parameter.\n * @category Core\n */\nclass Param_Param extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Param_Param.getDefaults(), arguments, ["param", "units", "convert"]));\n this.name = "Param";\n this.overridden = false;\n /**\n * The minimum output value\n */\n this._minOutput = 1e-7;\n const options = Defaults_optionsFromArguments(Param_Param.getDefaults(), arguments, ["param", "units", "convert"]);\n Debug_assert(TypeCheck_isDefined(options.param) &&\n (isAudioParam(options.param) || options.param instanceof Param_Param), "param must be an AudioParam");\n while (!isAudioParam(options.param)) {\n options.param = options.param._param;\n }\n this._swappable = TypeCheck_isDefined(options.swappable) ? options.swappable : false;\n if (this._swappable) {\n this.input = this.context.createGain();\n // initialize\n this._param = options.param;\n this.input.connect(this._param);\n }\n else {\n this._param = this.input = options.param;\n }\n this._events = new Timeline(1000);\n this._initialValue = this._param.defaultValue;\n this.units = options.units;\n this.convert = options.convert;\n this._minValue = options.minValue;\n this._maxValue = options.maxValue;\n // if the value is defined, set it immediately\n if (TypeCheck_isDefined(options.value) && options.value !== this._toType(this._initialValue)) {\n this.setValueAtTime(options.value, 0);\n }\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n convert: true,\n units: "number",\n });\n }\n get value() {\n const now = this.now();\n return this.getValueAtTime(now);\n }\n set value(value) {\n this.cancelScheduledValues(this.now());\n this.setValueAtTime(value, this.now());\n }\n get minValue() {\n // if it\'s not the default minValue, return it\n if (TypeCheck_isDefined(this._minValue)) {\n return this._minValue;\n }\n else if (this.units === "time" || this.units === "frequency" ||\n this.units === "normalRange" || this.units === "positive" ||\n this.units === "transportTime" || this.units === "ticks" ||\n this.units === "bpm" || this.units === "hertz" || this.units === "samples") {\n return 0;\n }\n else if (this.units === "audioRange") {\n return -1;\n }\n else if (this.units === "decibels") {\n return -Infinity;\n }\n else {\n return this._param.minValue;\n }\n }\n get maxValue() {\n if (TypeCheck_isDefined(this._maxValue)) {\n return this._maxValue;\n }\n else if (this.units === "normalRange" ||\n this.units === "audioRange") {\n return 1;\n }\n else {\n return this._param.maxValue;\n }\n }\n /**\n * Type guard based on the unit name\n */\n _is(arg, type) {\n return this.units === type;\n }\n /**\n * Make sure the value is always in the defined range\n */\n _assertRange(value) {\n if (TypeCheck_isDefined(this.maxValue) && TypeCheck_isDefined(this.minValue)) {\n Debug_assertRange(value, this._fromType(this.minValue), this._fromType(this.maxValue));\n }\n return value;\n }\n /**\n * Convert the given value from the type specified by Param.units\n * into the destination value (such as Gain or Frequency).\n */\n _fromType(val) {\n if (this.convert && !this.overridden) {\n if (this._is(val, "time")) {\n return this.toSeconds(val);\n }\n else if (this._is(val, "decibels")) {\n return Conversions_dbToGain(val);\n }\n else if (this._is(val, "frequency")) {\n return this.toFrequency(val);\n }\n else {\n return val;\n }\n }\n else if (this.overridden) {\n // if it\'s overridden, should only schedule 0s\n return 0;\n }\n else {\n return val;\n }\n }\n /**\n * Convert the parameters value into the units specified by Param.units.\n */\n _toType(val) {\n if (this.convert && this.units === "decibels") {\n return Conversions_gainToDb(val);\n }\n else {\n return val;\n }\n }\n //-------------------------------------\n // ABSTRACT PARAM INTERFACE\n // all docs are generated from ParamInterface.ts\n //-------------------------------------\n setValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n const numericValue = this._fromType(value);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to setValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(time)}`);\n this._assertRange(numericValue);\n this.log(this.units, "setValueAtTime", value, computedTime);\n this._events.add({\n time: computedTime,\n type: "setValueAtTime",\n value: numericValue,\n });\n this._param.setValueAtTime(numericValue, computedTime);\n return this;\n }\n getValueAtTime(time) {\n const computedTime = Math.max(this.toSeconds(time), 0);\n const after = this._events.getAfter(computedTime);\n const before = this._events.get(computedTime);\n let value = this._initialValue;\n // if it was set by\n if (before === null) {\n value = this._initialValue;\n }\n else if (before.type === "setTargetAtTime" && (after === null || after.type === "setValueAtTime")) {\n const previous = this._events.getBefore(before.time);\n let previousVal;\n if (previous === null) {\n previousVal = this._initialValue;\n }\n else {\n previousVal = previous.value;\n }\n if (before.type === "setTargetAtTime") {\n value = this._exponentialApproach(before.time, previousVal, before.value, before.constant, computedTime);\n }\n }\n else if (after === null) {\n value = before.value;\n }\n else if (after.type === "linearRampToValueAtTime" || after.type === "exponentialRampToValueAtTime") {\n let beforeValue = before.value;\n if (before.type === "setTargetAtTime") {\n const previous = this._events.getBefore(before.time);\n if (previous === null) {\n beforeValue = this._initialValue;\n }\n else {\n beforeValue = previous.value;\n }\n }\n if (after.type === "linearRampToValueAtTime") {\n value = this._linearInterpolate(before.time, beforeValue, after.time, after.value, computedTime);\n }\n else {\n value = this._exponentialInterpolate(before.time, beforeValue, after.time, after.value, computedTime);\n }\n }\n else {\n value = before.value;\n }\n return this._toType(value);\n }\n setRampPoint(time) {\n time = this.toSeconds(time);\n let currentVal = this.getValueAtTime(time);\n this.cancelAndHoldAtTime(time);\n if (this._fromType(currentVal) === 0) {\n currentVal = this._toType(this._minOutput);\n }\n this.setValueAtTime(currentVal, time);\n return this;\n }\n linearRampToValueAtTime(value, endTime) {\n const numericValue = this._fromType(value);\n const computedTime = this.toSeconds(endTime);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to linearRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`);\n this._assertRange(numericValue);\n this._events.add({\n time: computedTime,\n type: "linearRampToValueAtTime",\n value: numericValue,\n });\n this.log(this.units, "linearRampToValueAtTime", value, computedTime);\n this._param.linearRampToValueAtTime(numericValue, computedTime);\n return this;\n }\n exponentialRampToValueAtTime(value, endTime) {\n let numericValue = this._fromType(value);\n // the value can\'t be 0\n numericValue = EQ(numericValue, 0) ? this._minOutput : numericValue;\n this._assertRange(numericValue);\n const computedTime = this.toSeconds(endTime);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to exponentialRampToValueAtTime: ${JSON.stringify(value)}, ${JSON.stringify(endTime)}`);\n // store the event\n this._events.add({\n time: computedTime,\n type: "exponentialRampToValueAtTime",\n value: numericValue,\n });\n this.log(this.units, "exponentialRampToValueAtTime", value, computedTime);\n this._param.exponentialRampToValueAtTime(numericValue, computedTime);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime));\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n startTime = this.toSeconds(startTime);\n this.setRampPoint(startTime);\n this.exponentialApproachValueAtTime(value, startTime, rampTime);\n return this;\n }\n exponentialApproachValueAtTime(value, time, rampTime) {\n time = this.toSeconds(time);\n rampTime = this.toSeconds(rampTime);\n const timeConstant = Math.log(rampTime + 1) / Math.log(200);\n this.setTargetAtTime(value, time, timeConstant);\n // at 90% start a linear ramp to the final value\n this.cancelAndHoldAtTime(time + rampTime * 0.9);\n this.linearRampToValueAtTime(value, time + rampTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n const numericValue = this._fromType(value);\n // The value will never be able to approach without timeConstant > 0.\n Debug_assert(isFinite(timeConstant) && timeConstant > 0, "timeConstant must be a number greater than 0");\n const computedTime = this.toSeconds(startTime);\n this._assertRange(numericValue);\n Debug_assert(isFinite(numericValue) && isFinite(computedTime), `Invalid argument(s) to setTargetAtTime: ${JSON.stringify(value)}, ${JSON.stringify(startTime)}`);\n this._events.add({\n constant: timeConstant,\n time: computedTime,\n type: "setTargetAtTime",\n value: numericValue,\n });\n this.log(this.units, "setTargetAtTime", value, computedTime, timeConstant);\n this._param.setTargetAtTime(numericValue, computedTime, timeConstant);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling = 1) {\n duration = this.toSeconds(duration);\n startTime = this.toSeconds(startTime);\n const startingValue = this._fromType(values[0]) * scaling;\n this.setValueAtTime(this._toType(startingValue), startTime);\n const segTime = duration / (values.length - 1);\n for (let i = 1; i < values.length; i++) {\n const numericValue = this._fromType(values[i]) * scaling;\n this.linearRampToValueAtTime(this._toType(numericValue), startTime + i * segTime);\n }\n return this;\n }\n cancelScheduledValues(time) {\n const computedTime = this.toSeconds(time);\n Debug_assert(isFinite(computedTime), `Invalid argument to cancelScheduledValues: ${JSON.stringify(time)}`);\n this._events.cancel(computedTime);\n this._param.cancelScheduledValues(computedTime);\n this.log(this.units, "cancelScheduledValues", computedTime);\n return this;\n }\n cancelAndHoldAtTime(time) {\n const computedTime = this.toSeconds(time);\n const valueAtTime = this._fromType(this.getValueAtTime(computedTime));\n // remove the schedule events\n Debug_assert(isFinite(computedTime), `Invalid argument to cancelAndHoldAtTime: ${JSON.stringify(time)}`);\n this.log(this.units, "cancelAndHoldAtTime", computedTime, "value=" + valueAtTime);\n // if there is an event at the given computedTime\n // and that even is not a "set"\n const before = this._events.get(computedTime);\n const after = this._events.getAfter(computedTime);\n if (before && EQ(before.time, computedTime)) {\n // remove everything after\n if (after) {\n this._param.cancelScheduledValues(after.time);\n this._events.cancel(after.time);\n }\n else {\n this._param.cancelAndHoldAtTime(computedTime);\n this._events.cancel(computedTime + this.sampleTime);\n }\n }\n else if (after) {\n this._param.cancelScheduledValues(after.time);\n // cancel the next event(s)\n this._events.cancel(after.time);\n if (after.type === "linearRampToValueAtTime") {\n this.linearRampToValueAtTime(this._toType(valueAtTime), computedTime);\n }\n else if (after.type === "exponentialRampToValueAtTime") {\n this.exponentialRampToValueAtTime(this._toType(valueAtTime), computedTime);\n }\n }\n // set the value at the given time\n this._events.add({\n time: computedTime,\n type: "setValueAtTime",\n value: valueAtTime,\n });\n this._param.setValueAtTime(valueAtTime, computedTime);\n return this;\n }\n rampTo(value, rampTime = 0.1, startTime) {\n if (this.units === "frequency" || this.units === "bpm" || this.units === "decibels") {\n this.exponentialRampTo(value, rampTime, startTime);\n }\n else {\n this.linearRampTo(value, rampTime, startTime);\n }\n return this;\n }\n /**\n * Apply all of the previously scheduled events to the passed in Param or AudioParam.\n * The applied values will start at the context\'s current time and schedule\n * all of the events which are scheduled on this Param onto the passed in param.\n */\n apply(param) {\n const now = this.context.currentTime;\n // set the param\'s value at the current time and schedule everything else\n param.setValueAtTime(this.getValueAtTime(now), now);\n // if the previous event was a curve, then set the rest of it\n const previousEvent = this._events.get(now);\n if (previousEvent && previousEvent.type === "setTargetAtTime") {\n // approx it until the next event with linear ramps\n const nextEvent = this._events.getAfter(previousEvent.time);\n // or for 2 seconds if there is no event\n const endTime = nextEvent ? nextEvent.time : now + 2;\n const subdivisions = (endTime - now) / 10;\n for (let i = now; i < endTime; i += subdivisions) {\n param.linearRampToValueAtTime(this.getValueAtTime(i), i);\n }\n }\n this._events.forEachAfter(this.context.currentTime, event => {\n if (event.type === "cancelScheduledValues") {\n param.cancelScheduledValues(event.time);\n }\n else if (event.type === "setTargetAtTime") {\n param.setTargetAtTime(event.value, event.time, event.constant);\n }\n else {\n param[event.type](event.value, event.time);\n }\n });\n return this;\n }\n /**\n * Replace the Param\'s internal AudioParam. Will apply scheduled curves\n * onto the parameter and replace the connections.\n */\n setParam(param) {\n Debug_assert(this._swappable, "The Param must be assigned as \'swappable\' in the constructor");\n const input = this.input;\n input.disconnect(this._param);\n this.apply(param);\n this._param = param;\n input.connect(this._param);\n return this;\n }\n dispose() {\n super.dispose();\n this._events.dispose();\n return this;\n }\n get defaultValue() {\n return this._toType(this._param.defaultValue);\n }\n //-------------------------------------\n // \tAUTOMATION CURVE CALCULATIONS\n // \tMIT License, copyright (c) 2014 Jordan Santell\n //-------------------------------------\n // Calculates the the value along the curve produced by setTargetAtTime\n _exponentialApproach(t0, v0, v1, timeConstant, t) {\n return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant);\n }\n // Calculates the the value along the curve produced by linearRampToValueAtTime\n _linearInterpolate(t0, v0, t1, v1, t) {\n return v0 + (v1 - v0) * ((t - t0) / (t1 - t0));\n }\n // Calculates the the value along the curve produced by exponentialRampToValueAtTime\n _exponentialInterpolate(t0, v0, t1, v1, t) {\n return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0));\n }\n}\n//# sourceMappingURL=Param.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioNode.js\n\n\n\n\n\n/**\n * ToneAudioNode is the base class for classes which process audio.\n */\nclass ToneAudioNode_ToneAudioNode extends ToneWithContext_ToneWithContext {\n constructor() {\n super(...arguments);\n /**\n * The name of the class\n */\n this.name = "ToneAudioNode";\n /**\n * List all of the node that must be set to match the ChannelProperties\n */\n this._internalChannels = [];\n }\n /**\n * The number of inputs feeding into the AudioNode.\n * For source nodes, this will be 0.\n * @example\n * const node = new Tone.Gain();\n * console.log(node.numberOfInputs);\n */\n get numberOfInputs() {\n if (TypeCheck_isDefined(this.input)) {\n if (isAudioParam(this.input) || this.input instanceof Param_Param) {\n return 1;\n }\n else {\n return this.input.numberOfInputs;\n }\n }\n else {\n return 0;\n }\n }\n /**\n * The number of outputs of the AudioNode.\n * @example\n * const node = new Tone.Gain();\n * console.log(node.numberOfOutputs);\n */\n get numberOfOutputs() {\n if (TypeCheck_isDefined(this.output)) {\n return this.output.numberOfOutputs;\n }\n else {\n return 0;\n }\n }\n //-------------------------------------\n // AUDIO PROPERTIES\n //-------------------------------------\n /**\n * Used to decide which nodes to get/set properties on\n */\n _isAudioNode(node) {\n return TypeCheck_isDefined(node) && (node instanceof ToneAudioNode_ToneAudioNode || AdvancedTypeCheck_isAudioNode(node));\n }\n /**\n * Get all of the audio nodes (either internal or input/output) which together\n * make up how the class node responds to channel input/output\n */\n _getInternalNodes() {\n const nodeList = this._internalChannels.slice(0);\n if (this._isAudioNode(this.input)) {\n nodeList.push(this.input);\n }\n if (this._isAudioNode(this.output)) {\n if (this.input !== this.output) {\n nodeList.push(this.output);\n }\n }\n return nodeList;\n }\n /**\n * Set the audio options for this node such as channelInterpretation\n * channelCount, etc.\n * @param options\n */\n _setChannelProperties(options) {\n const nodeList = this._getInternalNodes();\n nodeList.forEach(node => {\n node.channelCount = options.channelCount;\n node.channelCountMode = options.channelCountMode;\n node.channelInterpretation = options.channelInterpretation;\n });\n }\n /**\n * Get the current audio options for this node such as channelInterpretation\n * channelCount, etc.\n */\n _getChannelProperties() {\n const nodeList = this._getInternalNodes();\n Debug_assert(nodeList.length > 0, "ToneAudioNode does not have any internal nodes");\n // use the first node to get properties\n // they should all be the same\n const node = nodeList[0];\n return {\n channelCount: node.channelCount,\n channelCountMode: node.channelCountMode,\n channelInterpretation: node.channelInterpretation,\n };\n }\n /**\n * channelCount is the number of channels used when up-mixing and down-mixing\n * connections to any inputs to the node. The default value is 2 except for\n * specific nodes where its value is specially determined.\n */\n get channelCount() {\n return this._getChannelProperties().channelCount;\n }\n set channelCount(channelCount) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelCount }));\n }\n /**\n * channelCountMode determines how channels will be counted when up-mixing and\n * down-mixing connections to any inputs to the node.\n * The default value is "max". This attribute has no effect for nodes with no inputs.\n * * "max" - computedNumberOfChannels is the maximum of the number of channels of all connections to an input. In this mode channelCount is ignored.\n * * "clamped-max" - computedNumberOfChannels is determined as for "max" and then clamped to a maximum value of the given channelCount.\n * * "explicit" - computedNumberOfChannels is the exact value as specified by the channelCount.\n */\n get channelCountMode() {\n return this._getChannelProperties().channelCountMode;\n }\n set channelCountMode(channelCountMode) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelCountMode }));\n }\n /**\n * channelInterpretation determines how individual channels will be treated\n * when up-mixing and down-mixing connections to any inputs to the node.\n * The default value is "speakers".\n */\n get channelInterpretation() {\n return this._getChannelProperties().channelInterpretation;\n }\n set channelInterpretation(channelInterpretation) {\n const props = this._getChannelProperties();\n // merge it with the other properties\n this._setChannelProperties(Object.assign(props, { channelInterpretation }));\n }\n //-------------------------------------\n // CONNECTIONS\n //-------------------------------------\n /**\n * connect the output of a ToneAudioNode to an AudioParam, AudioNode, or ToneAudioNode\n * @param destination The output to connect to\n * @param outputNum The output to connect from\n * @param inputNum The input to connect to\n */\n connect(destination, outputNum = 0, inputNum = 0) {\n ToneAudioNode_connect(this, destination, outputNum, inputNum);\n return this;\n }\n /**\n * Connect the output to the context\'s destination node.\n * @example\n * const osc = new Tone.Oscillator("C2").start();\n * osc.toDestination();\n */\n toDestination() {\n this.connect(this.context.destination);\n return this;\n }\n /**\n * Connect the output to the context\'s destination node.\n * See [[toDestination]]\n * @deprecated\n */\n toMaster() {\n Debug_warn("toMaster() has been renamed toDestination()");\n return this.toDestination();\n }\n /**\n * disconnect the output\n */\n disconnect(destination, outputNum = 0, inputNum = 0) {\n ToneAudioNode_disconnect(this, destination, outputNum, inputNum);\n return this;\n }\n /**\n * Connect the output of this node to the rest of the nodes in series.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/handdrum-loop.mp3");\n * player.autostart = true;\n * const filter = new Tone.AutoFilter(4).start();\n * const distortion = new Tone.Distortion(0.5);\n * // connect the player to the filter, distortion and then to the master output\n * player.chain(filter, distortion, Tone.Destination);\n */\n chain(...nodes) {\n ToneAudioNode_connectSeries(this, ...nodes);\n return this;\n }\n /**\n * connect the output of this node to the rest of the nodes in parallel.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/conga-rhythm.mp3");\n * player.autostart = true;\n * const pitchShift = new Tone.PitchShift(4).toDestination();\n * const filter = new Tone.Filter("G5").toDestination();\n * // connect a node to the pitch shift and filter in parallel\n * player.fan(pitchShift, filter);\n */\n fan(...nodes) {\n nodes.forEach(node => this.connect(node));\n return this;\n }\n /**\n * Dispose and disconnect\n */\n dispose() {\n super.dispose();\n if (TypeCheck_isDefined(this.input)) {\n if (this.input instanceof ToneAudioNode_ToneAudioNode) {\n this.input.dispose();\n }\n else if (AdvancedTypeCheck_isAudioNode(this.input)) {\n this.input.disconnect();\n }\n }\n if (TypeCheck_isDefined(this.output)) {\n if (this.output instanceof ToneAudioNode_ToneAudioNode) {\n this.output.dispose();\n }\n else if (AdvancedTypeCheck_isAudioNode(this.output)) {\n this.output.disconnect();\n }\n }\n this._internalChannels = [];\n return this;\n }\n}\n//-------------------------------------\n// CONNECTIONS\n//-------------------------------------\n/**\n * connect together all of the arguments in series\n * @param nodes\n */\nfunction ToneAudioNode_connectSeries(...nodes) {\n const first = nodes.shift();\n nodes.reduce((prev, current) => {\n if (prev instanceof ToneAudioNode_ToneAudioNode) {\n prev.connect(current);\n }\n else if (AdvancedTypeCheck_isAudioNode(prev)) {\n ToneAudioNode_connect(prev, current);\n }\n return current;\n }, first);\n}\n/**\n * Connect two nodes together so that signal flows from the\n * first node to the second. Optionally specify the input and output channels.\n * @param srcNode The source node\n * @param dstNode The destination node\n * @param outputNumber The output channel of the srcNode\n * @param inputNumber The input channel of the dstNode\n */\nfunction ToneAudioNode_connect(srcNode, dstNode, outputNumber = 0, inputNumber = 0) {\n Debug_assert(TypeCheck_isDefined(srcNode), "Cannot connect from undefined node");\n Debug_assert(TypeCheck_isDefined(dstNode), "Cannot connect to undefined node");\n if (dstNode instanceof ToneAudioNode_ToneAudioNode || AdvancedTypeCheck_isAudioNode(dstNode)) {\n Debug_assert(dstNode.numberOfInputs > 0, "Cannot connect to node with no inputs");\n }\n Debug_assert(srcNode.numberOfOutputs > 0, "Cannot connect from node with no outputs");\n // resolve the input of the dstNode\n while ((dstNode instanceof ToneAudioNode_ToneAudioNode || dstNode instanceof Param_Param)) {\n if (TypeCheck_isDefined(dstNode.input)) {\n dstNode = dstNode.input;\n }\n }\n while (srcNode instanceof ToneAudioNode_ToneAudioNode) {\n if (TypeCheck_isDefined(srcNode.output)) {\n srcNode = srcNode.output;\n }\n }\n // make the connection\n if (isAudioParam(dstNode)) {\n srcNode.connect(dstNode, outputNumber);\n }\n else {\n srcNode.connect(dstNode, outputNumber, inputNumber);\n }\n}\n/**\n * Disconnect a node from all nodes or optionally include a destination node and input/output channels.\n * @param srcNode The source node\n * @param dstNode The destination node\n * @param outputNumber The output channel of the srcNode\n * @param inputNumber The input channel of the dstNode\n */\nfunction ToneAudioNode_disconnect(srcNode, dstNode, outputNumber = 0, inputNumber = 0) {\n // resolve the destination node\n if (TypeCheck_isDefined(dstNode)) {\n while (dstNode instanceof ToneAudioNode_ToneAudioNode) {\n dstNode = dstNode.input;\n }\n }\n // resolve the src node\n while (!(AdvancedTypeCheck_isAudioNode(srcNode))) {\n if (TypeCheck_isDefined(srcNode.output)) {\n srcNode = srcNode.output;\n }\n }\n if (isAudioParam(dstNode)) {\n srcNode.disconnect(dstNode, outputNumber);\n }\n else if (AdvancedTypeCheck_isAudioNode(dstNode)) {\n srcNode.disconnect(dstNode, outputNumber, inputNumber);\n }\n else {\n srcNode.disconnect();\n }\n}\n//# sourceMappingURL=ToneAudioNode.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Gain.js\n\n\n\n\n/**\n * A thin wrapper around the Native Web Audio GainNode.\n * The GainNode is a basic building block of the Web Audio\n * API and is useful for routing audio and adjusting gains.\n * @category Core\n * @example\n * return Tone.Offline(() => {\n * \tconst gainNode = new Tone.Gain(0).toDestination();\n * \tconst osc = new Tone.Oscillator(30).connect(gainNode).start();\n * \tgainNode.gain.rampTo(1, 0.1);\n * \tgainNode.gain.rampTo(0, 0.4, 0.2);\n * }, 0.7, 1);\n */\nclass Gain_Gain extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Gain_Gain.getDefaults(), arguments, ["gain", "units"]));\n this.name = "Gain";\n /**\n * The wrapped GainNode.\n */\n this._gainNode = this.context.createGain();\n // input = output\n this.input = this._gainNode;\n this.output = this._gainNode;\n const options = Defaults_optionsFromArguments(Gain_Gain.getDefaults(), arguments, ["gain", "units"]);\n this.gain = new Param_Param({\n context: this.context,\n convert: options.convert,\n param: this._gainNode.gain,\n units: options.units,\n value: options.gain,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n Interface_readOnly(this, "gain");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n convert: true,\n gain: 1,\n units: "gain",\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._gainNode.disconnect();\n this.gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Gain.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/OneShotSource.js\n\n\n\n\n/**\n * Base class for fire-and-forget nodes\n */\nclass OneShotSource extends ToneAudioNode_ToneAudioNode {\n constructor(options) {\n super(options);\n /**\n * The callback to invoke after the\n * source is done playing.\n */\n this.onended = Interface_noOp;\n /**\n * The start time\n */\n this._startTime = -1;\n /**\n * The stop time\n */\n this._stopTime = -1;\n /**\n * The id of the timeout\n */\n this._timeout = -1;\n /**\n * The public output node\n */\n this.output = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The output gain node.\n */\n this._gainNode = this.output;\n /**\n * Get the playback state at the given time\n */\n this.getStateAtTime = function (time) {\n const computedTime = this.toSeconds(time);\n if (this._startTime !== -1 &&\n computedTime >= this._startTime &&\n (this._stopTime === -1 || computedTime <= this._stopTime)) {\n return "started";\n }\n else {\n return "stopped";\n }\n };\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n this._curve = options.curve;\n this.onended = options.onended;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n curve: "linear",\n fadeIn: 0,\n fadeOut: 0,\n onended: Interface_noOp,\n });\n }\n /**\n * Start the source at the given time\n * @param time When to start the source\n */\n _startGain(time, gain = 1) {\n Debug_assert(this._startTime === -1, "Source cannot be started more than once");\n // apply a fade in envelope\n const fadeInTime = this.toSeconds(this._fadeIn);\n // record the start time\n this._startTime = time + fadeInTime;\n this._startTime = Math.max(this._startTime, this.context.currentTime);\n // schedule the envelope\n if (fadeInTime > 0) {\n this._gainNode.gain.setValueAtTime(0, time);\n if (this._curve === "linear") {\n this._gainNode.gain.linearRampToValueAtTime(gain, time + fadeInTime);\n }\n else {\n this._gainNode.gain.exponentialApproachValueAtTime(gain, time, fadeInTime);\n }\n }\n else {\n this._gainNode.gain.setValueAtTime(gain, time);\n }\n return this;\n }\n /**\n * Stop the source node at the given time.\n * @param time When to stop the source\n */\n stop(time) {\n this.log("stop", time);\n this._stopGain(this.toSeconds(time));\n return this;\n }\n /**\n * Stop the source at the given time\n * @param time When to stop the source\n */\n _stopGain(time) {\n Debug_assert(this._startTime !== -1, "\'start\' must be called before \'stop\'");\n // cancel the previous stop\n this.cancelStop();\n // the fadeOut time\n const fadeOutTime = this.toSeconds(this._fadeOut);\n // schedule the stop callback\n this._stopTime = this.toSeconds(time) + fadeOutTime;\n this._stopTime = Math.max(this._stopTime, this.context.currentTime);\n if (fadeOutTime > 0) {\n // start the fade out curve at the given time\n if (this._curve === "linear") {\n this._gainNode.gain.linearRampTo(0, fadeOutTime, time);\n }\n else {\n this._gainNode.gain.targetRampTo(0, fadeOutTime, time);\n }\n }\n else {\n // stop any ongoing ramps, and set the value to 0\n this._gainNode.gain.cancelAndHoldAtTime(time);\n this._gainNode.gain.setValueAtTime(0, time);\n }\n this.context.clearTimeout(this._timeout);\n this._timeout = this.context.setTimeout(() => {\n // allow additional time for the exponential curve to fully decay\n const additionalTail = this._curve === "exponential" ? fadeOutTime * 2 : 0;\n this._stopSource(this.now() + additionalTail);\n this._onended();\n }, this._stopTime - this.context.currentTime);\n return this;\n }\n /**\n * Invoke the onended callback\n */\n _onended() {\n if (this.onended !== Interface_noOp) {\n this.onended(this);\n // overwrite onended to make sure it only is called once\n this.onended = Interface_noOp;\n // dispose when it\'s ended to free up for garbage collection only in the online context\n if (!this.context.isOffline) {\n const disposeCallback = () => this.dispose();\n // @ts-ignore\n if (typeof window.requestIdleCallback !== "undefined") {\n // @ts-ignore\n window.requestIdleCallback(disposeCallback);\n }\n else {\n setTimeout(disposeCallback, 1000);\n }\n }\n }\n }\n /**\n * Get the playback state at the current time\n */\n get state() {\n return this.getStateAtTime(this.now());\n }\n /**\n * Cancel a scheduled stop event\n */\n cancelStop() {\n this.log("cancelStop");\n Debug_assert(this._startTime !== -1, "Source is not started");\n // cancel the stop envelope\n this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime);\n this.context.clearTimeout(this._timeout);\n this._stopTime = -1;\n return this;\n }\n dispose() {\n super.dispose();\n this._gainNode.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=OneShotSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/ToneConstantSource.js\n\n\n\n\n/**\n * Wrapper around the native fire-and-forget ConstantSource.\n * Adds the ability to reschedule the stop method.\n * @category Signal\n */\nclass ToneConstantSource_ToneConstantSource extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneConstantSource_ToneConstantSource.getDefaults(), arguments, ["offset"]));\n this.name = "ToneConstantSource";\n /**\n * The signal generator\n */\n this._source = this.context.createConstantSource();\n const options = Defaults_optionsFromArguments(ToneConstantSource_ToneConstantSource.getDefaults(), arguments, ["offset"]);\n ToneAudioNode_connect(this._source, this._gainNode);\n this.offset = new Param_Param({\n context: this.context,\n convert: options.convert,\n param: this._source.offset,\n units: options.units,\n value: options.offset,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n convert: true,\n offset: 1,\n units: "number",\n });\n }\n /**\n * Start the source node at the given time\n * @param time When to start the source\n */\n start(time) {\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n this._startGain(computedTime);\n this._source.start(computedTime);\n return this;\n }\n _stopSource(time) {\n this._source.stop(time);\n }\n dispose() {\n super.dispose();\n if (this.state === "started") {\n this.stop();\n }\n this._source.disconnect();\n this.offset.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneConstantSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Signal.js\n\n\n\n\n\n\n/**\n * A signal is an audio-rate value. Tone.Signal is a core component of the library.\n * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal\n * has all of the methods available to native Web Audio\n * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface)\n * as well as additional conveniences. Read more about working with signals\n * [here](https://github.com/Tonejs/Tone.js/wiki/Signals).\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // a scheduleable signal which can be connected to control an AudioParam or another Signal\n * const signal = new Tone.Signal({\n * \tvalue: "C4",\n * \tunits: "frequency"\n * }).connect(osc.frequency);\n * // the scheduled ramp controls the connected signal\n * signal.rampTo("C2", 4, "+0.5");\n * @category Signal\n */\nclass Signal_Signal extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Signal_Signal.getDefaults(), arguments, ["value", "units"]));\n this.name = "Signal";\n /**\n * Indicates if the value should be overridden on connection.\n */\n this.override = true;\n const options = Defaults_optionsFromArguments(Signal_Signal.getDefaults(), arguments, ["value", "units"]);\n this.output = this._constantSource = new ToneConstantSource_ToneConstantSource({\n context: this.context,\n convert: options.convert,\n offset: options.value,\n units: options.units,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n this._constantSource.start(0);\n this.input = this._param = this._constantSource.offset;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n convert: true,\n units: "number",\n value: 0,\n });\n }\n connect(destination, outputNum = 0, inputNum = 0) {\n // start it only when connected to something\n Signal_connectSignal(this, destination, outputNum, inputNum);\n return this;\n }\n dispose() {\n super.dispose();\n this._param.dispose();\n this._constantSource.dispose();\n return this;\n }\n //-------------------------------------\n // ABSTRACT PARAM INTERFACE\n // just a proxy for the ConstantSourceNode\'s offset AudioParam\n // all docs are generated from AbstractParam.ts\n //-------------------------------------\n setValueAtTime(value, time) {\n this._param.setValueAtTime(value, time);\n return this;\n }\n getValueAtTime(time) {\n return this._param.getValueAtTime(time);\n }\n setRampPoint(time) {\n this._param.setRampPoint(time);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n this._param.linearRampToValueAtTime(value, time);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n this._param.exponentialRampToValueAtTime(value, time);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n this._param.exponentialRampTo(value, rampTime, startTime);\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n this._param.linearRampTo(value, rampTime, startTime);\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n this._param.targetRampTo(value, rampTime, startTime);\n return this;\n }\n exponentialApproachValueAtTime(value, time, rampTime) {\n this._param.exponentialApproachValueAtTime(value, time, rampTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n this._param.setTargetAtTime(value, startTime, timeConstant);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling) {\n this._param.setValueCurveAtTime(values, startTime, duration, scaling);\n return this;\n }\n cancelScheduledValues(time) {\n this._param.cancelScheduledValues(time);\n return this;\n }\n cancelAndHoldAtTime(time) {\n this._param.cancelAndHoldAtTime(time);\n return this;\n }\n rampTo(value, rampTime, startTime) {\n this._param.rampTo(value, rampTime, startTime);\n return this;\n }\n get value() {\n return this._param.value;\n }\n set value(value) {\n this._param.value = value;\n }\n get convert() {\n return this._param.convert;\n }\n set convert(convert) {\n this._param.convert = convert;\n }\n get units() {\n return this._param.units;\n }\n get overridden() {\n return this._param.overridden;\n }\n set overridden(overridden) {\n this._param.overridden = overridden;\n }\n get maxValue() {\n return this._param.maxValue;\n }\n get minValue() {\n return this._param.minValue;\n }\n /**\n * See [[Param.apply]].\n */\n apply(param) {\n this._param.apply(param);\n return this;\n }\n}\n/**\n * When connecting from a signal, it\'s necessary to zero out the node destination\n * node if that node is also a signal. If the destination is not 0, then the values\n * will be summed. This method insures that the output of the destination signal will\n * be the same as the source signal, making the destination signal a pass through node.\n * @param signal The output signal to connect from\n * @param destination the destination to connect to\n * @param outputNum the optional output number\n * @param inputNum the input number\n */\nfunction Signal_connectSignal(signal, destination, outputNum, inputNum) {\n if (destination instanceof Param_Param || isAudioParam(destination) ||\n (destination instanceof Signal_Signal && destination.override)) {\n // cancel changes\n destination.cancelScheduledValues(0);\n // reset the value\n destination.setValueAtTime(0, 0);\n // mark the value as overridden\n if (destination instanceof Signal_Signal) {\n destination.overridden = true;\n }\n }\n ToneAudioNode_connect(signal, destination, outputNum, inputNum);\n}\n//# sourceMappingURL=Signal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickParam.js\n\n\n\n\n/**\n * A Param class just for computing ticks. Similar to the [[Param]] class,\n * but offers conversion to BPM values as well as ability to compute tick\n * duration and elapsed ticks\n */\nclass TickParam extends Param_Param {\n constructor() {\n super(Defaults_optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]));\n this.name = "TickParam";\n /**\n * The timeline which tracks all of the automations.\n */\n this._events = new Timeline(Infinity);\n /**\n * The internal holder for the multiplier value\n */\n this._multiplier = 1;\n const options = Defaults_optionsFromArguments(TickParam.getDefaults(), arguments, ["value"]);\n // set the multiplier\n this._multiplier = options.multiplier;\n // clear the ticks from the beginning\n this._events.cancel(0);\n // set an initial event\n this._events.add({\n ticks: 0,\n time: 0,\n type: "setValueAtTime",\n value: this._fromType(options.value),\n });\n this.setValueAtTime(options.value, 0);\n }\n static getDefaults() {\n return Object.assign(Param_Param.getDefaults(), {\n multiplier: 1,\n units: "hertz",\n value: 1,\n });\n }\n setTargetAtTime(value, time, constant) {\n // approximate it with multiple linear ramps\n time = this.toSeconds(time);\n this.setRampPoint(time);\n const computedValue = this._fromType(value);\n // start from previously scheduled value\n const prevEvent = this._events.get(time);\n const segments = Math.round(Math.max(1 / constant, 1));\n for (let i = 0; i <= segments; i++) {\n const segTime = constant * i + time;\n const rampVal = this._exponentialApproach(prevEvent.time, prevEvent.value, computedValue, constant, segTime);\n this.linearRampToValueAtTime(this._toType(rampVal), segTime);\n }\n return this;\n }\n setValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n super.setValueAtTime(value, time);\n const event = this._events.get(computedTime);\n const previousEvent = this._events.previousEvent(event);\n const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime);\n event.ticks = Math.max(ticksUntilTime, 0);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n const computedTime = this.toSeconds(time);\n super.linearRampToValueAtTime(value, time);\n const event = this._events.get(computedTime);\n const previousEvent = this._events.previousEvent(event);\n const ticksUntilTime = this._getTicksUntilEvent(previousEvent, computedTime);\n event.ticks = Math.max(ticksUntilTime, 0);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n // aproximate it with multiple linear ramps\n time = this.toSeconds(time);\n const computedVal = this._fromType(value);\n // start from previously scheduled value\n const prevEvent = this._events.get(time);\n // approx 10 segments per second\n const segments = Math.round(Math.max((time - prevEvent.time) * 10, 1));\n const segmentDur = ((time - prevEvent.time) / segments);\n for (let i = 0; i <= segments; i++) {\n const segTime = segmentDur * i + prevEvent.time;\n const rampVal = this._exponentialInterpolate(prevEvent.time, prevEvent.value, time, computedVal, segTime);\n this.linearRampToValueAtTime(this._toType(rampVal), segTime);\n }\n return this;\n }\n /**\n * Returns the tick value at the time. Takes into account\n * any automation curves scheduled on the signal.\n * @param event The time to get the tick count at\n * @return The number of ticks which have elapsed at the time given any automations.\n */\n _getTicksUntilEvent(event, time) {\n if (event === null) {\n event = {\n ticks: 0,\n time: 0,\n type: "setValueAtTime",\n value: 0,\n };\n }\n else if (TypeCheck_isUndef(event.ticks)) {\n const previousEvent = this._events.previousEvent(event);\n event.ticks = this._getTicksUntilEvent(previousEvent, event.time);\n }\n const val0 = this._fromType(this.getValueAtTime(event.time));\n let val1 = this._fromType(this.getValueAtTime(time));\n // if it\'s right on the line, take the previous value\n const onTheLineEvent = this._events.get(time);\n if (onTheLineEvent && onTheLineEvent.time === time && onTheLineEvent.type === "setValueAtTime") {\n val1 = this._fromType(this.getValueAtTime(time - this.sampleTime));\n }\n return 0.5 * (time - event.time) * (val0 + val1) + event.ticks;\n }\n /**\n * Returns the tick value at the time. Takes into account\n * any automation curves scheduled on the signal.\n * @param time The time to get the tick count at\n * @return The number of ticks which have elapsed at the time given any automations.\n */\n getTicksAtTime(time) {\n const computedTime = this.toSeconds(time);\n const event = this._events.get(computedTime);\n return Math.max(this._getTicksUntilEvent(event, computedTime), 0);\n }\n /**\n * Return the elapsed time of the number of ticks from the given time\n * @param ticks The number of ticks to calculate\n * @param time The time to get the next tick from\n * @return The duration of the number of ticks from the given time in seconds\n */\n getDurationOfTicks(ticks, time) {\n const computedTime = this.toSeconds(time);\n const currentTick = this.getTicksAtTime(time);\n return this.getTimeOfTick(currentTick + ticks) - computedTime;\n }\n /**\n * Given a tick, returns the time that tick occurs at.\n * @return The time that the tick occurs.\n */\n getTimeOfTick(tick) {\n const before = this._events.get(tick, "ticks");\n const after = this._events.getAfter(tick, "ticks");\n if (before && before.ticks === tick) {\n return before.time;\n }\n else if (before && after &&\n after.type === "linearRampToValueAtTime" &&\n before.value !== after.value) {\n const val0 = this._fromType(this.getValueAtTime(before.time));\n const val1 = this._fromType(this.getValueAtTime(after.time));\n const delta = (val1 - val0) / (after.time - before.time);\n const k = Math.sqrt(Math.pow(val0, 2) - 2 * delta * (before.ticks - tick));\n const sol1 = (-val0 + k) / delta;\n const sol2 = (-val0 - k) / delta;\n return (sol1 > 0 ? sol1 : sol2) + before.time;\n }\n else if (before) {\n if (before.value === 0) {\n return Infinity;\n }\n else {\n return before.time + (tick - before.ticks) / before.value;\n }\n }\n else {\n return tick / this._initialValue;\n }\n }\n /**\n * Convert some number of ticks their the duration in seconds accounting\n * for any automation curves starting at the given time.\n * @param ticks The number of ticks to convert to seconds.\n * @param when When along the automation timeline to convert the ticks.\n * @return The duration in seconds of the ticks.\n */\n ticksToTime(ticks, when) {\n return this.getDurationOfTicks(ticks, when);\n }\n /**\n * The inverse of [[ticksToTime]]. Convert a duration in\n * seconds to the corresponding number of ticks accounting for any\n * automation curves starting at the given time.\n * @param duration The time interval to convert to ticks.\n * @param when When along the automation timeline to convert the ticks.\n * @return The duration in ticks.\n */\n timeToTicks(duration, when) {\n const computedTime = this.toSeconds(when);\n const computedDuration = this.toSeconds(duration);\n const startTicks = this.getTicksAtTime(computedTime);\n const endTicks = this.getTicksAtTime(computedTime + computedDuration);\n return endTicks - startTicks;\n }\n /**\n * Convert from the type when the unit value is BPM\n */\n _fromType(val) {\n if (this.units === "bpm" && this.multiplier) {\n return 1 / (60 / val / this.multiplier);\n }\n else {\n return super._fromType(val);\n }\n }\n /**\n * Special case of type conversion where the units === "bpm"\n */\n _toType(val) {\n if (this.units === "bpm" && this.multiplier) {\n return (val / this.multiplier) * 60;\n }\n else {\n return super._toType(val);\n }\n }\n /**\n * A multiplier on the bpm value. Useful for setting a PPQ relative to the base frequency value.\n */\n get multiplier() {\n return this._multiplier;\n }\n set multiplier(m) {\n // get and reset the current value with the new multiplier\n // might be necessary to clear all the previous values\n const currentVal = this.value;\n this._multiplier = m;\n this.cancelScheduledValues(0);\n this.setValueAtTime(currentVal, 0);\n }\n}\n//# sourceMappingURL=TickParam.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickSignal.js\n\n\n\n/**\n * TickSignal extends Tone.Signal, but adds the capability\n * to calculate the number of elapsed ticks. exponential and target curves\n * are approximated with multiple linear ramps.\n *\n * Thank you Bruno Dias, H. Sofia Pinto, and David M. Matos,\n * for your [WAC paper](https://smartech.gatech.edu/bitstream/handle/1853/54588/WAC2016-49.pdf)\n * describing integrating timing functions for tempo calculations.\n */\nclass TickSignal extends Signal_Signal {\n constructor() {\n super(Defaults_optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]));\n this.name = "TickSignal";\n const options = Defaults_optionsFromArguments(TickSignal.getDefaults(), arguments, ["value"]);\n this.input = this._param = new TickParam({\n context: this.context,\n convert: options.convert,\n multiplier: options.multiplier,\n param: this._constantSource.offset,\n units: options.units,\n value: options.value,\n });\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n multiplier: 1,\n units: "hertz",\n value: 1,\n });\n }\n ticksToTime(ticks, when) {\n return this._param.ticksToTime(ticks, when);\n }\n timeToTicks(duration, when) {\n return this._param.timeToTicks(duration, when);\n }\n getTimeOfTick(tick) {\n return this._param.getTimeOfTick(tick);\n }\n getDurationOfTicks(ticks, time) {\n return this._param.getDurationOfTicks(ticks, time);\n }\n getTicksAtTime(time) {\n return this._param.getTicksAtTime(time);\n }\n /**\n * A multiplier on the bpm value. Useful for setting a PPQ relative to the base frequency value.\n */\n get multiplier() {\n return this._param.multiplier;\n }\n set multiplier(m) {\n this._param.multiplier = m;\n }\n dispose() {\n super.dispose();\n this._param.dispose();\n return this;\n }\n}\n//# sourceMappingURL=TickSignal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TickSource.js\n\n\n\n\n\n\n\n\n/**\n * Uses [TickSignal](TickSignal) to track elapsed ticks with complex automation curves.\n */\nclass TickSource extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]));\n this.name = "TickSource";\n /**\n * The state timeline\n */\n this._state = new StateTimeline_StateTimeline();\n /**\n * The offset values of the ticks\n */\n this._tickOffset = new Timeline();\n const options = Defaults_optionsFromArguments(TickSource.getDefaults(), arguments, ["frequency"]);\n this.frequency = new TickSignal({\n context: this.context,\n units: options.units,\n value: options.frequency,\n });\n Interface_readOnly(this, "frequency");\n // set the initial state\n this._state.setStateAtTime("stopped", 0);\n // add the first event\n this.setTicksAtTime(0, 0);\n }\n static getDefaults() {\n return Object.assign({\n frequency: 1,\n units: "hertz",\n }, ToneWithContext_ToneWithContext.getDefaults());\n }\n /**\n * Returns the playback state of the source, either "started", "stopped" or "paused".\n */\n get state() {\n return this.getStateAtTime(this.now());\n }\n /**\n * Start the clock at the given time. Optionally pass in an offset\n * of where to start the tick counter from.\n * @param time The time the clock should start\n * @param offset The number of ticks to start the source at\n */\n start(time, offset) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) !== "started") {\n this._state.setStateAtTime("started", computedTime);\n if (TypeCheck_isDefined(offset)) {\n this.setTicksAtTime(offset, computedTime);\n }\n }\n return this;\n }\n /**\n * Stop the clock. Stopping the clock resets the tick counter to 0.\n * @param time The time when the clock should stop.\n */\n stop(time) {\n const computedTime = this.toSeconds(time);\n // cancel the previous stop\n if (this._state.getValueAtTime(computedTime) === "stopped") {\n const event = this._state.get(computedTime);\n if (event && event.time > 0) {\n this._tickOffset.cancel(event.time);\n this._state.cancel(event.time);\n }\n }\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n this.setTicksAtTime(0, computedTime);\n return this;\n }\n /**\n * Pause the clock. Pausing does not reset the tick counter.\n * @param time The time when the clock should stop.\n */\n pause(time) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) === "started") {\n this._state.setStateAtTime("paused", computedTime);\n }\n return this;\n }\n /**\n * Cancel start/stop/pause and setTickAtTime events scheduled after the given time.\n * @param time When to clear the events after\n */\n cancel(time) {\n time = this.toSeconds(time);\n this._state.cancel(time);\n this._tickOffset.cancel(time);\n return this;\n }\n /**\n * Get the elapsed ticks at the given time\n * @param time When to get the tick value\n * @return The number of ticks\n */\n getTicksAtTime(time) {\n const computedTime = this.toSeconds(time);\n const stopEvent = this._state.getLastState("stopped", computedTime);\n // this event allows forEachBetween to iterate until the current time\n const tmpEvent = { state: "paused", time: computedTime };\n this._state.add(tmpEvent);\n // keep track of the previous offset event\n let lastState = stopEvent;\n let elapsedTicks = 0;\n // iterate through all the events since the last stop\n this._state.forEachBetween(stopEvent.time, computedTime + this.sampleTime, e => {\n let periodStartTime = lastState.time;\n // if there is an offset event in this period use that\n const offsetEvent = this._tickOffset.get(e.time);\n if (offsetEvent && offsetEvent.time >= lastState.time) {\n elapsedTicks = offsetEvent.ticks;\n periodStartTime = offsetEvent.time;\n }\n if (lastState.state === "started" && e.state !== "started") {\n elapsedTicks += this.frequency.getTicksAtTime(e.time) - this.frequency.getTicksAtTime(periodStartTime);\n }\n lastState = e;\n });\n // remove the temporary event\n this._state.remove(tmpEvent);\n // return the ticks\n return elapsedTicks;\n }\n /**\n * The number of times the callback was invoked. Starts counting at 0\n * and increments after the callback was invoked. Returns -1 when stopped.\n */\n get ticks() {\n return this.getTicksAtTime(this.now());\n }\n set ticks(t) {\n this.setTicksAtTime(t, this.now());\n }\n /**\n * The time since ticks=0 that the TickSource has been running. Accounts\n * for tempo curves\n */\n get seconds() {\n return this.getSecondsAtTime(this.now());\n }\n set seconds(s) {\n const now = this.now();\n const ticks = this.frequency.timeToTicks(s, now);\n this.setTicksAtTime(ticks, now);\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n time = this.toSeconds(time);\n const stopEvent = this._state.getLastState("stopped", time);\n // this event allows forEachBetween to iterate until the current time\n const tmpEvent = { state: "paused", time };\n this._state.add(tmpEvent);\n // keep track of the previous offset event\n let lastState = stopEvent;\n let elapsedSeconds = 0;\n // iterate through all the events since the last stop\n this._state.forEachBetween(stopEvent.time, time + this.sampleTime, e => {\n let periodStartTime = lastState.time;\n // if there is an offset event in this period use that\n const offsetEvent = this._tickOffset.get(e.time);\n if (offsetEvent && offsetEvent.time >= lastState.time) {\n elapsedSeconds = offsetEvent.seconds;\n periodStartTime = offsetEvent.time;\n }\n if (lastState.state === "started" && e.state !== "started") {\n elapsedSeconds += e.time - periodStartTime;\n }\n lastState = e;\n });\n // remove the temporary event\n this._state.remove(tmpEvent);\n // return the ticks\n return elapsedSeconds;\n }\n /**\n * Set the clock\'s ticks at the given time.\n * @param ticks The tick value to set\n * @param time When to set the tick value\n */\n setTicksAtTime(ticks, time) {\n time = this.toSeconds(time);\n this._tickOffset.cancel(time);\n this._tickOffset.add({\n seconds: this.frequency.getDurationOfTicks(ticks, time),\n ticks,\n time,\n });\n return this;\n }\n /**\n * Returns the scheduled state at the given time.\n * @param time The time to query.\n */\n getStateAtTime(time) {\n time = this.toSeconds(time);\n return this._state.getValueAtTime(time);\n }\n /**\n * Get the time of the given tick. The second argument\n * is when to test before. Since ticks can be set (with setTicksAtTime)\n * there may be multiple times for a given tick value.\n * @param tick The tick number.\n * @param before When to measure the tick value from.\n * @return The time of the tick\n */\n getTimeOfTick(tick, before = this.now()) {\n const offset = this._tickOffset.get(before);\n const event = this._state.get(before);\n const startTime = Math.max(offset.time, event.time);\n const absoluteTicks = this.frequency.getTicksAtTime(startTime) + tick - offset.ticks;\n return this.frequency.getTimeOfTick(absoluteTicks);\n }\n /**\n * Invoke the callback event at all scheduled ticks between the\n * start time and the end time\n * @param startTime The beginning of the search range\n * @param endTime The end of the search range\n * @param callback The callback to invoke with each tick\n */\n forEachTickBetween(startTime, endTime, callback) {\n // only iterate through the sections where it is "started"\n let lastStateEvent = this._state.get(startTime);\n this._state.forEachBetween(startTime, endTime, event => {\n if (lastStateEvent && lastStateEvent.state === "started" && event.state !== "started") {\n this.forEachTickBetween(Math.max(lastStateEvent.time, startTime), event.time - this.sampleTime, callback);\n }\n lastStateEvent = event;\n });\n let error = null;\n if (lastStateEvent && lastStateEvent.state === "started") {\n const maxStartTime = Math.max(lastStateEvent.time, startTime);\n // figure out the difference between the frequency ticks and the\n const startTicks = this.frequency.getTicksAtTime(maxStartTime);\n const ticksAtStart = this.frequency.getTicksAtTime(lastStateEvent.time);\n const diff = startTicks - ticksAtStart;\n let offset = Math.ceil(diff) - diff;\n // guard against floating point issues\n offset = EQ(offset, 1) ? 0 : offset;\n let nextTickTime = this.frequency.getTimeOfTick(startTicks + offset);\n while (nextTickTime < endTime) {\n try {\n callback(nextTickTime, Math.round(this.getTicksAtTime(nextTickTime)));\n }\n catch (e) {\n error = e;\n break;\n }\n nextTickTime += this.frequency.getDurationOfTicks(1, nextTickTime);\n }\n }\n if (error) {\n throw error;\n }\n return this;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._state.dispose();\n this._tickOffset.dispose();\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=TickSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Clock.js\n\n\n\n\n\n\n\n/**\n * A sample accurate clock which provides a callback at the given rate.\n * While the callback is not sample-accurate (it is still susceptible to\n * loose JS timing), the time passed in as the argument to the callback\n * is precise. For most applications, it is better to use Tone.Transport\n * instead of the Clock by itself since you can synchronize multiple callbacks.\n * @example\n * // the callback will be invoked approximately once a second\n * // and will print the time exactly once a second apart.\n * const clock = new Tone.Clock(time => {\n * \tconsole.log(time);\n * }, 1);\n * clock.start();\n * @category Core\n */\nclass Clock_Clock extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Clock_Clock.getDefaults(), arguments, ["callback", "frequency"]));\n this.name = "Clock";\n /**\n * The callback function to invoke at the scheduled tick.\n */\n this.callback = Interface_noOp;\n /**\n * The last time the loop callback was invoked\n */\n this._lastUpdate = 0;\n /**\n * Keep track of the playback state\n */\n this._state = new StateTimeline_StateTimeline("stopped");\n /**\n * Context bound reference to the _loop method\n * This is necessary to remove the event in the end.\n */\n this._boundLoop = this._loop.bind(this);\n const options = Defaults_optionsFromArguments(Clock_Clock.getDefaults(), arguments, ["callback", "frequency"]);\n this.callback = options.callback;\n this._tickSource = new TickSource({\n context: this.context,\n frequency: options.frequency,\n units: options.units,\n });\n this._lastUpdate = 0;\n this.frequency = this._tickSource.frequency;\n Interface_readOnly(this, "frequency");\n // add an initial state\n this._state.setStateAtTime("stopped", 0);\n // bind a callback to the worker thread\n this.context.on("tick", this._boundLoop);\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n callback: Interface_noOp,\n frequency: 1,\n units: "hertz",\n });\n }\n /**\n * Returns the playback state of the source, either "started", "stopped" or "paused".\n */\n get state() {\n return this._state.getValueAtTime(this.now());\n }\n /**\n * Start the clock at the given time. Optionally pass in an offset\n * of where to start the tick counter from.\n * @param time The time the clock should start\n * @param offset Where the tick counter starts counting from.\n */\n start(time, offset) {\n // make sure the context is running\n assertContextRunning(this.context);\n // start the loop\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n if (this._state.getValueAtTime(computedTime) !== "started") {\n this._state.setStateAtTime("started", computedTime);\n this._tickSource.start(computedTime, offset);\n if (computedTime < this._lastUpdate) {\n this.emit("start", computedTime, offset);\n }\n }\n return this;\n }\n /**\n * Stop the clock. Stopping the clock resets the tick counter to 0.\n * @param time The time when the clock should stop.\n * @example\n * const clock = new Tone.Clock(time => {\n * \tconsole.log(time);\n * }, 1);\n * clock.start();\n * // stop the clock after 10 seconds\n * clock.stop("+10");\n */\n stop(time) {\n const computedTime = this.toSeconds(time);\n this.log("stop", computedTime);\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n this._tickSource.stop(computedTime);\n if (computedTime < this._lastUpdate) {\n this.emit("stop", computedTime);\n }\n return this;\n }\n /**\n * Pause the clock. Pausing does not reset the tick counter.\n * @param time The time when the clock should stop.\n */\n pause(time) {\n const computedTime = this.toSeconds(time);\n if (this._state.getValueAtTime(computedTime) === "started") {\n this._state.setStateAtTime("paused", computedTime);\n this._tickSource.pause(computedTime);\n if (computedTime < this._lastUpdate) {\n this.emit("pause", computedTime);\n }\n }\n return this;\n }\n /**\n * The number of times the callback was invoked. Starts counting at 0\n * and increments after the callback was invoked.\n */\n get ticks() {\n return Math.ceil(this.getTicksAtTime(this.now()));\n }\n set ticks(t) {\n this._tickSource.ticks = t;\n }\n /**\n * The time since ticks=0 that the Clock has been running. Accounts for tempo curves\n */\n get seconds() {\n return this._tickSource.seconds;\n }\n set seconds(s) {\n this._tickSource.seconds = s;\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n return this._tickSource.getSecondsAtTime(time);\n }\n /**\n * Set the clock\'s ticks at the given time.\n * @param ticks The tick value to set\n * @param time When to set the tick value\n */\n setTicksAtTime(ticks, time) {\n this._tickSource.setTicksAtTime(ticks, time);\n return this;\n }\n /**\n * Get the time of the given tick. The second argument\n * is when to test before. Since ticks can be set (with setTicksAtTime)\n * there may be multiple times for a given tick value.\n * @param tick The tick number.\n * @param before When to measure the tick value from.\n * @return The time of the tick\n */\n getTimeOfTick(tick, before = this.now()) {\n return this._tickSource.getTimeOfTick(tick, before);\n }\n /**\n * Get the clock\'s ticks at the given time.\n * @param time When to get the tick value\n * @return The tick value at the given time.\n */\n getTicksAtTime(time) {\n return this._tickSource.getTicksAtTime(time);\n }\n /**\n * Get the time of the next tick\n * @param offset The tick number.\n */\n nextTickTime(offset, when) {\n const computedTime = this.toSeconds(when);\n const currentTick = this.getTicksAtTime(computedTime);\n return this._tickSource.getTimeOfTick(currentTick + offset, computedTime);\n }\n /**\n * The scheduling loop.\n */\n _loop() {\n const startTime = this._lastUpdate;\n const endTime = this.now();\n this._lastUpdate = endTime;\n this.log("loop", startTime, endTime);\n if (startTime !== endTime) {\n // the state change events\n this._state.forEachBetween(startTime, endTime, e => {\n switch (e.state) {\n case "started":\n const offset = this._tickSource.getTicksAtTime(e.time);\n this.emit("start", e.time, offset);\n break;\n case "stopped":\n if (e.time !== 0) {\n this.emit("stop", e.time);\n }\n break;\n case "paused":\n this.emit("pause", e.time);\n break;\n }\n });\n // the tick callbacks\n this._tickSource.forEachTickBetween(startTime, endTime, (time, ticks) => {\n this.callback(time, ticks);\n });\n }\n }\n /**\n * Returns the scheduled state at the given time.\n * @param time The time to query.\n * @return The name of the state input in setStateAtTime.\n * @example\n * const clock = new Tone.Clock();\n * clock.start("+0.1");\n * clock.getStateAtTime("+0.1"); // returns "started"\n */\n getStateAtTime(time) {\n const computedTime = this.toSeconds(time);\n return this._state.getValueAtTime(computedTime);\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.context.off("tick", this._boundLoop);\n this._tickSource.dispose();\n this._state.dispose();\n return this;\n }\n}\nEmitter.mixin(Clock_Clock);\n//# sourceMappingURL=Clock.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Delay.js\n\n\n\n\n/**\n * Wrapper around Web Audio\'s native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface).\n * @category Core\n * @example\n * return Tone.Offline(() => {\n * \tconst delay = new Tone.Delay(0.1).toDestination();\n * \t// connect the signal to both the delay and the destination\n * \tconst pulse = new Tone.PulseOscillator().connect(delay).toDestination();\n * \t// start and stop the pulse\n * \tpulse.start(0).stop(0.01);\n * }, 0.5, 1);\n */\nclass Delay_Delay extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Delay_Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]));\n this.name = "Delay";\n const options = optionsFromArguments(Delay_Delay.getDefaults(), arguments, ["delayTime", "maxDelay"]);\n const maxDelayInSeconds = this.toSeconds(options.maxDelay);\n this._maxDelay = Math.max(maxDelayInSeconds, this.toSeconds(options.delayTime));\n this._delayNode = this.input = this.output = this.context.createDelay(maxDelayInSeconds);\n this.delayTime = new Param({\n context: this.context,\n param: this._delayNode.delayTime,\n units: "time",\n value: options.delayTime,\n minValue: 0,\n maxValue: this.maxDelay,\n });\n readOnly(this, "delayTime");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n delayTime: 0,\n maxDelay: 1,\n });\n }\n /**\n * The maximum delay time. This cannot be changed after\n * the value is passed into the constructor.\n */\n get maxDelay() {\n return this._maxDelay;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._delayNode.disconnect();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Delay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Offline.js\n\n\n\n\n/**\n * Generate a buffer by rendering all of the Tone.js code within the callback using the OfflineAudioContext.\n * The OfflineAudioContext is capable of rendering much faster than real time in many cases.\n * The callback function also passes in an offline instance of [[Context]] which can be used\n * to schedule events along the Transport.\n * @param callback All Tone.js nodes which are created and scheduled within this callback are recorded into the output Buffer.\n * @param duration the amount of time to record for.\n * @return The promise which is invoked with the ToneAudioBuffer of the recorded output.\n * @example\n * // render 2 seconds of the oscillator\n * Tone.Offline(() => {\n * \t// only nodes created in this callback will be recorded\n * \tconst oscillator = new Tone.Oscillator().toDestination().start(0);\n * }, 2).then((buffer) => {\n * \t// do something with the output buffer\n * \tconsole.log(buffer);\n * });\n * @example\n * // can also schedule events along the Transport\n * // using the passed in Offline Transport\n * Tone.Offline(({ transport }) => {\n * \tconst osc = new Tone.Oscillator().toDestination();\n * \ttransport.schedule(time => {\n * \t\tosc.start(time).stop(time + 0.1);\n * \t}, 1);\n * \t// make sure to start the transport\n * \ttransport.start(0.2);\n * }, 4).then((buffer) => {\n * \t// do something with the output buffer\n * \tconsole.log(buffer);\n * });\n * @category Core\n */\nfunction Offline(callback, duration, channels = 2, sampleRate = getContext().sampleRate) {\n return __awaiter(this, void 0, void 0, function* () {\n // set the OfflineAudioContext based on the current context\n const originalContext = getContext();\n const context = new OfflineContext(channels, duration, sampleRate);\n setContext(context);\n // invoke the callback/scheduling\n yield callback(context);\n // then render the audio\n const bufferPromise = context.render();\n // return the original AudioContext\n setContext(originalContext);\n // await the rendering\n const buffer = yield bufferPromise;\n // return the audio\n return new ToneAudioBuffer(buffer);\n });\n}\n//# sourceMappingURL=Offline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/ToneAudioBuffers.js\n\n\n\n\n\n\n/**\n * A data structure for holding multiple buffers in a Map-like datastructure.\n *\n * @example\n * const pianoSamples = new Tone.ToneAudioBuffers({\n * \tA1: "https://tonejs.github.io/audio/casio/A1.mp3",\n * \tA2: "https://tonejs.github.io/audio/casio/A2.mp3",\n * }, () => {\n * \tconst player = new Tone.Player().toDestination();\n * \t// play one of the samples when they all load\n * \tplayer.buffer = pianoSamples.get("A2");\n * \tplayer.start();\n * });\n * @example\n * // To pass in additional parameters in the second parameter\n * const buffers = new Tone.ToneAudioBuffers({\n * \t urls: {\n * \t\t A1: "A1.mp3",\n * \t\t A2: "A2.mp3",\n * \t },\n * \t onload: () => console.log("loaded"),\n * \t baseUrl: "https://tonejs.github.io/audio/casio/"\n * });\n * @category Core\n */\nclass ToneAudioBuffers_ToneAudioBuffers extends Tone {\n constructor() {\n super();\n this.name = "ToneAudioBuffers";\n /**\n * All of the buffers\n */\n this._buffers = new Map();\n /**\n * Keep track of the number of loaded buffers\n */\n this._loadingCount = 0;\n const options = Defaults_optionsFromArguments(ToneAudioBuffers_ToneAudioBuffers.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls");\n this.baseUrl = options.baseUrl;\n // add each one\n Object.keys(options.urls).forEach(name => {\n this._loadingCount++;\n const url = options.urls[name];\n this.add(name, url, this._bufferLoaded.bind(this, options.onload), options.onerror);\n });\n }\n static getDefaults() {\n return {\n baseUrl: "",\n onerror: Interface_noOp,\n onload: Interface_noOp,\n urls: {},\n };\n }\n /**\n * True if the buffers object has a buffer by that name.\n * @param name The key or index of the buffer.\n */\n has(name) {\n return this._buffers.has(name.toString());\n }\n /**\n * Get a buffer by name. If an array was loaded,\n * then use the array index.\n * @param name The key or index of the buffer.\n */\n get(name) {\n Debug_assert(this.has(name), `ToneAudioBuffers has no buffer named: ${name}`);\n return this._buffers.get(name.toString());\n }\n /**\n * A buffer was loaded. decrement the counter.\n */\n _bufferLoaded(callback) {\n this._loadingCount--;\n if (this._loadingCount === 0 && callback) {\n callback();\n }\n }\n /**\n * If the buffers are loaded or not\n */\n get loaded() {\n return Array.from(this._buffers).every(([_, buffer]) => buffer.loaded);\n }\n /**\n * Add a buffer by name and url to the Buffers\n * @param name A unique name to give the buffer\n * @param url Either the url of the bufer, or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n * @param onerror Invoked if the buffer can\'t be loaded\n */\n add(name, url, callback = Interface_noOp, onerror = Interface_noOp) {\n if (TypeCheck_isString(url)) {\n this._buffers.set(name.toString(), new ToneAudioBuffer_ToneAudioBuffer(this.baseUrl + url, callback, onerror));\n }\n else {\n this._buffers.set(name.toString(), new ToneAudioBuffer_ToneAudioBuffer(url, callback, onerror));\n }\n return this;\n }\n dispose() {\n super.dispose();\n this._buffers.forEach(buffer => buffer.dispose());\n this._buffers.clear();\n return this;\n }\n}\n//# sourceMappingURL=ToneAudioBuffers.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Midi.js\n\n\n\n/**\n * Midi is a primitive type for encoding Time values.\n * Midi can be constructed with or without the `new` keyword. Midi can be passed\n * into the parameter of any method which takes time as an argument.\n * @category Unit\n */\nclass Midi_MidiClass extends (/* unused pure expression or super */ null && (FrequencyClass)) {\n constructor() {\n super(...arguments);\n this.name = "MidiClass";\n this.defaultUnits = "midi";\n }\n /**\n * Returns the value of a frequency in the current units\n */\n _frequencyToUnits(freq) {\n return ftom(super._frequencyToUnits(freq));\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return ftom(super._ticksToUnits(ticks));\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return ftom(super._beatsToUnits(beats));\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return ftom(super._secondsToUnits(seconds));\n }\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Midi(60).toMidi(); // 60\n */\n toMidi() {\n return this.valueOf();\n }\n /**\n * Return the value of the frequency as a MIDI note\n * @example\n * Tone.Midi(60).toFrequency(); // 261.6255653005986\n */\n toFrequency() {\n return mtof(this.toMidi());\n }\n /**\n * Transposes the frequency by the given number of semitones.\n * @return A new transposed MidiClass\n * @example\n * Tone.Midi("A4").transpose(3); // "C5"\n */\n transpose(interval) {\n return new Midi_MidiClass(this.context, this.toMidi() + interval);\n }\n}\n/**\n * Convert a value into a FrequencyClass object.\n * @category Unit\n */\nfunction Midi(value, units) {\n return new Midi_MidiClass(getContext(), value, units);\n}\n//# sourceMappingURL=Midi.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/type/Ticks.js\n\n\n/**\n * Ticks is a primitive type for encoding Time values.\n * Ticks can be constructed with or without the `new` keyword. Ticks can be passed\n * into the parameter of any method which takes time as an argument.\n * @example\n * const t = Tone.Ticks("4n"); // a quarter note as ticks\n * @category Unit\n */\nclass Ticks_TicksClass extends TransportTime_TransportTimeClass {\n constructor() {\n super(...arguments);\n this.name = "Ticks";\n this.defaultUnits = "i";\n }\n /**\n * Get the current time in the given units\n */\n _now() {\n return this.context.transport.ticks;\n }\n /**\n * Return the value of the beats in the current units\n */\n _beatsToUnits(beats) {\n return this._getPPQ() * beats;\n }\n /**\n * Returns the value of a second in the current units\n */\n _secondsToUnits(seconds) {\n return Math.floor(seconds / (60 / this._getBpm()) * this._getPPQ());\n }\n /**\n * Returns the value of a tick in the current time units\n */\n _ticksToUnits(ticks) {\n return ticks;\n }\n /**\n * Return the time in ticks\n */\n toTicks() {\n return this.valueOf();\n }\n /**\n * Return the time in seconds\n */\n toSeconds() {\n return (this.valueOf() / this._getPPQ()) * (60 / this._getBpm());\n }\n}\n/**\n * Convert a time representation to ticks\n * @category Unit\n */\nfunction Ticks(value, units) {\n return new Ticks_TicksClass(getContext(), value, units);\n}\n//# sourceMappingURL=Ticks.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Draw.js\n\n\n\n/**\n * Draw is useful for synchronizing visuals and audio events.\n * Callbacks from Tone.Transport or any of the Tone.Event classes\n * always happen _before_ the scheduled time and are not synchronized\n * to the animation frame so they are not good for triggering tightly\n * synchronized visuals and sound. Draw makes it easy to schedule\n * callbacks using the AudioContext time and uses requestAnimationFrame.\n * @example\n * Tone.Transport.schedule((time) => {\n * \t// use the time argument to schedule a callback with Draw\n * \tTone.Draw.schedule(() => {\n * \t\t// do drawing or DOM manipulation here\n * \t\tconsole.log(time);\n * \t}, time);\n * }, "+0.5");\n * Tone.Transport.start();\n * @category Core\n */\nclass Draw extends ToneWithContext_ToneWithContext {\n constructor() {\n super(...arguments);\n this.name = "Draw";\n /**\n * The duration after which events are not invoked.\n */\n this.expiration = 0.25;\n /**\n * The amount of time before the scheduled time\n * that the callback can be invoked. Default is\n * half the time of an animation frame (0.008 seconds).\n */\n this.anticipation = 0.008;\n /**\n * All of the events.\n */\n this._events = new Timeline();\n /**\n * The draw loop\n */\n this._boundDrawLoop = this._drawLoop.bind(this);\n /**\n * The animation frame id\n */\n this._animationFrame = -1;\n }\n /**\n * Schedule a function at the given time to be invoked\n * on the nearest animation frame.\n * @param callback Callback is invoked at the given time.\n * @param time The time relative to the AudioContext time to invoke the callback.\n * @example\n * Tone.Transport.scheduleRepeat(time => {\n * \tTone.Draw.schedule(() => console.log(time), time);\n * }, 1);\n * Tone.Transport.start();\n */\n schedule(callback, time) {\n this._events.add({\n callback,\n time: this.toSeconds(time),\n });\n // start the draw loop on the first event\n if (this._events.length === 1) {\n this._animationFrame = requestAnimationFrame(this._boundDrawLoop);\n }\n return this;\n }\n /**\n * Cancel events scheduled after the given time\n * @param after Time after which scheduled events will be removed from the scheduling timeline.\n */\n cancel(after) {\n this._events.cancel(this.toSeconds(after));\n return this;\n }\n /**\n * The draw loop\n */\n _drawLoop() {\n const now = this.context.currentTime;\n while (this._events.length && this._events.peek().time - this.anticipation <= now) {\n const event = this._events.shift();\n if (event && now - event.time <= this.expiration) {\n event.callback();\n }\n }\n if (this._events.length > 0) {\n this._animationFrame = requestAnimationFrame(this._boundDrawLoop);\n }\n }\n dispose() {\n super.dispose();\n this._events.dispose();\n cancelAnimationFrame(this._animationFrame);\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.draw = new Draw({ context });\n});\nonContextClose(context => {\n context.draw.dispose();\n});\n//# sourceMappingURL=Draw.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/IntervalTimeline.js\n\n\n\n/**\n * Similar to Tone.Timeline, but all events represent\n * intervals with both "time" and "duration" times. The\n * events are placed in a tree structure optimized\n * for querying an intersection point with the timeline\n * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree)\n * to represent the data.\n */\nclass IntervalTimeline extends Tone {\n constructor() {\n super(...arguments);\n this.name = "IntervalTimeline";\n /**\n * The root node of the inteval tree\n */\n this._root = null;\n /**\n * Keep track of the length of the timeline.\n */\n this._length = 0;\n }\n /**\n * The event to add to the timeline. All events must\n * have a time and duration value\n * @param event The event to add to the timeline\n */\n add(event) {\n Debug_assert(TypeCheck_isDefined(event.time), "Events must have a time property");\n Debug_assert(TypeCheck_isDefined(event.duration), "Events must have a duration parameter");\n event.time = event.time.valueOf();\n let node = new IntervalNode(event.time, event.time + event.duration, event);\n if (this._root === null) {\n this._root = node;\n }\n else {\n this._root.insert(node);\n }\n this._length++;\n // Restructure tree to be balanced\n while (node !== null) {\n node.updateHeight();\n node.updateMax();\n this._rebalance(node);\n node = node.parent;\n }\n return this;\n }\n /**\n * Remove an event from the timeline.\n * @param event The event to remove from the timeline\n */\n remove(event) {\n if (this._root !== null) {\n const results = [];\n this._root.search(event.time, results);\n for (const node of results) {\n if (node.event === event) {\n this._removeNode(node);\n this._length--;\n break;\n }\n }\n }\n return this;\n }\n /**\n * The number of items in the timeline.\n * @readOnly\n */\n get length() {\n return this._length;\n }\n /**\n * Remove events whose time time is after the given time\n * @param after The time to query.\n */\n cancel(after) {\n this.forEachFrom(after, event => this.remove(event));\n return this;\n }\n /**\n * Set the root node as the given node\n */\n _setRoot(node) {\n this._root = node;\n if (this._root !== null) {\n this._root.parent = null;\n }\n }\n /**\n * Replace the references to the node in the node\'s parent\n * with the replacement node.\n */\n _replaceNodeInParent(node, replacement) {\n if (node.parent !== null) {\n if (node.isLeftChild()) {\n node.parent.left = replacement;\n }\n else {\n node.parent.right = replacement;\n }\n this._rebalance(node.parent);\n }\n else {\n this._setRoot(replacement);\n }\n }\n /**\n * Remove the node from the tree and replace it with\n * a successor which follows the schema.\n */\n _removeNode(node) {\n if (node.left === null && node.right === null) {\n this._replaceNodeInParent(node, null);\n }\n else if (node.right === null) {\n this._replaceNodeInParent(node, node.left);\n }\n else if (node.left === null) {\n this._replaceNodeInParent(node, node.right);\n }\n else {\n const balance = node.getBalance();\n let replacement;\n let temp = null;\n if (balance > 0) {\n if (node.left.right === null) {\n replacement = node.left;\n replacement.right = node.right;\n temp = replacement;\n }\n else {\n replacement = node.left.right;\n while (replacement.right !== null) {\n replacement = replacement.right;\n }\n if (replacement.parent) {\n replacement.parent.right = replacement.left;\n temp = replacement.parent;\n replacement.left = node.left;\n replacement.right = node.right;\n }\n }\n }\n else if (node.right.left === null) {\n replacement = node.right;\n replacement.left = node.left;\n temp = replacement;\n }\n else {\n replacement = node.right.left;\n while (replacement.left !== null) {\n replacement = replacement.left;\n }\n if (replacement.parent) {\n replacement.parent.left = replacement.right;\n temp = replacement.parent;\n replacement.left = node.left;\n replacement.right = node.right;\n }\n }\n if (node.parent !== null) {\n if (node.isLeftChild()) {\n node.parent.left = replacement;\n }\n else {\n node.parent.right = replacement;\n }\n }\n else {\n this._setRoot(replacement);\n }\n if (temp) {\n this._rebalance(temp);\n }\n }\n node.dispose();\n }\n /**\n * Rotate the tree to the left\n */\n _rotateLeft(node) {\n const parent = node.parent;\n const isLeftChild = node.isLeftChild();\n // Make node.right the new root of this sub tree (instead of node)\n const pivotNode = node.right;\n if (pivotNode) {\n node.right = pivotNode.left;\n pivotNode.left = node;\n }\n if (parent !== null) {\n if (isLeftChild) {\n parent.left = pivotNode;\n }\n else {\n parent.right = pivotNode;\n }\n }\n else {\n this._setRoot(pivotNode);\n }\n }\n /**\n * Rotate the tree to the right\n */\n _rotateRight(node) {\n const parent = node.parent;\n const isLeftChild = node.isLeftChild();\n // Make node.left the new root of this sub tree (instead of node)\n const pivotNode = node.left;\n if (pivotNode) {\n node.left = pivotNode.right;\n pivotNode.right = node;\n }\n if (parent !== null) {\n if (isLeftChild) {\n parent.left = pivotNode;\n }\n else {\n parent.right = pivotNode;\n }\n }\n else {\n this._setRoot(pivotNode);\n }\n }\n /**\n * Balance the BST\n */\n _rebalance(node) {\n const balance = node.getBalance();\n if (balance > 1 && node.left) {\n if (node.left.getBalance() < 0) {\n this._rotateLeft(node.left);\n }\n else {\n this._rotateRight(node);\n }\n }\n else if (balance < -1 && node.right) {\n if (node.right.getBalance() > 0) {\n this._rotateRight(node.right);\n }\n else {\n this._rotateLeft(node);\n }\n }\n }\n /**\n * Get an event whose time and duration span the give time. Will\n * return the match whose "time" value is closest to the given time.\n * @return The event which spans the desired time\n */\n get(time) {\n if (this._root !== null) {\n const results = [];\n this._root.search(time, results);\n if (results.length > 0) {\n let max = results[0];\n for (let i = 1; i < results.length; i++) {\n if (results[i].low > max.low) {\n max = results[i];\n }\n }\n return max.event;\n }\n }\n return null;\n }\n /**\n * Iterate over everything in the timeline.\n * @param callback The callback to invoke with every item\n */\n forEach(callback) {\n if (this._root !== null) {\n const allNodes = [];\n this._root.traverse(node => allNodes.push(node));\n allNodes.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Iterate over everything in the array in which the given time\n * overlaps with the time and duration time of the event.\n * @param time The time to check if items are overlapping\n * @param callback The callback to invoke with every item\n */\n forEachAtTime(time, callback) {\n if (this._root !== null) {\n const results = [];\n this._root.search(time, results);\n results.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Iterate over everything in the array in which the time is greater\n * than or equal to the given time.\n * @param time The time to check if items are before\n * @param callback The callback to invoke with every item\n */\n forEachFrom(time, callback) {\n if (this._root !== null) {\n const results = [];\n this._root.searchAfter(time, results);\n results.forEach(node => {\n if (node.event) {\n callback(node.event);\n }\n });\n }\n return this;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n if (this._root !== null) {\n this._root.traverse(node => node.dispose());\n }\n this._root = null;\n return this;\n }\n}\n//-------------------------------------\n// \tINTERVAL NODE HELPER\n//-------------------------------------\n/**\n * Represents a node in the binary search tree, with the addition\n * of a "high" value which keeps track of the highest value of\n * its children.\n * References:\n * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/\n * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf\n * @param low\n * @param high\n */\nclass IntervalNode {\n constructor(low, high, event) {\n // the nodes to the left\n this._left = null;\n // the nodes to the right\n this._right = null;\n // the parent node\n this.parent = null;\n // the number of child nodes\n this.height = 0;\n this.event = event;\n // the low value\n this.low = low;\n // the high value\n this.high = high;\n // the high value for this and all child nodes\n this.max = this.high;\n }\n /**\n * Insert a node into the correct spot in the tree\n */\n insert(node) {\n if (node.low <= this.low) {\n if (this.left === null) {\n this.left = node;\n }\n else {\n this.left.insert(node);\n }\n }\n else if (this.right === null) {\n this.right = node;\n }\n else {\n this.right.insert(node);\n }\n }\n /**\n * Search the tree for nodes which overlap\n * with the given point\n * @param point The point to query\n * @param results The array to put the results\n */\n search(point, results) {\n // If p is to the right of the rightmost point of any interval\n // in this node and all children, there won\'t be any matches.\n if (point > this.max) {\n return;\n }\n // Search left children\n if (this.left !== null) {\n this.left.search(point, results);\n }\n // Check this node\n if (this.low <= point && this.high > point) {\n results.push(this);\n }\n // If p is to the left of the time of this interval,\n // then it can\'t be in any child to the right.\n if (this.low > point) {\n return;\n }\n // Search right children\n if (this.right !== null) {\n this.right.search(point, results);\n }\n }\n /**\n * Search the tree for nodes which are less\n * than the given point\n * @param point The point to query\n * @param results The array to put the results\n */\n searchAfter(point, results) {\n // Check this node\n if (this.low >= point) {\n results.push(this);\n if (this.left !== null) {\n this.left.searchAfter(point, results);\n }\n }\n // search the right side\n if (this.right !== null) {\n this.right.searchAfter(point, results);\n }\n }\n /**\n * Invoke the callback on this element and both it\'s branches\n * @param {Function} callback\n */\n traverse(callback) {\n callback(this);\n if (this.left !== null) {\n this.left.traverse(callback);\n }\n if (this.right !== null) {\n this.right.traverse(callback);\n }\n }\n /**\n * Update the height of the node\n */\n updateHeight() {\n if (this.left !== null && this.right !== null) {\n this.height = Math.max(this.left.height, this.right.height) + 1;\n }\n else if (this.right !== null) {\n this.height = this.right.height + 1;\n }\n else if (this.left !== null) {\n this.height = this.left.height + 1;\n }\n else {\n this.height = 0;\n }\n }\n /**\n * Update the height of the node\n */\n updateMax() {\n this.max = this.high;\n if (this.left !== null) {\n this.max = Math.max(this.max, this.left.max);\n }\n if (this.right !== null) {\n this.max = Math.max(this.max, this.right.max);\n }\n }\n /**\n * The balance is how the leafs are distributed on the node\n * @return Negative numbers are balanced to the right\n */\n getBalance() {\n let balance = 0;\n if (this.left !== null && this.right !== null) {\n balance = this.left.height - this.right.height;\n }\n else if (this.left !== null) {\n balance = this.left.height + 1;\n }\n else if (this.right !== null) {\n balance = -(this.right.height + 1);\n }\n return balance;\n }\n /**\n * @returns true if this node is the left child of its parent\n */\n isLeftChild() {\n return this.parent !== null && this.parent.left === this;\n }\n /**\n * get/set the left node\n */\n get left() {\n return this._left;\n }\n set left(node) {\n this._left = node;\n if (node !== null) {\n node.parent = this;\n }\n this.updateHeight();\n this.updateMax();\n }\n /**\n * get/set the right node\n */\n get right() {\n return this._right;\n }\n set right(node) {\n this._right = node;\n if (node !== null) {\n node.parent = this;\n }\n this.updateHeight();\n this.updateMax();\n }\n /**\n * null out references.\n */\n dispose() {\n this.parent = null;\n this._left = null;\n this._right = null;\n this.event = null;\n }\n}\n//# sourceMappingURL=IntervalTimeline.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/index.js\n\n// export * from "./clock/Transport";\n\n\n\n// export * from "./context/Destination";\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// get the units and export them under the "Unit" namespace\n\n\n// export the debug stuff as Debug\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Volume.js\n\n\n\n\n/**\n * Volume is a simple volume node, useful for creating a volume fader.\n *\n * @example\n * const vol = new Tone.Volume(-12).toDestination();\n * const osc = new Tone.Oscillator().connect(vol).start();\n * @category Component\n */\nclass Volume_Volume extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Volume_Volume.getDefaults(), arguments, ["volume"]));\n this.name = "Volume";\n const options = Defaults_optionsFromArguments(Volume_Volume.getDefaults(), arguments, ["volume"]);\n this.input = this.output = new Gain_Gain({\n context: this.context,\n gain: options.volume,\n units: "decibels",\n });\n this.volume = this.output.gain;\n Interface_readOnly(this, "volume");\n this._unmutedVolume = options.volume;\n // set the mute initially\n this.mute = options.mute;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0,\n });\n }\n /**\n * Mute the output.\n * @example\n * const vol = new Tone.Volume(-12).toDestination();\n * const osc = new Tone.Oscillator().connect(vol).start();\n * // mute the output\n * vol.mute = true;\n */\n get mute() {\n return this.volume.value === -Infinity;\n }\n set mute(mute) {\n if (!this.mute && mute) {\n this._unmutedVolume = this.volume.value;\n // maybe it should ramp here?\n this.volume.value = -Infinity;\n }\n else if (this.mute && !mute) {\n this.volume.value = this._unmutedVolume;\n }\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this.input.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Volume.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Destination.js\n\n\n\n\n\n/**\n * A single master output which is connected to the\n * AudioDestinationNode (aka your speakers).\n * It provides useful conveniences such as the ability\n * to set the volume and mute the entire application.\n * It also gives you the ability to apply master effects to your application.\n *\n * @example\n * const oscillator = new Tone.Oscillator().start();\n * // the audio will go from the oscillator to the speakers\n * oscillator.connect(Tone.getDestination());\n * // a convenience for connecting to the master output is also provided:\n * oscillator.toDestination();\n * @category Core\n */\nclass Destination extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Destination.getDefaults(), arguments));\n this.name = "Destination";\n this.input = new Volume_Volume({ context: this.context });\n this.output = new Gain_Gain({ context: this.context });\n /**\n * The volume of the master output in decibels. -Infinity is silent, and 0 is no change.\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * osc.start();\n * // ramp the volume down to silent over 10 seconds\n * Tone.getDestination().volume.rampTo(-Infinity, 10);\n */\n this.volume = this.input.volume;\n const options = Defaults_optionsFromArguments(Destination.getDefaults(), arguments);\n ToneAudioNode_connectSeries(this.input, this.output, this.context.rawContext.destination);\n this.mute = options.mute;\n this._internalChannels = [this.input, this.context.rawContext.destination, this.output];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0,\n });\n }\n /**\n * Mute the output.\n * @example\n * const oscillator = new Tone.Oscillator().start().toDestination();\n * setTimeout(() => {\n * \t// mute the output\n * \tTone.Destination.mute = true;\n * }, 1000);\n */\n get mute() {\n return this.input.mute;\n }\n set mute(mute) {\n this.input.mute = mute;\n }\n /**\n * Add a master effects chain. NOTE: this will disconnect any nodes which were previously\n * chained in the master effects chain.\n * @param args All arguments will be connected in a row and the Master will be routed through it.\n * @example\n * // route all audio through a filter and compressor\n * const lowpass = new Tone.Filter(800, "lowpass");\n * const compressor = new Tone.Compressor(-18);\n * Tone.Destination.chain(lowpass, compressor);\n */\n chain(...args) {\n this.input.disconnect();\n args.unshift(this.input);\n args.push(this.output);\n ToneAudioNode_connectSeries(...args);\n return this;\n }\n /**\n * The maximum number of channels the system can output\n * @example\n * console.log(Tone.Destination.maxChannelCount);\n */\n get maxChannelCount() {\n return this.context.rawContext.destination.maxChannelCount;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.destination = new Destination({ context });\n});\nonContextClose(context => {\n context.destination.dispose();\n});\n//# sourceMappingURL=Destination.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/TimelineValue.js\n\n\n/**\n * Represents a single value which is gettable and settable in a timed way\n */\nclass TimelineValue extends Tone {\n /**\n * @param initialValue The value to return if there is no scheduled values\n */\n constructor(initialValue) {\n super();\n this.name = "TimelineValue";\n /**\n * The timeline which stores the values\n */\n this._timeline = new Timeline({ memory: 10 });\n this._initialValue = initialValue;\n }\n /**\n * Set the value at the given time\n */\n set(value, time) {\n this._timeline.add({\n value, time\n });\n return this;\n }\n /**\n * Get the value at the given time\n */\n get(time) {\n const event = this._timeline.get(time);\n if (event) {\n return event.value;\n }\n else {\n return this._initialValue;\n }\n }\n}\n//# sourceMappingURL=TimelineValue.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TransportEvent.js\n\n/**\n * TransportEvent is an internal class used by [[Transport]]\n * to schedule events. Do no invoke this class directly, it is\n * handled from within Tone.Transport.\n */\nclass TransportEvent {\n /**\n * @param transport The transport object which the event belongs to\n */\n constructor(transport, opts) {\n /**\n * The unique id of the event\n */\n this.id = TransportEvent._eventId++;\n const options = Object.assign(TransportEvent.getDefaults(), opts);\n this.transport = transport;\n this.callback = options.callback;\n this._once = options.once;\n this.time = options.time;\n }\n static getDefaults() {\n return {\n callback: Interface_noOp,\n once: false,\n time: 0,\n };\n }\n /**\n * Invoke the event callback.\n * @param time The AudioContext time in seconds of the event\n */\n invoke(time) {\n if (this.callback) {\n this.callback(time);\n if (this._once) {\n this.transport.clear(this.id);\n }\n }\n }\n /**\n * Clean up\n */\n dispose() {\n this.callback = undefined;\n return this;\n }\n}\n/**\n * Current ID counter\n */\nTransportEvent._eventId = 0;\n//# sourceMappingURL=TransportEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/TransportRepeatEvent.js\n\n\n/**\n * TransportRepeatEvent is an internal class used by Tone.Transport\n * to schedule repeat events. This class should not be instantiated directly.\n */\nclass TransportRepeatEvent extends TransportEvent {\n /**\n * @param transport The transport object which the event belongs to\n */\n constructor(transport, opts) {\n super(transport, opts);\n /**\n * The ID of the current timeline event\n */\n this._currentId = -1;\n /**\n * The ID of the next timeline event\n */\n this._nextId = -1;\n /**\n * The time of the next event\n */\n this._nextTick = this.time;\n /**\n * a reference to the bound start method\n */\n this._boundRestart = this._restart.bind(this);\n const options = Object.assign(TransportRepeatEvent.getDefaults(), opts);\n this.duration = new Ticks_TicksClass(transport.context, options.duration).valueOf();\n this._interval = new Ticks_TicksClass(transport.context, options.interval).valueOf();\n this._nextTick = options.time;\n this.transport.on("start", this._boundRestart);\n this.transport.on("loopStart", this._boundRestart);\n this.context = this.transport.context;\n this._restart();\n }\n static getDefaults() {\n return Object.assign({}, TransportEvent.getDefaults(), {\n duration: Infinity,\n interval: 1,\n once: false,\n });\n }\n /**\n * Invoke the callback. Returns the tick time which\n * the next event should be scheduled at.\n * @param time The AudioContext time in seconds of the event\n */\n invoke(time) {\n // create more events if necessary\n this._createEvents(time);\n // call the super class\n super.invoke(time);\n }\n /**\n * Push more events onto the timeline to keep up with the position of the timeline\n */\n _createEvents(time) {\n // schedule the next event\n const ticks = this.transport.getTicksAtTime(time);\n if (ticks >= this.time && ticks >= this._nextTick && this._nextTick + this._interval < this.time + this.duration) {\n this._nextTick += this._interval;\n this._currentId = this._nextId;\n this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n }\n }\n /**\n * Push more events onto the timeline to keep up with the position of the timeline\n */\n _restart(time) {\n this.transport.clear(this._currentId);\n this.transport.clear(this._nextId);\n this._nextTick = this.time;\n const ticks = this.transport.getTicksAtTime(time);\n if (ticks > this.time) {\n this._nextTick = this.time + Math.ceil((ticks - this.time) / this._interval) * this._interval;\n }\n this._currentId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n this._nextTick += this._interval;\n this._nextId = this.transport.scheduleOnce(this.invoke.bind(this), new Ticks_TicksClass(this.context, this._nextTick).toSeconds());\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this.transport.clear(this._currentId);\n this.transport.clear(this._nextId);\n this.transport.off("start", this._boundRestart);\n this.transport.off("loopStart", this._boundRestart);\n return this;\n }\n}\n//# sourceMappingURL=TransportRepeatEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/clock/Transport.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Transport for timing musical events.\n * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame)\n * Transport timing events pass in the exact time of the scheduled event\n * in the argument of the callback function. Pass that time value to the object\n * you\'re scheduling. <br><br>\n * A single transport is created for you when the library is initialized.\n * <br><br>\n * The transport emits the events: "start", "stop", "pause", and "loop" which are\n * called with the time of that event as the argument.\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * // repeated event every 8th note\n * Tone.Transport.scheduleRepeat((time) => {\n * \t// use the callback time to schedule events\n * \tosc.start(time).stop(time + 0.1);\n * }, "8n");\n * // transport must be started before it starts invoking events\n * Tone.Transport.start();\n * @category Core\n */\nclass Transport extends ToneWithContext_ToneWithContext {\n constructor() {\n super(Defaults_optionsFromArguments(Transport.getDefaults(), arguments));\n this.name = "Transport";\n //-------------------------------------\n // \tLOOPING\n //-------------------------------------\n /**\n * If the transport loops or not.\n */\n this._loop = new TimelineValue(false);\n /**\n * The loop start position in ticks\n */\n this._loopStart = 0;\n /**\n * The loop end position in ticks\n */\n this._loopEnd = 0;\n //-------------------------------------\n // \tTIMELINE EVENTS\n //-------------------------------------\n /**\n * All the events in an object to keep track by ID\n */\n this._scheduledEvents = {};\n /**\n * The scheduled events.\n */\n this._timeline = new Timeline();\n /**\n * Repeated events\n */\n this._repeatedEvents = new IntervalTimeline();\n /**\n * All of the synced Signals\n */\n this._syncedSignals = [];\n /**\n * The swing amount\n */\n this._swingAmount = 0;\n const options = Defaults_optionsFromArguments(Transport.getDefaults(), arguments);\n // CLOCK/TEMPO\n this._ppq = options.ppq;\n this._clock = new Clock_Clock({\n callback: this._processTick.bind(this),\n context: this.context,\n frequency: 0,\n units: "bpm",\n });\n this._bindClockEvents();\n this.bpm = this._clock.frequency;\n this._clock.frequency.multiplier = options.ppq;\n this.bpm.setValueAtTime(options.bpm, 0);\n Interface_readOnly(this, "bpm");\n this._timeSignature = options.timeSignature;\n // SWING\n this._swingTicks = options.ppq / 2; // 8n\n }\n static getDefaults() {\n return Object.assign(ToneWithContext_ToneWithContext.getDefaults(), {\n bpm: 120,\n loopEnd: "4m",\n loopStart: 0,\n ppq: 192,\n swing: 0,\n swingSubdivision: "8n",\n timeSignature: 4,\n });\n }\n //-------------------------------------\n // \tTICKS\n //-------------------------------------\n /**\n * called on every tick\n * @param tickTime clock relative tick time\n */\n _processTick(tickTime, ticks) {\n // do the loop test\n if (this._loop.get(tickTime)) {\n if (ticks >= this._loopEnd) {\n this.emit("loopEnd", tickTime);\n this._clock.setTicksAtTime(this._loopStart, tickTime);\n ticks = this._loopStart;\n this.emit("loopStart", tickTime, this._clock.getSecondsAtTime(tickTime));\n this.emit("loop", tickTime);\n }\n }\n // handle swing\n if (this._swingAmount > 0 &&\n ticks % this._ppq !== 0 && // not on a downbeat\n ticks % (this._swingTicks * 2) !== 0) {\n // add some swing\n const progress = (ticks % (this._swingTicks * 2)) / (this._swingTicks * 2);\n const amount = Math.sin((progress) * Math.PI) * this._swingAmount;\n tickTime += new Ticks_TicksClass(this.context, this._swingTicks * 2 / 3).toSeconds() * amount;\n }\n // invoke the timeline events scheduled on this tick\n this._timeline.forEachAtTime(ticks, event => event.invoke(tickTime));\n }\n //-------------------------------------\n // \tSCHEDULABLE EVENTS\n //-------------------------------------\n /**\n * Schedule an event along the timeline.\n * @param callback The callback to be invoked at the time.\n * @param time The time to invoke the callback at.\n * @return The id of the event which can be used for canceling the event.\n * @example\n * // schedule an event on the 16th measure\n * Tone.Transport.schedule((time) => {\n * \t// invoked on measure 16\n * \tconsole.log("measure 16!");\n * }, "16:0:0");\n */\n schedule(callback, time) {\n const event = new TransportEvent(this, {\n callback,\n time: new TransportTime_TransportTimeClass(this.context, time).toTicks(),\n });\n return this._addEvent(event, this._timeline);\n }\n /**\n * Schedule a repeated event along the timeline. The event will fire\n * at the `interval` starting at the `startTime` and for the specified\n * `duration`.\n * @param callback The callback to invoke.\n * @param interval The duration between successive callbacks. Must be a positive number.\n * @param startTime When along the timeline the events should start being invoked.\n * @param duration How long the event should repeat.\n * @return The ID of the scheduled event. Use this to cancel the event.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // a callback invoked every eighth note after the first measure\n * Tone.Transport.scheduleRepeat((time) => {\n * \tosc.start(time).stop(time + 0.1);\n * }, "8n", "1m");\n */\n scheduleRepeat(callback, interval, startTime, duration = Infinity) {\n const event = new TransportRepeatEvent(this, {\n callback,\n duration: new TimeClass(this.context, duration).toTicks(),\n interval: new TimeClass(this.context, interval).toTicks(),\n time: new TransportTime_TransportTimeClass(this.context, startTime).toTicks(),\n });\n // kick it off if the Transport is started\n // @ts-ignore\n return this._addEvent(event, this._repeatedEvents);\n }\n /**\n * Schedule an event that will be removed after it is invoked.\n * @param callback The callback to invoke once.\n * @param time The time the callback should be invoked.\n * @returns The ID of the scheduled event.\n */\n scheduleOnce(callback, time) {\n const event = new TransportEvent(this, {\n callback,\n once: true,\n time: new TransportTime_TransportTimeClass(this.context, time).toTicks(),\n });\n return this._addEvent(event, this._timeline);\n }\n /**\n * Clear the passed in event id from the timeline\n * @param eventId The id of the event.\n */\n clear(eventId) {\n if (this._scheduledEvents.hasOwnProperty(eventId)) {\n const item = this._scheduledEvents[eventId.toString()];\n item.timeline.remove(item.event);\n item.event.dispose();\n delete this._scheduledEvents[eventId.toString()];\n }\n return this;\n }\n /**\n * Add an event to the correct timeline. Keep track of the\n * timeline it was added to.\n * @returns the event id which was just added\n */\n _addEvent(event, timeline) {\n this._scheduledEvents[event.id.toString()] = {\n event,\n timeline,\n };\n timeline.add(event);\n return event.id;\n }\n /**\n * Remove scheduled events from the timeline after\n * the given time. Repeated events will be removed\n * if their startTime is after the given time\n * @param after Clear all events after this time.\n */\n cancel(after = 0) {\n const computedAfter = this.toTicks(after);\n this._timeline.forEachFrom(computedAfter, event => this.clear(event.id));\n this._repeatedEvents.forEachFrom(computedAfter, event => this.clear(event.id));\n return this;\n }\n //-------------------------------------\n // \tSTART/STOP/PAUSE\n //-------------------------------------\n /**\n * Bind start/stop/pause events from the clock and emit them.\n */\n _bindClockEvents() {\n this._clock.on("start", (time, offset) => {\n offset = new Ticks_TicksClass(this.context, offset).toSeconds();\n this.emit("start", time, offset);\n });\n this._clock.on("stop", (time) => {\n this.emit("stop", time);\n });\n this._clock.on("pause", (time) => {\n this.emit("pause", time);\n });\n }\n /**\n * Returns the playback state of the source, either "started", "stopped", or "paused"\n */\n get state() {\n return this._clock.getStateAtTime(this.now());\n }\n /**\n * Start the transport and all sources synced to the transport.\n * @param time The time when the transport should start.\n * @param offset The timeline offset to start the transport.\n * @example\n * // start the transport in one second starting at beginning of the 5th measure.\n * Tone.Transport.start("+1", "4:0:0");\n */\n start(time, offset) {\n let offsetTicks;\n if (TypeCheck_isDefined(offset)) {\n offsetTicks = this.toTicks(offset);\n }\n // start the clock\n this._clock.start(time, offsetTicks);\n return this;\n }\n /**\n * Stop the transport and all sources synced to the transport.\n * @param time The time when the transport should stop.\n * @example\n * Tone.Transport.stop();\n */\n stop(time) {\n this._clock.stop(time);\n return this;\n }\n /**\n * Pause the transport and all sources synced to the transport.\n */\n pause(time) {\n this._clock.pause(time);\n return this;\n }\n /**\n * Toggle the current state of the transport. If it is\n * started, it will stop it, otherwise it will start the Transport.\n * @param time The time of the event\n */\n toggle(time) {\n time = this.toSeconds(time);\n if (this._clock.getStateAtTime(time) !== "started") {\n this.start(time);\n }\n else {\n this.stop(time);\n }\n return this;\n }\n //-------------------------------------\n // \tSETTERS/GETTERS\n //-------------------------------------\n /**\n * The time signature as just the numerator over 4.\n * For example 4/4 would be just 4 and 6/8 would be 3.\n * @example\n * // common time\n * Tone.Transport.timeSignature = 4;\n * // 7/8\n * Tone.Transport.timeSignature = [7, 8];\n * // this will be reduced to a single number\n * Tone.Transport.timeSignature; // returns 3.5\n */\n get timeSignature() {\n return this._timeSignature;\n }\n set timeSignature(timeSig) {\n if (TypeCheck_isArray(timeSig)) {\n timeSig = (timeSig[0] / timeSig[1]) * 4;\n }\n this._timeSignature = timeSig;\n }\n /**\n * When the Transport.loop = true, this is the starting position of the loop.\n */\n get loopStart() {\n return new TimeClass(this.context, this._loopStart, "i").toSeconds();\n }\n set loopStart(startPosition) {\n this._loopStart = this.toTicks(startPosition);\n }\n /**\n * When the Transport.loop = true, this is the ending position of the loop.\n */\n get loopEnd() {\n return new TimeClass(this.context, this._loopEnd, "i").toSeconds();\n }\n set loopEnd(endPosition) {\n this._loopEnd = this.toTicks(endPosition);\n }\n /**\n * If the transport loops or not.\n */\n get loop() {\n return this._loop.get(this.now());\n }\n set loop(loop) {\n this._loop.set(loop, this.now());\n }\n /**\n * Set the loop start and stop at the same time.\n * @example\n * // loop over the first measure\n * Tone.Transport.setLoopPoints(0, "1m");\n * Tone.Transport.loop = true;\n */\n setLoopPoints(startPosition, endPosition) {\n this.loopStart = startPosition;\n this.loopEnd = endPosition;\n return this;\n }\n /**\n * The swing value. Between 0-1 where 1 equal to the note + half the subdivision.\n */\n get swing() {\n return this._swingAmount;\n }\n set swing(amount) {\n // scale the values to a normal range\n this._swingAmount = amount;\n }\n /**\n * Set the subdivision which the swing will be applied to.\n * The default value is an 8th note. Value must be less\n * than a quarter note.\n */\n get swingSubdivision() {\n return new Ticks_TicksClass(this.context, this._swingTicks).toNotation();\n }\n set swingSubdivision(subdivision) {\n this._swingTicks = this.toTicks(subdivision);\n }\n /**\n * The Transport\'s position in Bars:Beats:Sixteenths.\n * Setting the value will jump to that position right away.\n */\n get position() {\n const now = this.now();\n const ticks = this._clock.getTicksAtTime(now);\n return new Ticks_TicksClass(this.context, ticks).toBarsBeatsSixteenths();\n }\n set position(progress) {\n const ticks = this.toTicks(progress);\n this.ticks = ticks;\n }\n /**\n * The Transport\'s position in seconds\n * Setting the value will jump to that position right away.\n */\n get seconds() {\n return this._clock.seconds;\n }\n set seconds(s) {\n const now = this.now();\n const ticks = this._clock.frequency.timeToTicks(s, now);\n this.ticks = ticks;\n }\n /**\n * The Transport\'s loop position as a normalized value. Always\n * returns 0 if the transport if loop is not true.\n */\n get progress() {\n if (this.loop) {\n const now = this.now();\n const ticks = this._clock.getTicksAtTime(now);\n return (ticks - this._loopStart) / (this._loopEnd - this._loopStart);\n }\n else {\n return 0;\n }\n }\n /**\n * The transports current tick position.\n */\n get ticks() {\n return this._clock.ticks;\n }\n set ticks(t) {\n if (this._clock.ticks !== t) {\n const now = this.now();\n // stop everything synced to the transport\n if (this.state === "started") {\n const ticks = this._clock.getTicksAtTime(now);\n // schedule to start on the next tick, #573\n const remainingTick = this._clock.frequency.getDurationOfTicks(Math.ceil(ticks) - ticks, now);\n const time = now + remainingTick;\n this.emit("stop", time);\n this._clock.setTicksAtTime(t, time);\n // restart it with the new time\n this.emit("start", time, this._clock.getSecondsAtTime(time));\n }\n else {\n this._clock.setTicksAtTime(t, now);\n }\n }\n }\n /**\n * Get the clock\'s ticks at the given time.\n * @param time When to get the tick value\n * @return The tick value at the given time.\n */\n getTicksAtTime(time) {\n return Math.round(this._clock.getTicksAtTime(time));\n }\n /**\n * Return the elapsed seconds at the given time.\n * @param time When to get the elapsed seconds\n * @return The number of elapsed seconds\n */\n getSecondsAtTime(time) {\n return this._clock.getSecondsAtTime(time);\n }\n /**\n * Pulses Per Quarter note. This is the smallest resolution\n * the Transport timing supports. This should be set once\n * on initialization and not set again. Changing this value\n * after other objects have been created can cause problems.\n */\n get PPQ() {\n return this._clock.frequency.multiplier;\n }\n set PPQ(ppq) {\n this._clock.frequency.multiplier = ppq;\n }\n //-------------------------------------\n // \tSYNCING\n //-------------------------------------\n /**\n * Returns the time aligned to the next subdivision\n * of the Transport. If the Transport is not started,\n * it will return 0.\n * Note: this will not work precisely during tempo ramps.\n * @param subdivision The subdivision to quantize to\n * @return The context time of the next subdivision.\n * @example\n * // the transport must be started, otherwise returns 0\n * Tone.Transport.start();\n * Tone.Transport.nextSubdivision("4n");\n */\n nextSubdivision(subdivision) {\n subdivision = this.toTicks(subdivision);\n if (this.state !== "started") {\n // if the transport\'s not started, return 0\n return 0;\n }\n else {\n const now = this.now();\n // the remainder of the current ticks and the subdivision\n const transportPos = this.getTicksAtTime(now);\n const remainingTicks = subdivision - transportPos % subdivision;\n return this._clock.nextTickTime(remainingTicks, now);\n }\n }\n /**\n * Attaches the signal to the tempo control signal so that\n * any changes in the tempo will change the signal in the same\n * ratio.\n *\n * @param signal\n * @param ratio Optionally pass in the ratio between the two signals.\n * \t\t\tOtherwise it will be computed based on their current values.\n */\n syncSignal(signal, ratio) {\n if (!ratio) {\n // get the sync ratio\n const now = this.now();\n if (signal.getValueAtTime(now) !== 0) {\n const bpm = this.bpm.getValueAtTime(now);\n const computedFreq = 1 / (60 / bpm / this.PPQ);\n ratio = signal.getValueAtTime(now) / computedFreq;\n }\n else {\n ratio = 0;\n }\n }\n const ratioSignal = new Gain_Gain(ratio);\n // @ts-ignore\n this.bpm.connect(ratioSignal);\n // @ts-ignore\n ratioSignal.connect(signal._param);\n this._syncedSignals.push({\n initial: signal.value,\n ratio: ratioSignal,\n signal,\n });\n signal.value = 0;\n return this;\n }\n /**\n * Unsyncs a previously synced signal from the transport\'s control.\n * See Transport.syncSignal.\n */\n unsyncSignal(signal) {\n for (let i = this._syncedSignals.length - 1; i >= 0; i--) {\n const syncedSignal = this._syncedSignals[i];\n if (syncedSignal.signal === signal) {\n syncedSignal.ratio.dispose();\n syncedSignal.signal.value = syncedSignal.initial;\n this._syncedSignals.splice(i, 1);\n }\n }\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._clock.dispose();\n Interface_writable(this, "bpm");\n this._timeline.dispose();\n this._repeatedEvents.dispose();\n return this;\n }\n}\nEmitter.mixin(Transport);\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.transport = new Transport({ context });\n});\nonContextClose(context => {\n context.transport.dispose();\n});\n//# sourceMappingURL=Transport.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/Source.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Base class for sources.\n * start/stop of this.context.transport.\n *\n * ```\n * // Multiple state change events can be chained together,\n * // but must be set in the correct order and with ascending times\n * // OK\n * state.start().stop("+0.2");\n * // OK\n * state.start().stop("+0.2").start("+0.4").stop("+0.7")\n * // BAD\n * state.stop("+0.2").start();\n * // BAD\n * state.start("+0.3").stop("+0.2");\n * ```\n */\nclass Source_Source extends ToneAudioNode_ToneAudioNode {\n constructor(options) {\n super(options);\n /**\n * Sources have no inputs\n */\n this.input = undefined;\n /**\n * Keep track of the scheduled state.\n */\n this._state = new StateTimeline_StateTimeline("stopped");\n /**\n * The synced `start` callback function from the transport\n */\n this._synced = false;\n /**\n * Keep track of all of the scheduled event ids\n */\n this._scheduled = [];\n /**\n * Placeholder functions for syncing/unsyncing to transport\n */\n this._syncedStart = Interface_noOp;\n this._syncedStop = Interface_noOp;\n this._state.memory = 100;\n this._state.increasing = true;\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n mute: options.mute,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n Interface_readOnly(this, "volume");\n this.onstop = options.onstop;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n onstop: Interface_noOp,\n volume: 0,\n });\n }\n /**\n * Returns the playback state of the source, either "started" or "stopped".\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/ahntone_c3.mp3", () => {\n * \tplayer.start();\n * \tconsole.log(player.state);\n * }).toDestination();\n */\n get state() {\n if (this._synced) {\n if (this.context.transport.state === "started") {\n return this._state.getValueAtTime(this.context.transport.seconds);\n }\n else {\n return "stopped";\n }\n }\n else {\n return this._state.getValueAtTime(this.now());\n }\n }\n /**\n * Mute the output.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // mute the output\n * osc.mute = true;\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n /**\n * Ensure that the scheduled time is not before the current time.\n * Should only be used when scheduled unsynced.\n */\n _clampToCurrentTime(time) {\n if (this._synced) {\n return time;\n }\n else {\n return Math.max(time, this.context.currentTime);\n }\n }\n /**\n * Start the source at the specified time. If no time is given,\n * start the source now.\n * @param time When the source should be started.\n * @example\n * const source = new Tone.Oscillator().toDestination();\n * source.start("+0.5"); // starts the source 0.5 seconds from now\n */\n start(time, offset, duration) {\n let computedTime = TypeCheck_isUndef(time) && this._synced ? this.context.transport.seconds : this.toSeconds(time);\n computedTime = this._clampToCurrentTime(computedTime);\n // if it\'s started, stop it and restart it\n if (!this._synced && this._state.getValueAtTime(computedTime) === "started") {\n // time should be strictly greater than the previous start time\n Debug_assert(GT(computedTime, this._state.get(computedTime).time), "Start time must be strictly greater than previous start time");\n this._state.cancel(computedTime);\n this._state.setStateAtTime("started", computedTime);\n this.log("restart", computedTime);\n this.restart(computedTime, offset, duration);\n }\n else {\n this.log("start", computedTime);\n this._state.setStateAtTime("started", computedTime);\n if (this._synced) {\n // add the offset time to the event\n const event = this._state.get(computedTime);\n if (event) {\n event.offset = this.toSeconds(Defaults_defaultArg(offset, 0));\n event.duration = duration ? this.toSeconds(duration) : undefined;\n }\n const sched = this.context.transport.schedule(t => {\n this._start(t, offset, duration);\n }, computedTime);\n this._scheduled.push(sched);\n // if the transport is already started\n // and the time is greater than where the transport is\n if (this.context.transport.state === "started" &&\n this.context.transport.getSecondsAtTime(this.immediate()) > computedTime) {\n this._syncedStart(this.now(), this.context.transport.seconds);\n }\n }\n else {\n assertContextRunning(this.context);\n this._start(computedTime, offset, duration);\n }\n }\n return this;\n }\n /**\n * Stop the source at the specified time. If no time is given,\n * stop the source now.\n * @param time When the source should be stopped.\n * @example\n * const source = new Tone.Oscillator().toDestination();\n * source.start();\n * source.stop("+0.5"); // stops the source 0.5 seconds from now\n */\n stop(time) {\n let computedTime = TypeCheck_isUndef(time) && this._synced ? this.context.transport.seconds : this.toSeconds(time);\n computedTime = this._clampToCurrentTime(computedTime);\n if (this._state.getValueAtTime(computedTime) === "started" || TypeCheck_isDefined(this._state.getNextState("started", computedTime))) {\n this.log("stop", computedTime);\n if (!this._synced) {\n this._stop(computedTime);\n }\n else {\n const sched = this.context.transport.schedule(this._stop.bind(this), computedTime);\n this._scheduled.push(sched);\n }\n this._state.cancel(computedTime);\n this._state.setStateAtTime("stopped", computedTime);\n }\n return this;\n }\n /**\n * Restart the source.\n */\n restart(time, offset, duration) {\n time = this.toSeconds(time);\n if (this._state.getValueAtTime(time) === "started") {\n this._state.cancel(time);\n this._restart(time, offset, duration);\n }\n return this;\n }\n /**\n * Sync the source to the Transport so that all subsequent\n * calls to `start` and `stop` are synced to the TransportTime\n * instead of the AudioContext time.\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination();\n * // sync the source so that it plays between 0 and 0.3 on the Transport\'s timeline\n * osc.sync().start(0).stop(0.3);\n * // start the transport.\n * Tone.Transport.start();\n * // set it to loop once a second\n * Tone.Transport.loop = true;\n * Tone.Transport.loopEnd = 1;\n */\n sync() {\n if (!this._synced) {\n this._synced = true;\n this._syncedStart = (time, offset) => {\n if (offset > 0) {\n // get the playback state at that time\n const stateEvent = this._state.get(offset);\n // listen for start events which may occur in the middle of the sync\'ed time\n if (stateEvent && stateEvent.state === "started" && stateEvent.time !== offset) {\n // get the offset\n const startOffset = offset - this.toSeconds(stateEvent.time);\n let duration;\n if (stateEvent.duration) {\n duration = this.toSeconds(stateEvent.duration) - startOffset;\n }\n this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration);\n }\n }\n };\n this._syncedStop = time => {\n const seconds = this.context.transport.getSecondsAtTime(Math.max(time - this.sampleTime, 0));\n if (this._state.getValueAtTime(seconds) === "started") {\n this._stop(time);\n }\n };\n this.context.transport.on("start", this._syncedStart);\n this.context.transport.on("loopStart", this._syncedStart);\n this.context.transport.on("stop", this._syncedStop);\n this.context.transport.on("pause", this._syncedStop);\n this.context.transport.on("loopEnd", this._syncedStop);\n }\n return this;\n }\n /**\n * Unsync the source to the Transport. See Source.sync\n */\n unsync() {\n if (this._synced) {\n this.context.transport.off("stop", this._syncedStop);\n this.context.transport.off("pause", this._syncedStop);\n this.context.transport.off("loopEnd", this._syncedStop);\n this.context.transport.off("start", this._syncedStart);\n this.context.transport.off("loopStart", this._syncedStart);\n }\n this._synced = false;\n // clear all of the scheduled ids\n this._scheduled.forEach(id => this.context.transport.clear(id));\n this._scheduled = [];\n this._state.cancel(0);\n // stop it also\n this._stop(0);\n return this;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.onstop = Interface_noOp;\n this.unsync();\n this._volume.dispose();\n this._state.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Source.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/ToneBufferSource.js\n\n\n\n\n\n\n\n\n\n/**\n * Wrapper around the native BufferSourceNode.\n * @category Source\n */\nclass ToneBufferSource_ToneBufferSource extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneBufferSource_ToneBufferSource.getDefaults(), arguments, ["url", "onload"]));\n this.name = "ToneBufferSource";\n /**\n * The oscillator\n */\n this._source = this.context.createBufferSource();\n this._internalChannels = [this._source];\n /**\n * indicators if the source has started/stopped\n */\n this._sourceStarted = false;\n this._sourceStopped = false;\n const options = Defaults_optionsFromArguments(ToneBufferSource_ToneBufferSource.getDefaults(), arguments, ["url", "onload"]);\n ToneAudioNode_connect(this._source, this._gainNode);\n this._source.onended = () => this._stopSource();\n /**\n * The playbackRate of the buffer\n */\n this.playbackRate = new Param_Param({\n context: this.context,\n param: this._source.playbackRate,\n units: "positive",\n value: options.playbackRate,\n });\n // set some values initially\n this.loop = options.loop;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this._buffer = new ToneAudioBuffer_ToneAudioBuffer(options.url, options.onload, options.onerror);\n this._internalChannels.push(this._source);\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n url: new ToneAudioBuffer_ToneAudioBuffer(),\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n onload: Interface_noOp,\n onerror: Interface_noOp,\n playbackRate: 1,\n });\n }\n /**\n * The fadeIn time of the amplitude envelope.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(t) {\n this._fadeIn = t;\n }\n /**\n * The fadeOut time of the amplitude envelope.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(t) {\n this._fadeOut = t;\n }\n /**\n * The curve applied to the fades, either "linear" or "exponential"\n */\n get curve() {\n return this._curve;\n }\n set curve(t) {\n this._curve = t;\n }\n /**\n * Start the buffer\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset)\n * @param gain The gain to play the buffer back at.\n */\n start(time, offset, duration, gain = 1) {\n Debug_assert(this.buffer.loaded, "buffer is either not set or not loaded");\n const computedTime = this.toSeconds(time);\n // apply the gain envelope\n this._startGain(computedTime, gain);\n // if it\'s a loop the default offset is the loopstart point\n if (this.loop) {\n offset = Defaults_defaultArg(offset, this.loopStart);\n }\n else {\n // otherwise the default offset is 0\n offset = Defaults_defaultArg(offset, 0);\n }\n // make sure the offset is not less than 0\n let computedOffset = Math.max(this.toSeconds(offset), 0);\n // start the buffer source\n if (this.loop) {\n // modify the offset if it\'s greater than the loop time\n const loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration;\n const loopStart = this.toSeconds(this.loopStart);\n const loopDuration = loopEnd - loopStart;\n // move the offset back\n if (GTE(computedOffset, loopEnd)) {\n computedOffset = ((computedOffset - loopStart) % loopDuration) + loopStart;\n }\n // when the offset is very close to the duration, set it to 0\n if (EQ(computedOffset, this.buffer.duration)) {\n computedOffset = 0;\n }\n }\n // this.buffer.loaded would have return false if the AudioBuffer was undefined\n this._source.buffer = this.buffer.get();\n this._source.loopEnd = this.toSeconds(this.loopEnd) || this.buffer.duration;\n if (LT(computedOffset, this.buffer.duration)) {\n this._sourceStarted = true;\n this._source.start(computedTime, computedOffset);\n }\n // if a duration is given, schedule a stop\n if (TypeCheck_isDefined(duration)) {\n let computedDur = this.toSeconds(duration);\n // make sure it\'s never negative\n computedDur = Math.max(computedDur, 0);\n this.stop(computedTime + computedDur);\n }\n return this;\n }\n _stopSource(time) {\n if (!this._sourceStopped && this._sourceStarted) {\n this._sourceStopped = true;\n this._source.stop(this.toSeconds(time));\n this._onended();\n }\n }\n /**\n * If loop is true, the loop will start at this position.\n */\n get loopStart() {\n return this._source.loopStart;\n }\n set loopStart(loopStart) {\n this._source.loopStart = this.toSeconds(loopStart);\n }\n /**\n * If loop is true, the loop will end at this position.\n */\n get loopEnd() {\n return this._source.loopEnd;\n }\n set loopEnd(loopEnd) {\n this._source.loopEnd = this.toSeconds(loopEnd);\n }\n /**\n * The audio buffer belonging to the player.\n */\n get buffer() {\n return this._buffer;\n }\n set buffer(buffer) {\n this._buffer.set(buffer);\n }\n /**\n * If the buffer should loop once it\'s over.\n */\n get loop() {\n return this._source.loop;\n }\n set loop(loop) {\n this._source.loop = loop;\n if (this._sourceStarted) {\n this.cancelStop();\n }\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._source.onended = null;\n this._source.disconnect();\n this._buffer.dispose();\n this.playbackRate.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneBufferSource.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/Noise.js\n\n\n\n\n\n/**\n * Noise is a noise generator. It uses looped noise buffers to save on performance.\n * Noise supports the noise types: "pink", "white", and "brown". Read more about\n * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise).\n *\n * @example\n * // initialize the noise and start\n * const noise = new Tone.Noise("pink").start();\n * // make an autofilter to shape the noise\n * const autoFilter = new Tone.AutoFilter({\n * \tfrequency: "8n",\n * \tbaseFrequency: 200,\n * \toctaves: 8\n * }).toDestination().start();\n * // connect the noise\n * noise.connect(autoFilter);\n * // start the autofilter LFO\n * autoFilter.start();\n * @category Source\n */\nclass Noise_Noise extends (/* unused pure expression or super */ null && (Source)) {\n constructor() {\n super(optionsFromArguments(Noise_Noise.getDefaults(), arguments, ["type"]));\n this.name = "Noise";\n /**\n * Private reference to the source\n */\n this._source = null;\n const options = optionsFromArguments(Noise_Noise.getDefaults(), arguments, ["type"]);\n this._playbackRate = options.playbackRate;\n this.type = options.type;\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n fadeIn: 0,\n fadeOut: 0,\n playbackRate: 1,\n type: "white",\n });\n }\n /**\n * The type of the noise. Can be "white", "brown", or "pink".\n * @example\n * const noise = new Tone.Noise().toDestination().start();\n * noise.type = "brown";\n */\n get type() {\n return this._type;\n }\n set type(type) {\n assert(type in _noiseBuffers, "Noise: invalid type: " + type);\n if (this._type !== type) {\n this._type = type;\n // if it\'s playing, stop and restart it\n if (this.state === "started") {\n const now = this.now();\n this._stop(now);\n this._start(now);\n }\n }\n }\n /**\n * The playback rate of the noise. Affects\n * the "frequency" of the noise.\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n if (this._source) {\n this._source.playbackRate.value = rate;\n }\n }\n /**\n * internal start method\n */\n _start(time) {\n const buffer = _noiseBuffers[this._type];\n this._source = new ToneBufferSource({\n url: buffer,\n context: this.context,\n fadeIn: this._fadeIn,\n fadeOut: this._fadeOut,\n loop: true,\n onended: () => this.onstop(this),\n playbackRate: this._playbackRate,\n }).connect(this.output);\n this._source.start(this.toSeconds(time), Math.random() * (buffer.duration - 0.001));\n }\n /**\n * internal stop method\n */\n _stop(time) {\n if (this._source) {\n this._source.stop(this.toSeconds(time));\n this._source = null;\n }\n }\n /**\n * The fadeIn time of the amplitude envelope.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(time) {\n this._fadeIn = time;\n if (this._source) {\n this._source.fadeIn = this._fadeIn;\n }\n }\n /**\n * The fadeOut time of the amplitude envelope.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(time) {\n this._fadeOut = time;\n if (this._source) {\n this._source.fadeOut = this._fadeOut;\n }\n }\n _restart(time) {\n // TODO could be optimized by cancelling the buffer source \'stop\'\n this._stop(time);\n this._start(time);\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n if (this._source) {\n this._source.disconnect();\n }\n return this;\n }\n}\n//--------------------\n// THE NOISE BUFFERS\n//--------------------\n// Noise buffer stats\nconst BUFFER_LENGTH = 44100 * 5;\nconst NUM_CHANNELS = 2;\n/**\n * Cache the noise buffers\n */\nconst _noiseCache = {\n brown: null,\n pink: null,\n white: null,\n};\n/**\n * The noise arrays. Generated on initialization.\n * borrowed heavily from https://github.com/zacharydenton/noise.js\n * (c) 2013 Zach Denton (MIT)\n */\nconst _noiseBuffers = {\n get brown() {\n if (!_noiseCache.brown) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n let lastOut = 0.0;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n const white = Math.random() * 2 - 1;\n channel[i] = (lastOut + (0.02 * white)) / 1.02;\n lastOut = channel[i];\n channel[i] *= 3.5; // (roughly) compensate for gain\n }\n }\n _noiseCache.brown = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.brown;\n },\n get pink() {\n if (!_noiseCache.pink) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n let b0, b1, b2, b3, b4, b5, b6;\n b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0.0;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n const white = Math.random() * 2 - 1;\n b0 = 0.99886 * b0 + white * 0.0555179;\n b1 = 0.99332 * b1 + white * 0.0750759;\n b2 = 0.96900 * b2 + white * 0.1538520;\n b3 = 0.86650 * b3 + white * 0.3104856;\n b4 = 0.55000 * b4 + white * 0.5329522;\n b5 = -0.7616 * b5 - white * 0.0168980;\n channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362;\n channel[i] *= 0.11; // (roughly) compensate for gain\n b6 = white * 0.115926;\n }\n }\n _noiseCache.pink = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.pink;\n },\n get white() {\n if (!_noiseCache.white) {\n const buffer = [];\n for (let channelNum = 0; channelNum < NUM_CHANNELS; channelNum++) {\n const channel = new Float32Array(BUFFER_LENGTH);\n buffer[channelNum] = channel;\n for (let i = 0; i < BUFFER_LENGTH; i++) {\n channel[i] = Math.random() * 2 - 1;\n }\n }\n _noiseCache.white = new ToneAudioBuffer_ToneAudioBuffer().fromArray(buffer);\n }\n return _noiseCache.white;\n },\n};\n//# sourceMappingURL=Noise.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/UserMedia.js\n\n\n\n\n\n\n\n/**\n * UserMedia uses MediaDevices.getUserMedia to open up and external microphone or audio input.\n * Check [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia)\n * to see which browsers are supported. Access to an external input\n * is limited to secure (HTTPS) connections.\n * @example\n * const meter = new Tone.Meter();\n * const mic = new Tone.UserMedia().connect(meter);\n * mic.open().then(() => {\n * \t// promise resolves when input is available\n * \tconsole.log("mic open");\n * \t// print the incoming mic levels in decibels\n * \tsetInterval(() => console.log(meter.getValue()), 100);\n * }).catch(e => {\n * \t// promise is rejected when the user doesn\'t have or allow mic access\n * \tconsole.log("mic not open");\n * });\n * @category Source\n */\nclass UserMedia extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]));\n this.name = "UserMedia";\n const options = optionsFromArguments(UserMedia.getDefaults(), arguments, ["volume"]);\n this._volume = this.output = new Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n readOnly(this, "volume");\n this.mute = options.mute;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n mute: false,\n volume: 0\n });\n }\n /**\n * Open the media stream. If a string is passed in, it is assumed\n * to be the label or id of the stream, if a number is passed in,\n * it is the input number of the stream.\n * @param labelOrId The label or id of the audio input media device.\n * With no argument, the default stream is opened.\n * @return The promise is resolved when the stream is open.\n */\n open(labelOrId) {\n return __awaiter(this, void 0, void 0, function* () {\n assert(UserMedia.supported, "UserMedia is not supported");\n // close the previous stream\n if (this.state === "started") {\n this.close();\n }\n const devices = yield UserMedia.enumerateDevices();\n if (isNumber(labelOrId)) {\n this._device = devices[labelOrId];\n }\n else {\n this._device = devices.find((device) => {\n return device.label === labelOrId || device.deviceId === labelOrId;\n });\n // didn\'t find a matching device\n if (!this._device && devices.length > 0) {\n this._device = devices[0];\n }\n assert(isDefined(this._device), `No matching device ${labelOrId}`);\n }\n // do getUserMedia\n const constraints = {\n audio: {\n echoCancellation: false,\n sampleRate: this.context.sampleRate,\n noiseSuppression: false,\n mozNoiseSuppression: false,\n }\n };\n if (this._device) {\n // @ts-ignore\n constraints.audio.deviceId = this._device.deviceId;\n }\n const stream = yield navigator.mediaDevices.getUserMedia(constraints);\n // start a new source only if the previous one is closed\n if (!this._stream) {\n this._stream = stream;\n // Wrap a MediaStreamSourceNode around the live input stream.\n const mediaStreamNode = this.context.createMediaStreamSource(stream);\n // Connect the MediaStreamSourceNode to a gate gain node\n connect(mediaStreamNode, this.output);\n this._mediaStream = mediaStreamNode;\n }\n return this;\n });\n }\n /**\n * Close the media stream\n */\n close() {\n if (this._stream && this._mediaStream) {\n this._stream.getAudioTracks().forEach((track) => {\n track.stop();\n });\n this._stream = undefined;\n // remove the old media stream\n this._mediaStream.disconnect();\n this._mediaStream = undefined;\n }\n this._device = undefined;\n return this;\n }\n /**\n * Returns a promise which resolves with the list of audio input devices available.\n * @return The promise that is resolved with the devices\n * @example\n * Tone.UserMedia.enumerateDevices().then((devices) => {\n * \t// print the device labels\n * \tconsole.log(devices.map(device => device.label));\n * });\n */\n static enumerateDevices() {\n return __awaiter(this, void 0, void 0, function* () {\n const allDevices = yield navigator.mediaDevices.enumerateDevices();\n return allDevices.filter(device => {\n return device.kind === "audioinput";\n });\n });\n }\n /**\n * Returns the playback state of the source, "started" when the microphone is open\n * and "stopped" when the mic is closed.\n */\n get state() {\n return this._stream && this._stream.active ? "started" : "stopped";\n }\n /**\n * Returns an identifier for the represented device that is\n * persisted across sessions. It is un-guessable by other applications and\n * unique to the origin of the calling application. It is reset when the\n * user clears cookies (for Private Browsing, a different identifier is\n * used that is not persisted across sessions). Returns undefined when the\n * device is not open.\n */\n get deviceId() {\n if (this._device) {\n return this._device.deviceId;\n }\n else {\n return undefined;\n }\n }\n /**\n * Returns a group identifier. Two devices have the\n * same group identifier if they belong to the same physical device.\n * Returns null when the device is not open.\n */\n get groupId() {\n if (this._device) {\n return this._device.groupId;\n }\n else {\n return undefined;\n }\n }\n /**\n * Returns a label describing this device (for example "Built-in Microphone").\n * Returns undefined when the device is not open or label is not available\n * because of permissions.\n */\n get label() {\n if (this._device) {\n return this._device.label;\n }\n else {\n return undefined;\n }\n }\n /**\n * Mute the output.\n * @example\n * const mic = new Tone.UserMedia();\n * mic.open().then(() => {\n * \t// promise resolves when input is available\n * });\n * // mute the output\n * mic.mute = true;\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n dispose() {\n super.dispose();\n this.close();\n this._volume.dispose();\n this.volume.dispose();\n return this;\n }\n /**\n * If getUserMedia is supported by the browser.\n */\n static get supported() {\n return isDefined(navigator.mediaDevices) &&\n isDefined(navigator.mediaDevices.getUserMedia);\n }\n}\n//# sourceMappingURL=UserMedia.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/OscillatorInterface.js\n\n\n/**\n * Render a segment of the oscillator to an offline context and return the results as an array\n */\nfunction generateWaveform(instance, length) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const duration = length / instance.context.sampleRate;\n const context = new OfflineContext_OfflineContext(1, duration, instance.context.sampleRate);\n const clone = new instance.constructor(Object.assign(instance.get(), {\n // should do 2 iterations\n frequency: 2 / duration,\n // zero out the detune\n detune: 0,\n context\n })).toDestination();\n clone.start(0);\n const buffer = yield context.render();\n return buffer.getChannelData(0);\n });\n}\n//# sourceMappingURL=OscillatorInterface.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/ToneOscillatorNode.js\n\n\n\n\n\n/**\n * Wrapper around the native fire-and-forget OscillatorNode.\n * Adds the ability to reschedule the stop method.\n * ***[[Oscillator]] is better for most use-cases***\n * @category Source\n */\nclass ToneOscillatorNode_ToneOscillatorNode extends OneShotSource {\n constructor() {\n super(Defaults_optionsFromArguments(ToneOscillatorNode_ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "ToneOscillatorNode";\n /**\n * The oscillator\n */\n this._oscillator = this.context.createOscillator();\n this._internalChannels = [this._oscillator];\n const options = Defaults_optionsFromArguments(ToneOscillatorNode_ToneOscillatorNode.getDefaults(), arguments, ["frequency", "type"]);\n ToneAudioNode_connect(this._oscillator, this._gainNode);\n this.type = options.type;\n this.frequency = new Param_Param({\n context: this.context,\n param: this._oscillator.frequency,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Param_Param({\n context: this.context,\n param: this._oscillator.detune,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, ["frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(OneShotSource.getDefaults(), {\n detune: 0,\n frequency: 440,\n type: "sine",\n });\n }\n /**\n * Start the oscillator node at the given time\n * @param time When to start the oscillator\n */\n start(time) {\n const computedTime = this.toSeconds(time);\n this.log("start", computedTime);\n this._startGain(computedTime);\n this._oscillator.start(computedTime);\n return this;\n }\n _stopSource(time) {\n this._oscillator.stop(time);\n }\n /**\n * Sets an arbitrary custom periodic waveform given a PeriodicWave.\n * @param periodicWave PeriodicWave should be created with context.createPeriodicWave\n */\n setPeriodicWave(periodicWave) {\n this._oscillator.setPeriodicWave(periodicWave);\n return this;\n }\n /**\n * The oscillator type. Either \'sine\', \'sawtooth\', \'square\', or \'triangle\'\n */\n get type() {\n return this._oscillator.type;\n }\n set type(type) {\n this._oscillator.type = type;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n if (this.state === "started") {\n this.stop();\n }\n this._oscillator.disconnect();\n this.frequency.dispose();\n this.detune.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneOscillatorNode.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/Oscillator.js\n\n\n\n\n\n\n\n\n\n\n/**\n * Oscillator supports a number of features including\n * phase rotation, multiple oscillator types (see Oscillator.type),\n * and Transport syncing (see Oscillator.syncFrequency).\n *\n * @example\n * // make and start a 440hz sine tone\n * const osc = new Tone.Oscillator(440, "sine").toDestination().start();\n * @category Source\n */\nclass Oscillator_Oscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(Oscillator_Oscillator.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "Oscillator";\n /**\n * the main oscillator\n */\n this._oscillator = null;\n const options = Defaults_optionsFromArguments(Oscillator_Oscillator.getDefaults(), arguments, ["frequency", "type"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n Interface_readOnly(this, "frequency");\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, "detune");\n this._partials = options.partials;\n this._partialCount = options.partialCount;\n this._type = options.type;\n if (options.partialCount && options.type !== "custom") {\n this._type = this.baseType + options.partialCount.toString();\n }\n this.phase = options.phase;\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n partialCount: 0,\n partials: [],\n phase: 0,\n type: "sine",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n const computedTime = this.toSeconds(time);\n // new oscillator with previous values\n const oscillator = new ToneOscillatorNode_ToneOscillatorNode({\n context: this.context,\n onended: () => this.onstop(this),\n });\n this._oscillator = oscillator;\n if (this._wave) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n else {\n this._oscillator.type = this._type;\n }\n // connect the control signal to the oscillator frequency & detune\n this._oscillator.connect(this.output);\n this.frequency.connect(this._oscillator.frequency);\n this.detune.connect(this._oscillator.detune);\n // start the oscillator\n this._oscillator.start(computedTime);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n const computedTime = this.toSeconds(time);\n if (this._oscillator) {\n this._oscillator.stop(computedTime);\n }\n }\n /**\n * Restart the oscillator. Does not stop the oscillator, but instead\n * just cancels any scheduled \'stop\' from being invoked.\n */\n _restart(time) {\n const computedTime = this.toSeconds(time);\n this.log("restart", computedTime);\n if (this._oscillator) {\n this._oscillator.cancelStop();\n }\n this._state.cancel(computedTime);\n return this;\n }\n /**\n * Sync the signal to the Transport\'s bpm. Any changes to the transports bpm,\n * will also affect the oscillators frequency.\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * osc.frequency.value = 440;\n * // the ratio between the bpm and the frequency will be maintained\n * osc.syncFrequency();\n * // double the tempo\n * Tone.Transport.bpm.value *= 2;\n * // the frequency of the oscillator is doubled to 880\n */\n syncFrequency() {\n this.context.transport.syncSignal(this.frequency);\n return this;\n }\n /**\n * Unsync the oscillator\'s frequency from the Transport.\n * See Oscillator.syncFrequency\n */\n unsyncFrequency() {\n this.context.transport.unsyncSignal(this.frequency);\n return this;\n }\n /**\n * Get a cached periodic wave. Avoids having to recompute\n * the oscillator values when they have already been computed\n * with the same values.\n */\n _getCachedPeriodicWave() {\n if (this._type === "custom") {\n const oscProps = Oscillator_Oscillator._periodicWaveCache.find(description => {\n return description.phase === this._phase &&\n deepEquals(description.partials, this._partials);\n });\n return oscProps;\n }\n else {\n const oscProps = Oscillator_Oscillator._periodicWaveCache.find(description => {\n return description.type === this._type &&\n description.phase === this._phase;\n });\n this._partialCount = oscProps ? oscProps.partialCount : this._partialCount;\n return oscProps;\n }\n }\n get type() {\n return this._type;\n }\n set type(type) {\n this._type = type;\n const isBasicType = ["sine", "square", "sawtooth", "triangle"].indexOf(type) !== -1;\n if (this._phase === 0 && isBasicType) {\n this._wave = undefined;\n this._partialCount = 0;\n // just go with the basic approach\n if (this._oscillator !== null) {\n // already tested that it\'s a basic type\n this._oscillator.type = type;\n }\n }\n else {\n // first check if the value is cached\n const cache = this._getCachedPeriodicWave();\n if (TypeCheck_isDefined(cache)) {\n const { partials, wave } = cache;\n this._wave = wave;\n this._partials = partials;\n if (this._oscillator !== null) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n }\n else {\n const [real, imag] = this._getRealImaginary(type, this._phase);\n const periodicWave = this.context.createPeriodicWave(real, imag);\n this._wave = periodicWave;\n if (this._oscillator !== null) {\n this._oscillator.setPeriodicWave(this._wave);\n }\n // set the cache\n Oscillator_Oscillator._periodicWaveCache.push({\n imag,\n partialCount: this._partialCount,\n partials: this._partials,\n phase: this._phase,\n real,\n type: this._type,\n wave: this._wave,\n });\n if (Oscillator_Oscillator._periodicWaveCache.length > 100) {\n Oscillator_Oscillator._periodicWaveCache.shift();\n }\n }\n }\n }\n get baseType() {\n return this._type.replace(this.partialCount.toString(), "");\n }\n set baseType(baseType) {\n if (this.partialCount && this._type !== "custom" && baseType !== "custom") {\n this.type = baseType + this.partialCount;\n }\n else {\n this.type = baseType;\n }\n }\n get partialCount() {\n return this._partialCount;\n }\n set partialCount(p) {\n Debug_assertRange(p, 0);\n let type = this._type;\n const partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(this._type);\n if (partial) {\n type = partial[1];\n }\n if (this._type !== "custom") {\n if (p === 0) {\n this.type = type;\n }\n else {\n this.type = type + p.toString();\n }\n }\n else {\n // extend or shorten the partials array\n const fullPartials = new Float32Array(p);\n // copy over the partials array\n this._partials.forEach((v, i) => fullPartials[i] = v);\n this._partials = Array.from(fullPartials);\n this.type = this._type;\n }\n }\n /**\n * Returns the real and imaginary components based\n * on the oscillator type.\n * @returns [real: Float32Array, imaginary: Float32Array]\n */\n _getRealImaginary(type, phase) {\n const fftSize = 4096;\n let periodicWaveSize = fftSize / 2;\n const real = new Float32Array(periodicWaveSize);\n const imag = new Float32Array(periodicWaveSize);\n let partialCount = 1;\n if (type === "custom") {\n partialCount = this._partials.length + 1;\n this._partialCount = this._partials.length;\n periodicWaveSize = partialCount;\n // if the partial count is 0, don\'t bother doing any computation\n if (this._partials.length === 0) {\n return [real, imag];\n }\n }\n else {\n const partial = /^(sine|triangle|square|sawtooth)(\\d+)$/.exec(type);\n if (partial) {\n partialCount = parseInt(partial[2], 10) + 1;\n this._partialCount = parseInt(partial[2], 10);\n type = partial[1];\n partialCount = Math.max(partialCount, 2);\n periodicWaveSize = partialCount;\n }\n else {\n this._partialCount = 0;\n }\n this._partials = [];\n }\n for (let n = 1; n < periodicWaveSize; ++n) {\n const piFactor = 2 / (n * Math.PI);\n let b;\n switch (type) {\n case "sine":\n b = (n <= partialCount) ? 1 : 0;\n this._partials[n - 1] = b;\n break;\n case "square":\n b = (n & 1) ? 2 * piFactor : 0;\n this._partials[n - 1] = b;\n break;\n case "sawtooth":\n b = piFactor * ((n & 1) ? 1 : -1);\n this._partials[n - 1] = b;\n break;\n case "triangle":\n if (n & 1) {\n b = 2 * (piFactor * piFactor) * ((((n - 1) >> 1) & 1) ? -1 : 1);\n }\n else {\n b = 0;\n }\n this._partials[n - 1] = b;\n break;\n case "custom":\n b = this._partials[n - 1];\n break;\n default:\n throw new TypeError("Oscillator: invalid type: " + type);\n }\n if (b !== 0) {\n real[n] = -b * Math.sin(phase * n);\n imag[n] = b * Math.cos(phase * n);\n }\n else {\n real[n] = 0;\n imag[n] = 0;\n }\n }\n return [real, imag];\n }\n /**\n * Compute the inverse FFT for a given phase.\n */\n _inverseFFT(real, imag, phase) {\n let sum = 0;\n const len = real.length;\n for (let i = 0; i < len; i++) {\n sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase);\n }\n return sum;\n }\n /**\n * Returns the initial value of the oscillator when stopped.\n * E.g. a "sine" oscillator with phase = 90 would return an initial value of -1.\n */\n getInitialValue() {\n const [real, imag] = this._getRealImaginary(this._type, 0);\n let maxValue = 0;\n const twoPi = Math.PI * 2;\n const testPositions = 32;\n // check for peaks in 16 places\n for (let i = 0; i < testPositions; i++) {\n maxValue = Math.max(this._inverseFFT(real, imag, (i / testPositions) * twoPi), maxValue);\n }\n return Math_clamp(-this._inverseFFT(real, imag, this._phase) / maxValue, -1, 1);\n }\n get partials() {\n return this._partials.slice(0, this.partialCount);\n }\n set partials(partials) {\n this._partials = partials;\n this._partialCount = this._partials.length;\n if (partials.length) {\n this.type = "custom";\n }\n }\n get phase() {\n return this._phase * (180 / Math.PI);\n }\n set phase(phase) {\n this._phase = phase * Math.PI / 180;\n // reset the type\n this.type = this._type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n dispose() {\n super.dispose();\n if (this._oscillator !== null) {\n this._oscillator.dispose();\n }\n this._wave = undefined;\n this.frequency.dispose();\n this.detune.dispose();\n return this;\n }\n}\n/**\n * Cache the periodic waves to avoid having to redo computations\n */\nOscillator_Oscillator._periodicWaveCache = [];\n//# sourceMappingURL=Oscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/SignalOperator.js\n\n\n\n/**\n * A signal operator has an input and output and modifies the signal.\n */\nclass SignalOperator_SignalOperator extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(SignalOperator_SignalOperator.getDefaults(), arguments, ["context"])));\n }\n connect(destination, outputNum = 0, inputNum = 0) {\n Signal_connectSignal(this, destination, outputNum, inputNum);\n return this;\n }\n}\n//# sourceMappingURL=SignalOperator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/WaveShaper.js\n\n\n\n\n\n/**\n * Wraps the native Web Audio API\n * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface).\n *\n * @example\n * const osc = new Tone.Oscillator().toDestination().start();\n * // multiply the output of the signal by 2 using the waveshaper\'s function\n * const timesTwo = new Tone.WaveShaper((val) => val * 2, 2048).connect(osc.frequency);\n * const signal = new Tone.Signal(440).connect(timesTwo);\n * @category Signal\n */\nclass WaveShaper_WaveShaper extends SignalOperator_SignalOperator {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(WaveShaper_WaveShaper.getDefaults(), arguments, ["mapping", "length"])));\n this.name = "WaveShaper";\n /**\n * the waveshaper node\n */\n this._shaper = this.context.createWaveShaper();\n /**\n * The input to the waveshaper node.\n */\n this.input = this._shaper;\n /**\n * The output from the waveshaper node\n */\n this.output = this._shaper;\n const options = Defaults_optionsFromArguments(WaveShaper_WaveShaper.getDefaults(), arguments, ["mapping", "length"]);\n if (TypeCheck_isArray(options.mapping) || options.mapping instanceof Float32Array) {\n this.curve = Float32Array.from(options.mapping);\n }\n else if (isFunction(options.mapping)) {\n this.setMap(options.mapping, options.length);\n }\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n length: 1024,\n });\n }\n /**\n * Uses a mapping function to set the value of the curve.\n * @param mapping The function used to define the values.\n * The mapping function take two arguments:\n * the first is the value at the current position\n * which goes from -1 to 1 over the number of elements\n * in the curve array. The second argument is the array position.\n * @example\n * const shaper = new Tone.WaveShaper();\n * // map the input signal from [-1, 1] to [0, 10]\n * shaper.setMap((val, index) => (val + 1) * 5);\n */\n setMap(mapping, length = 1024) {\n const array = new Float32Array(length);\n for (let i = 0, len = length; i < len; i++) {\n const normalized = (i / (len - 1)) * 2 - 1;\n array[i] = mapping(normalized, i);\n }\n this.curve = array;\n return this;\n }\n /**\n * The array to set as the waveshaper curve. For linear curves\n * array length does not make much difference, but for complex curves\n * longer arrays will provide smoother interpolation.\n */\n get curve() {\n return this._shaper.curve;\n }\n set curve(mapping) {\n this._shaper.curve = mapping;\n }\n /**\n * Specifies what type of oversampling (if any) should be used when\n * applying the shaping curve. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n const isOverSampleType = ["none", "2x", "4x"].some(str => str.includes(oversampling));\n Debug_assert(isOverSampleType, "oversampling must be either \'none\', \'2x\', or \'4x\'");\n this._shaper.oversample = oversampling;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._shaper.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=WaveShaper.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/AudioToGain.js\n\n\n/**\n * AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1].\n * See [[GainToAudio]].\n * @category Signal\n */\nclass AudioToGain_AudioToGain extends SignalOperator_SignalOperator {\n constructor() {\n super(...arguments);\n this.name = "AudioToGain";\n /**\n * The node which converts the audio ranges\n */\n this._norm = new WaveShaper_WaveShaper({\n context: this.context,\n mapping: x => (x + 1) / 2,\n });\n /**\n * The AudioRange input [-1, 1]\n */\n this.input = this._norm;\n /**\n * The GainRange output [0, 1]\n */\n this.output = this._norm;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._norm.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AudioToGain.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Multiply.js\n\n\n\n/**\n * Multiply two incoming signals. Or, if a number is given in the constructor,\n * multiplies the incoming signal by that value.\n *\n * @example\n * // multiply two signals\n * const mult = new Tone.Multiply();\n * const sigA = new Tone.Signal(3);\n * const sigB = new Tone.Signal(4);\n * sigA.connect(mult);\n * sigB.connect(mult.factor);\n * // output of mult is 12.\n * @example\n * // multiply a signal and a number\n * const mult = new Tone.Multiply(10);\n * const sig = new Tone.Signal(2).connect(mult);\n * // the output of mult is 20.\n * @category Signal\n */\nclass Multiply_Multiply extends Signal_Signal {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(Multiply_Multiply.getDefaults(), arguments, ["value"])));\n this.name = "Multiply";\n /**\n * Indicates if the value should be overridden on connection\n */\n this.override = false;\n const options = Defaults_optionsFromArguments(Multiply_Multiply.getDefaults(), arguments, ["value"]);\n this._mult = this.input = this.output = new Gain_Gain({\n context: this.context,\n minValue: options.minValue,\n maxValue: options.maxValue,\n });\n this.factor = this._param = this._mult.gain;\n this.factor.setValueAtTime(options.value, 0);\n }\n static getDefaults() {\n return Object.assign(Signal_Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._mult.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Multiply.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/AMOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * An amplitude modulated oscillator node. It is implemented with\n * two oscillators, one which modulators the other\'s amplitude\n * through a gain node.\n * ```\n * +-------------+ +----------+\n * | Carrier Osc +>------\x3e GainNode |\n * +-------------+ | +---\x3eOutput\n * +---\x3e gain |\n * +---------------+ | +----------+\n * | Modulator Osc +>---+\n * +---------------+\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst amOsc = new Tone.AMOscillator(30, "sine", "square").toDestination().start();\n * }, 0.2, 1);\n * @category Source\n */\nclass AMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));\n this.name = "AMOscillator";\n /**\n * convert the -1,1 output to 0,1\n */\n this._modulationScale = new AudioToGain_AudioToGain({ context: this.context });\n /**\n * the node where the modulation happens\n */\n this._modulationNode = new Gain_Gain({\n context: this.context,\n });\n const options = Defaults_optionsFromArguments(AMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);\n this._carrier = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: options.type,\n });\n this.frequency = this._carrier.frequency,\n this.detune = this._carrier.detune;\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n phase: options.phase,\n type: options.modulationType,\n });\n this.harmonicity = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n // connections\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n this._carrier.chain(this._modulationNode, this.output);\n Interface_readOnly(this, ["frequency", "detune", "harmonicity"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n harmonicity: 1,\n modulationType: "square",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._modulator.start(time);\n this._carrier.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n this._modulator.stop(time);\n this._carrier.stop(time);\n }\n _restart(time) {\n this._modulator.restart(time);\n this._carrier.restart(time);\n }\n /**\n * The type of the carrier oscillator\n */\n get type() {\n return this._carrier.type;\n }\n set type(type) {\n this._carrier.type = type;\n }\n get baseType() {\n return this._carrier.baseType;\n }\n set baseType(baseType) {\n this._carrier.baseType = baseType;\n }\n get partialCount() {\n return this._carrier.partialCount;\n }\n set partialCount(partialCount) {\n this._carrier.partialCount = partialCount;\n }\n /**\n * The type of the modulator oscillator\n */\n get modulationType() {\n return this._modulator.type;\n }\n set modulationType(type) {\n this._modulator.type = type;\n }\n get phase() {\n return this._carrier.phase;\n }\n set phase(phase) {\n this._carrier.phase = phase;\n this._modulator.phase = phase;\n }\n get partials() {\n return this._carrier.partials;\n }\n set partials(partials) {\n this._carrier.partials = partials;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this.harmonicity.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this._modulationNode.dispose();\n this._modulationScale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/FMOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * FMOscillator implements a frequency modulation synthesis\n * ```\n * +-------------+\n * +---------------+ +-------------+ | Carrier Osc |\n * | Modulator Osc +>-------\x3e GainNode | | +---\x3eOutput\n * +---------------+ | +>----\x3e frequency |\n * +--\x3e gain | +-------------+\n * | +-------------+\n * +-----------------+ |\n * | modulationIndex +>--+\n * +-----------------+\n * ```\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst fmOsc = new Tone.FMOscillator({\n * \t\tfrequency: 200,\n * \t\ttype: "square",\n * \t\tmodulationType: "triangle",\n * \t\tharmonicity: 0.2,\n * \t\tmodulationIndex: 3\n * \t}).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass FMOscillator_FMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(FMOscillator_FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]));\n this.name = "FMOscillator";\n /**\n * the node where the modulation happens\n */\n this._modulationNode = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n const options = Defaults_optionsFromArguments(FMOscillator_FMOscillator.getDefaults(), arguments, ["frequency", "type", "modulationType"]);\n this._carrier = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: 0,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: options.type,\n });\n this.detune = this._carrier.detune;\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n phase: options.phase,\n type: options.modulationType,\n });\n this.harmonicity = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n this.modulationIndex = new Multiply_Multiply({\n context: this.context,\n units: "positive",\n value: options.modulationIndex,\n });\n // connections\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.frequency.chain(this.modulationIndex, this._modulationNode);\n this._modulator.connect(this._modulationNode.gain);\n this._modulationNode.connect(this._carrier.frequency);\n this._carrier.connect(this.output);\n this.detune.connect(this._modulator.detune);\n Interface_readOnly(this, ["modulationIndex", "frequency", "detune", "harmonicity"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n harmonicity: 1,\n modulationIndex: 2,\n modulationType: "square",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._modulator.start(time);\n this._carrier.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n this._modulator.stop(time);\n this._carrier.stop(time);\n }\n _restart(time) {\n this._modulator.restart(time);\n this._carrier.restart(time);\n return this;\n }\n get type() {\n return this._carrier.type;\n }\n set type(type) {\n this._carrier.type = type;\n }\n get baseType() {\n return this._carrier.baseType;\n }\n set baseType(baseType) {\n this._carrier.baseType = baseType;\n }\n get partialCount() {\n return this._carrier.partialCount;\n }\n set partialCount(partialCount) {\n this._carrier.partialCount = partialCount;\n }\n /**\n * The type of the modulator oscillator\n */\n get modulationType() {\n return this._modulator.type;\n }\n set modulationType(type) {\n this._modulator.type = type;\n }\n get phase() {\n return this._carrier.phase;\n }\n set phase(phase) {\n this._carrier.phase = phase;\n this._modulator.phase = phase;\n }\n get partials() {\n return this._carrier.partials;\n }\n set partials(partials) {\n this._carrier.partials = partials;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.harmonicity.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this._modulationNode.dispose();\n this.modulationIndex.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/PulseOscillator.js\n\n\n\n\n\n\n\n\n\n/**\n * PulseOscillator is an oscillator with control over pulse width,\n * also known as the duty cycle. At 50% duty cycle (width = 0) the wave is\n * a square wave.\n * [Read more](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/).\n * ```\n * width = -0.25 width = 0.0 width = 0.25\n *\n * +-----+ +-------+ + +-------+ +-+\n * | | | | | | |\n * | | | | | | |\n * +-+ +-------+ + +-------+ +-----+\n *\n *\n * width = -0.5 width = 0.5\n *\n * +---+ +-------+ +---+\n * | | | |\n * | | | |\n * +---+ +-------+ +---+\n *\n *\n * width = -0.75 width = 0.75\n *\n * +-+ +-------+ +-----+\n * | | | |\n * | | | |\n * +-----+ +-------+ +-+\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst pulse = new Tone.PulseOscillator(50, 0.4).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass PulseOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]));\n this.name = "PulseOscillator";\n /**\n * gate the width amount\n */\n this._widthGate = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * Threshold the signal to turn it into a square\n */\n this._thresh = new WaveShaper_WaveShaper({\n context: this.context,\n mapping: val => val <= 0 ? -1 : 1,\n });\n const options = Defaults_optionsFromArguments(PulseOscillator.getDefaults(), arguments, ["frequency", "width"]);\n this.width = new Signal_Signal({\n context: this.context,\n units: "audioRange",\n value: options.width,\n });\n this._triangle = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n type: "triangle",\n });\n this.frequency = this._triangle.frequency;\n this.detune = this._triangle.detune;\n // connections\n this._triangle.chain(this._thresh, this.output);\n this.width.chain(this._widthGate, this._thresh);\n Interface_readOnly(this, ["width", "frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n phase: 0,\n type: "pulse",\n width: 0.2,\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._triangle.start(time);\n this._widthGate.gain.setValueAtTime(1, time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._triangle.stop(time);\n // the width is still connected to the output.\n // that needs to be stopped also\n this._widthGate.gain.cancelScheduledValues(time);\n this._widthGate.gain.setValueAtTime(0, time);\n }\n _restart(time) {\n this._triangle.restart(time);\n this._widthGate.gain.cancelScheduledValues(time);\n this._widthGate.gain.setValueAtTime(1, time);\n }\n /**\n * The phase of the oscillator in degrees.\n */\n get phase() {\n return this._triangle.phase;\n }\n set phase(phase) {\n this._triangle.phase = phase;\n }\n /**\n * The type of the oscillator. Always returns "pulse".\n */\n get type() {\n return "pulse";\n }\n /**\n * The baseType of the oscillator. Always returns "pulse".\n */\n get baseType() {\n return "pulse";\n }\n /**\n * The partials of the waveform. Cannot set partials for this waveform type\n */\n get partials() {\n return [];\n }\n /**\n * No partials for this waveform type.\n */\n get partialCount() {\n return 0;\n }\n /**\n * *Internal use* The carrier oscillator type is fed through the\n * waveshaper node to create the pulse. Using different carrier oscillators\n * changes oscillator\'s behavior.\n */\n set carrierType(type) {\n this._triangle.type = type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up method.\n */\n dispose() {\n super.dispose();\n this._triangle.dispose();\n this.width.dispose();\n this._widthGate.dispose();\n this._thresh.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PulseOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/FatOscillator.js\n\n\n\n\n\n\n\n\n/**\n * FatOscillator is an array of oscillators with detune spread between the oscillators\n * @example\n * const fatOsc = new Tone.FatOscillator("Ab3", "sawtooth", 40).toDestination().start();\n * @category Source\n */\nclass FatOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]));\n this.name = "FatOscillator";\n /**\n * The array of oscillators\n */\n this._oscillators = [];\n const options = Defaults_optionsFromArguments(FatOscillator.getDefaults(), arguments, ["frequency", "type", "spread"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this._spread = options.spread;\n this._type = options.type;\n this._phase = options.phase;\n this._partials = options.partials;\n this._partialCount = options.partialCount;\n // set the count initially\n this.count = options.count;\n Interface_readOnly(this, ["frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), {\n count: 3,\n spread: 20,\n type: "sawtooth",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._forEach(osc => osc.start(time));\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._forEach(osc => osc.stop(time));\n }\n _restart(time) {\n this._forEach(osc => osc.restart(time));\n }\n /**\n * Iterate over all of the oscillators\n */\n _forEach(iterator) {\n for (let i = 0; i < this._oscillators.length; i++) {\n iterator(this._oscillators[i], i);\n }\n }\n /**\n * The type of the oscillator\n */\n get type() {\n return this._type;\n }\n set type(type) {\n this._type = type;\n this._forEach(osc => osc.type = type);\n }\n /**\n * The detune spread between the oscillators. If "count" is\n * set to 3 oscillators and the "spread" is set to 40,\n * the three oscillators would be detuned like this: [-20, 0, 20]\n * for a total detune spread of 40 cents.\n * @example\n * const fatOsc = new Tone.FatOscillator().toDestination().start();\n * fatOsc.spread = 70;\n */\n get spread() {\n return this._spread;\n }\n set spread(spread) {\n this._spread = spread;\n if (this._oscillators.length > 1) {\n const start = -spread / 2;\n const step = spread / (this._oscillators.length - 1);\n this._forEach((osc, i) => osc.detune.value = start + step * i);\n }\n }\n /**\n * The number of detuned oscillators. Must be an integer greater than 1.\n * @example\n * const fatOsc = new Tone.FatOscillator("C#3", "sawtooth").toDestination().start();\n * // use 4 sawtooth oscillators\n * fatOsc.count = 4;\n */\n get count() {\n return this._oscillators.length;\n }\n set count(count) {\n Debug_assertRange(count, 1);\n if (this._oscillators.length !== count) {\n // dispose the previous oscillators\n this._forEach(osc => osc.dispose());\n this._oscillators = [];\n for (let i = 0; i < count; i++) {\n const osc = new Oscillator_Oscillator({\n context: this.context,\n volume: -6 - count * 1.1,\n type: this._type,\n phase: this._phase + (i / count) * 360,\n partialCount: this._partialCount,\n onstop: i === 0 ? () => this.onstop(this) : Interface_noOp,\n });\n if (this.type === "custom") {\n osc.partials = this._partials;\n }\n this.frequency.connect(osc.frequency);\n this.detune.connect(osc.detune);\n osc.detune.overridden = false;\n osc.connect(this.output);\n this._oscillators[i] = osc;\n }\n // set the spread\n this.spread = this._spread;\n if (this.state === "started") {\n this._forEach(osc => osc.start());\n }\n }\n }\n get phase() {\n return this._phase;\n }\n set phase(phase) {\n this._phase = phase;\n this._forEach((osc, i) => osc.phase = this._phase + (i / this.count) * 360);\n }\n get baseType() {\n return this._oscillators[0].baseType;\n }\n set baseType(baseType) {\n this._forEach(osc => osc.baseType = baseType);\n this._type = this._oscillators[0].type;\n }\n get partials() {\n return this._oscillators[0].partials;\n }\n set partials(partials) {\n this._partials = partials;\n this._partialCount = this._partials.length;\n if (partials.length) {\n this._type = "custom";\n this._forEach(osc => osc.partials = partials);\n }\n }\n get partialCount() {\n return this._oscillators[0].partialCount;\n }\n set partialCount(partialCount) {\n this._partialCount = partialCount;\n this._forEach(osc => osc.partialCount = partialCount);\n this._type = this._oscillators[0].type;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this._forEach(osc => osc.dispose());\n return this;\n }\n}\n//# sourceMappingURL=FatOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/PWMOscillator.js\n\n\n\n\n\n\n\n\n/**\n * PWMOscillator modulates the width of a Tone.PulseOscillator\n * at the modulationFrequency. This has the effect of continuously\n * changing the timbre of the oscillator by altering the harmonics\n * generated.\n * @example\n * return Tone.Offline(() => {\n * \tconst pwm = new Tone.PWMOscillator(60, 0.3).toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass PWMOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]));\n this.name = "PWMOscillator";\n this.sourceType = "pwm";\n /**\n * Scale the oscillator so it doesn\'t go silent\n * at the extreme values.\n */\n this._scale = new Multiply_Multiply({\n context: this.context,\n value: 2,\n });\n const options = Defaults_optionsFromArguments(PWMOscillator.getDefaults(), arguments, ["frequency", "modulationFrequency"]);\n this._pulse = new PulseOscillator({\n context: this.context,\n frequency: options.modulationFrequency,\n });\n // change the pulse oscillator type\n this._pulse.carrierType = "sine";\n this.modulationFrequency = this._pulse.frequency;\n this._modulator = new Oscillator_Oscillator({\n context: this.context,\n detune: options.detune,\n frequency: options.frequency,\n onstop: () => this.onstop(this),\n phase: options.phase,\n });\n this.frequency = this._modulator.frequency;\n this.detune = this._modulator.detune;\n // connections\n this._modulator.chain(this._scale, this._pulse.width);\n this._pulse.connect(this.output);\n Interface_readOnly(this, ["modulationFrequency", "frequency", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n detune: 0,\n frequency: 440,\n modulationFrequency: 0.4,\n phase: 0,\n type: "pwm",\n });\n }\n /**\n * start the oscillator\n */\n _start(time) {\n time = this.toSeconds(time);\n this._modulator.start(time);\n this._pulse.start(time);\n }\n /**\n * stop the oscillator\n */\n _stop(time) {\n time = this.toSeconds(time);\n this._modulator.stop(time);\n this._pulse.stop(time);\n }\n /**\n * restart the oscillator\n */\n _restart(time) {\n this._modulator.restart(time);\n this._pulse.restart(time);\n }\n /**\n * The type of the oscillator. Always returns "pwm".\n */\n get type() {\n return "pwm";\n }\n /**\n * The baseType of the oscillator. Always returns "pwm".\n */\n get baseType() {\n return "pwm";\n }\n /**\n * The partials of the waveform. Cannot set partials for this waveform type\n */\n get partials() {\n return [];\n }\n /**\n * No partials for this waveform type.\n */\n get partialCount() {\n return 0;\n }\n /**\n * The phase of the oscillator in degrees.\n */\n get phase() {\n return this._modulator.phase;\n }\n set phase(phase) {\n this._modulator.phase = phase;\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._pulse.dispose();\n this._scale.dispose();\n this._modulator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PWMOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/OmniOscillator.js\n\n\n\n\n\n\n\n\n\n\n\n\n\nconst OmniOscillatorSourceMap = {\n am: AMOscillator,\n fat: FatOscillator,\n fm: FMOscillator_FMOscillator,\n oscillator: Oscillator_Oscillator,\n pulse: PulseOscillator,\n pwm: PWMOscillator,\n};\n/**\n * OmniOscillator aggregates all of the oscillator types into one.\n * @example\n * return Tone.Offline(() => {\n * \tconst omniOsc = new Tone.OmniOscillator("C#4", "pwm").toDestination().start();\n * }, 0.1, 1);\n * @category Source\n */\nclass OmniOscillator_OmniOscillator extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(OmniOscillator_OmniOscillator.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "OmniOscillator";\n const options = Defaults_optionsFromArguments(OmniOscillator_OmniOscillator.getDefaults(), arguments, ["frequency", "type"]);\n this.frequency = new Signal_Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal_Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n Interface_readOnly(this, ["frequency", "detune"]);\n // set the options\n this.set(options);\n }\n static getDefaults() {\n return Object.assign(Oscillator_Oscillator.getDefaults(), FMOscillator_FMOscillator.getDefaults(), AMOscillator.getDefaults(), FatOscillator.getDefaults(), PulseOscillator.getDefaults(), PWMOscillator.getDefaults());\n }\n /**\n * start the oscillator\n */\n _start(time) {\n this._oscillator.start(time);\n }\n /**\n * start the oscillator\n */\n _stop(time) {\n this._oscillator.stop(time);\n }\n _restart(time) {\n this._oscillator.restart(time);\n return this;\n }\n /**\n * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or\n * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator\n * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the\n * oscillator\'s class are accessible when the oscillator is set to that type, but throws an error\n * when it\'s not.\n * @example\n * const omniOsc = new Tone.OmniOscillator().toDestination().start();\n * omniOsc.type = "pwm";\n * // modulationFrequency is parameter which is available\n * // only when the type is "pwm".\n * omniOsc.modulationFrequency.value = 0.5;\n */\n get type() {\n let prefix = "";\n if (["am", "fm", "fat"].some(p => this._sourceType === p)) {\n prefix = this._sourceType;\n }\n return prefix + this._oscillator.type;\n }\n set type(type) {\n if (type.substr(0, 2) === "fm") {\n this._createNewOscillator("fm");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(2);\n }\n else if (type.substr(0, 2) === "am") {\n this._createNewOscillator("am");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(2);\n }\n else if (type.substr(0, 3) === "fat") {\n this._createNewOscillator("fat");\n this._oscillator = this._oscillator;\n this._oscillator.type = type.substr(3);\n }\n else if (type === "pwm") {\n this._createNewOscillator("pwm");\n this._oscillator = this._oscillator;\n }\n else if (type === "pulse") {\n this._createNewOscillator("pulse");\n }\n else {\n this._createNewOscillator("oscillator");\n this._oscillator = this._oscillator;\n this._oscillator.type = type;\n }\n }\n /**\n * The value is an empty array when the type is not "custom".\n * This is not available on "pwm" and "pulse" oscillator types.\n * See [[Oscillator.partials]]\n */\n get partials() {\n return this._oscillator.partials;\n }\n set partials(partials) {\n if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) {\n this._oscillator.partials = partials;\n }\n }\n get partialCount() {\n return this._oscillator.partialCount;\n }\n set partialCount(partialCount) {\n if (!this._getOscType(this._oscillator, "pulse") && !this._getOscType(this._oscillator, "pwm")) {\n this._oscillator.partialCount = partialCount;\n }\n }\n set(props) {\n // make sure the type is set first\n if (Reflect.has(props, "type") && props.type) {\n this.type = props.type;\n }\n // then set the rest\n super.set(props);\n return this;\n }\n /**\n * connect the oscillator to the frequency and detune signals\n */\n _createNewOscillator(oscType) {\n if (oscType !== this._sourceType) {\n this._sourceType = oscType;\n const OscConstructor = OmniOscillatorSourceMap[oscType];\n // short delay to avoid clicks on the change\n const now = this.now();\n if (this._oscillator) {\n const oldOsc = this._oscillator;\n oldOsc.stop(now);\n // dispose the old one\n this.context.setTimeout(() => oldOsc.dispose(), this.blockTime);\n }\n this._oscillator = new OscConstructor({\n context: this.context,\n });\n this.frequency.connect(this._oscillator.frequency);\n this.detune.connect(this._oscillator.detune);\n this._oscillator.connect(this.output);\n this._oscillator.onstop = () => this.onstop(this);\n if (this.state === "started") {\n this._oscillator.start(now);\n }\n }\n }\n get phase() {\n return this._oscillator.phase;\n }\n set phase(phase) {\n this._oscillator.phase = phase;\n }\n /**\n * The source type of the oscillator.\n * @example\n * const omniOsc = new Tone.OmniOscillator(440, "fmsquare");\n * console.log(omniOsc.sourceType); // \'fm\'\n */\n get sourceType() {\n return this._sourceType;\n }\n set sourceType(sType) {\n // the basetype defaults to sine\n let baseType = "sine";\n if (this._oscillator.type !== "pwm" && this._oscillator.type !== "pulse") {\n baseType = this._oscillator.type;\n }\n // set the type\n if (sType === "fm") {\n this.type = "fm" + baseType;\n }\n else if (sType === "am") {\n this.type = "am" + baseType;\n }\n else if (sType === "fat") {\n this.type = "fat" + baseType;\n }\n else if (sType === "oscillator") {\n this.type = baseType;\n }\n else if (sType === "pulse") {\n this.type = "pulse";\n }\n else if (sType === "pwm") {\n this.type = "pwm";\n }\n }\n _getOscType(osc, sourceType) {\n return osc instanceof OmniOscillatorSourceMap[sourceType];\n }\n /**\n * The base type of the oscillator. See [[Oscillator.baseType]]\n * @example\n * const omniOsc = new Tone.OmniOscillator(440, "fmsquare4");\n * console.log(omniOsc.sourceType, omniOsc.baseType, omniOsc.partialCount);\n */\n get baseType() {\n return this._oscillator.baseType;\n }\n set baseType(baseType) {\n if (!this._getOscType(this._oscillator, "pulse") &&\n !this._getOscType(this._oscillator, "pwm") &&\n baseType !== "pulse" && baseType !== "pwm") {\n this._oscillator.baseType = baseType;\n }\n }\n /**\n * The width of the oscillator when sourceType === "pulse".\n * See [[PWMOscillator.width]]\n */\n get width() {\n if (this._getOscType(this._oscillator, "pulse")) {\n return this._oscillator.width;\n }\n else {\n return undefined;\n }\n }\n /**\n * The number of detuned oscillators when sourceType === "fat".\n * See [[FatOscillator.count]]\n */\n get count() {\n if (this._getOscType(this._oscillator, "fat")) {\n return this._oscillator.count;\n }\n else {\n return undefined;\n }\n }\n set count(count) {\n if (this._getOscType(this._oscillator, "fat") && TypeCheck_isNumber(count)) {\n this._oscillator.count = count;\n }\n }\n /**\n * The detune spread between the oscillators when sourceType === "fat".\n * See [[FatOscillator.count]]\n */\n get spread() {\n if (this._getOscType(this._oscillator, "fat")) {\n return this._oscillator.spread;\n }\n else {\n return undefined;\n }\n }\n set spread(spread) {\n if (this._getOscType(this._oscillator, "fat") && TypeCheck_isNumber(spread)) {\n this._oscillator.spread = spread;\n }\n }\n /**\n * The type of the modulator oscillator. Only if the oscillator is set to "am" or "fm" types.\n * See [[AMOscillator]] or [[FMOscillator]]\n */\n get modulationType() {\n if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) {\n return this._oscillator.modulationType;\n }\n else {\n return undefined;\n }\n }\n set modulationType(mType) {\n if ((this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) && TypeCheck_isString(mType)) {\n this._oscillator.modulationType = mType;\n }\n }\n /**\n * The modulation index when the sourceType === "fm"\n * See [[FMOscillator]].\n */\n get modulationIndex() {\n if (this._getOscType(this._oscillator, "fm")) {\n return this._oscillator.modulationIndex;\n }\n else {\n return undefined;\n }\n }\n /**\n * Harmonicity is the frequency ratio between the carrier and the modulator oscillators.\n * See [[AMOscillator]] or [[FMOscillator]]\n */\n get harmonicity() {\n if (this._getOscType(this._oscillator, "fm") || this._getOscType(this._oscillator, "am")) {\n return this._oscillator.harmonicity;\n }\n else {\n return undefined;\n }\n }\n /**\n * The modulationFrequency Signal of the oscillator when sourceType === "pwm"\n * see [[PWMOscillator]]\n * @min 0.1\n * @max 5\n */\n get modulationFrequency() {\n if (this._getOscType(this._oscillator, "pwm")) {\n return this._oscillator.modulationFrequency;\n }\n else {\n return undefined;\n }\n }\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n return generateWaveform(this, length);\n });\n }\n dispose() {\n super.dispose();\n this.detune.dispose();\n this.frequency.dispose();\n this._oscillator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=OmniOscillator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Add.js\n\n\n\n\n/**\n * Add a signal and a number or two signals. When no value is\n * passed into the constructor, Tone.Add will sum input and `addend`\n * If a value is passed into the constructor, the it will be added to the input.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst add = new Tone.Add(2).toDestination();\n * \tadd.addend.setValueAtTime(1, 0.2);\n * \tconst signal = new Tone.Signal(2);\n * \t// add a signal and a scalar\n * \tsignal.connect(add);\n * \tsignal.setValueAtTime(1, 0.1);\n * }, 0.5, 1);\n * @category Signal\n */\nclass Add_Add extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Add_Add.getDefaults(), arguments, ["value"])));\n this.override = false;\n this.name = "Add";\n /**\n * the summing node\n */\n this._sum = new Gain({ context: this.context });\n this.input = this._sum;\n this.output = this._sum;\n /**\n * The value which is added to the input signal\n */\n this.addend = this._param;\n connectSeries(this._constantSource, this._sum);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._sum.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Add.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Scale.js\n\n\n\n\n/**\n * Performs a linear scaling on an input signal.\n * Scales a NormalRange input to between\n * outputMin and outputMax.\n *\n * @example\n * const scale = new Tone.Scale(50, 100);\n * const signal = new Tone.Signal(0.5).connect(scale);\n * // the output of scale equals 75\n * @category Signal\n */\nclass Scale_Scale extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Scale_Scale.getDefaults(), arguments, ["min", "max"])));\n this.name = "Scale";\n const options = optionsFromArguments(Scale_Scale.getDefaults(), arguments, ["min", "max"]);\n this._mult = this.input = new Multiply({\n context: this.context,\n value: options.max - options.min,\n });\n this._add = this.output = new Add({\n context: this.context,\n value: options.min,\n });\n this._min = options.min;\n this._max = options.max;\n this.input.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(SignalOperator.getDefaults(), {\n max: 1,\n min: 0,\n });\n }\n /**\n * The minimum output value. This number is output when the value input value is 0.\n */\n get min() {\n return this._min;\n }\n set min(min) {\n this._min = min;\n this._setRange();\n }\n /**\n * The maximum output value. This number is output when the value input value is 1.\n */\n get max() {\n return this._max;\n }\n set max(max) {\n this._max = max;\n this._setRange();\n }\n /**\n * set the values\n */\n _setRange() {\n this._add.value = this._min;\n this._mult.value = this._max - this._min;\n }\n dispose() {\n super.dispose();\n this._add.dispose();\n this._mult.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Scale.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Zero.js\n\n\n\n\n/**\n * Tone.Zero outputs 0\'s at audio-rate. The reason this has to be\n * it\'s own class is that many browsers optimize out Tone.Signal\n * with a value of 0 and will not process nodes further down the graph.\n * @category Signal\n */\nclass Zero_Zero extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Zero_Zero.getDefaults(), arguments)));\n this.name = "Zero";\n /**\n * The gain node which connects the constant source to the output\n */\n this._gain = new Gain({ context: this.context });\n /**\n * Only outputs 0\n */\n this.output = this._gain;\n /**\n * no input node\n */\n this.input = undefined;\n connect(this.context.getConstant(0), this._gain);\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n disconnect(this.context.getConstant(0), this._gain);\n return this;\n }\n}\n//# sourceMappingURL=Zero.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/oscillator/LFO.js\n\n\n\n\n\n\n\n\n\n\n/**\n * LFO stands for low frequency oscillator. LFO produces an output signal\n * which can be attached to an AudioParam or Tone.Signal\n * in order to modulate that parameter with an oscillator. The LFO can\n * also be synced to the transport to start/stop and change when the tempo changes.\n * @example\n * return Tone.Offline(() => {\n * \tconst lfo = new Tone.LFO("4n", 400, 4000).start().toDestination();\n * }, 0.5, 1);\n * @category Source\n */\nclass LFO_LFO extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(LFO_LFO.getDefaults(), arguments, ["frequency", "min", "max"]));\n this.name = "LFO";\n /**\n * The value that the LFO outputs when it\'s stopped\n */\n this._stoppedValue = 0;\n /**\n * A private placeholder for the units\n */\n this._units = "number";\n /**\n * If the input value is converted using the [[units]]\n */\n this.convert = true;\n /**\n * Private methods borrowed from Param\n */\n // @ts-ignore\n this._fromType = Param.prototype._fromType;\n // @ts-ignore\n this._toType = Param.prototype._toType;\n // @ts-ignore\n this._is = Param.prototype._is;\n // @ts-ignore\n this._clampValue = Param.prototype._clampValue;\n const options = optionsFromArguments(LFO_LFO.getDefaults(), arguments, ["frequency", "min", "max"]);\n this._oscillator = new Oscillator(options);\n this.frequency = this._oscillator.frequency;\n this._amplitudeGain = new Gain({\n context: this.context,\n gain: options.amplitude,\n units: "normalRange",\n });\n this.amplitude = this._amplitudeGain.gain;\n this._stoppedSignal = new Signal({\n context: this.context,\n units: "audioRange",\n value: 0,\n });\n this._zeros = new Zero({ context: this.context });\n this._a2g = new AudioToGain({ context: this.context });\n this._scaler = this.output = new Scale({\n context: this.context,\n max: options.max,\n min: options.min,\n });\n this.units = options.units;\n this.min = options.min;\n this.max = options.max;\n // connect it up\n this._oscillator.chain(this._amplitudeGain, this._a2g, this._scaler);\n this._zeros.connect(this._a2g);\n this._stoppedSignal.connect(this._a2g);\n readOnly(this, ["amplitude", "frequency"]);\n this.phase = options.phase;\n }\n static getDefaults() {\n return Object.assign(Oscillator.getDefaults(), {\n amplitude: 1,\n frequency: "4n",\n max: 1,\n min: 0,\n type: "sine",\n units: "number",\n });\n }\n /**\n * Start the LFO.\n * @param time The time the LFO will start\n */\n start(time) {\n time = this.toSeconds(time);\n this._stoppedSignal.setValueAtTime(0, time);\n this._oscillator.start(time);\n return this;\n }\n /**\n * Stop the LFO.\n * @param time The time the LFO will stop\n */\n stop(time) {\n time = this.toSeconds(time);\n this._stoppedSignal.setValueAtTime(this._stoppedValue, time);\n this._oscillator.stop(time);\n return this;\n }\n /**\n * Sync the start/stop/pause to the transport\n * and the frequency to the bpm of the transport\n * @example\n * const lfo = new Tone.LFO("8n");\n * lfo.sync().start(0);\n * // the rate of the LFO will always be an eighth note, even as the tempo changes\n */\n sync() {\n this._oscillator.sync();\n this._oscillator.syncFrequency();\n return this;\n }\n /**\n * unsync the LFO from transport control\n */\n unsync() {\n this._oscillator.unsync();\n this._oscillator.unsyncFrequency();\n return this;\n }\n /**\n * After the oscillator waveform is updated, reset the `_stoppedSignal` value to match the updated waveform\n */\n _setStoppedValue() {\n this._stoppedValue = this._oscillator.getInitialValue();\n this._stoppedSignal.value = this._stoppedValue;\n }\n /**\n * The minimum output of the LFO.\n */\n get min() {\n return this._toType(this._scaler.min);\n }\n set min(min) {\n min = this._fromType(min);\n this._scaler.min = min;\n }\n /**\n * The maximum output of the LFO.\n */\n get max() {\n return this._toType(this._scaler.max);\n }\n set max(max) {\n max = this._fromType(max);\n this._scaler.max = max;\n }\n /**\n * The type of the oscillator: See [[Oscillator.type]]\n */\n get type() {\n return this._oscillator.type;\n }\n set type(type) {\n this._oscillator.type = type;\n this._setStoppedValue();\n }\n /**\n * The oscillator\'s partials array: See [[Oscillator.partials]]\n */\n get partials() {\n return this._oscillator.partials;\n }\n set partials(partials) {\n this._oscillator.partials = partials;\n this._setStoppedValue();\n }\n /**\n * The phase of the LFO.\n */\n get phase() {\n return this._oscillator.phase;\n }\n set phase(phase) {\n this._oscillator.phase = phase;\n this._setStoppedValue();\n }\n /**\n * The output units of the LFO.\n */\n get units() {\n return this._units;\n }\n set units(val) {\n const currentMin = this.min;\n const currentMax = this.max;\n // convert the min and the max\n this._units = val;\n this.min = currentMin;\n this.max = currentMax;\n }\n /**\n * Returns the playback state of the source, either "started" or "stopped".\n */\n get state() {\n return this._oscillator.state;\n }\n /**\n * @param node the destination to connect to\n * @param outputNum the optional output number\n * @param inputNum the input number\n */\n connect(node, outputNum, inputNum) {\n if (node instanceof Param || node instanceof Signal) {\n this.convert = node.convert;\n this.units = node.units;\n }\n connectSignal(this, node, outputNum, inputNum);\n return this;\n }\n dispose() {\n super.dispose();\n this._oscillator.dispose();\n this._stoppedSignal.dispose();\n this._zeros.dispose();\n this._scaler.dispose();\n this._a2g.dispose();\n this._amplitudeGain.dispose();\n this.amplitude.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LFO.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/util/Decorator.js\n\n/**\n * Assert that the number is in the given range.\n */\nfunction range(min, max = Infinity) {\n const valueMap = new WeakMap();\n return function (target, propertyKey) {\n Reflect.defineProperty(target, propertyKey, {\n configurable: true,\n enumerable: true,\n get: function () {\n return valueMap.get(this);\n },\n set: function (newValue) {\n Debug_assertRange(newValue, min, max);\n valueMap.set(this, newValue);\n }\n });\n };\n}\n/**\n * Convert the time to seconds and assert that the time is in between the two\n * values when being set.\n */\nfunction timeRange(min, max = Infinity) {\n const valueMap = new WeakMap();\n return function (target, propertyKey) {\n Reflect.defineProperty(target, propertyKey, {\n configurable: true,\n enumerable: true,\n get: function () {\n return valueMap.get(this);\n },\n set: function (newValue) {\n Debug_assertRange(this.toSeconds(newValue), min, max);\n valueMap.set(this, newValue);\n }\n });\n };\n}\n//# sourceMappingURL=Decorator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/Player.js\n\n\n\n\n\n\n\n\n\n/**\n * Player is an audio file player with start, loop, and stop functions.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gong_1.mp3").toDestination();\n * // play as soon as the buffer is loaded\n * player.autostart = true;\n * @category Source\n */\nclass Player_Player extends Source_Source {\n constructor() {\n super(Defaults_optionsFromArguments(Player_Player.getDefaults(), arguments, ["url", "onload"]));\n this.name = "Player";\n /**\n * All of the active buffer source nodes\n */\n this._activeSources = new Set();\n const options = Defaults_optionsFromArguments(Player_Player.getDefaults(), arguments, ["url", "onload"]);\n this._buffer = new ToneAudioBuffer_ToneAudioBuffer({\n onload: this._onload.bind(this, options.onload),\n onerror: options.onerror,\n reverse: options.reverse,\n url: options.url,\n });\n this.autostart = options.autostart;\n this._loop = options.loop;\n this._loopStart = options.loopStart;\n this._loopEnd = options.loopEnd;\n this._playbackRate = options.playbackRate;\n this.fadeIn = options.fadeIn;\n this.fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source_Source.getDefaults(), {\n autostart: false,\n fadeIn: 0,\n fadeOut: 0,\n loop: false,\n loopEnd: 0,\n loopStart: 0,\n onload: Interface_noOp,\n onerror: Interface_noOp,\n playbackRate: 1,\n reverse: false,\n });\n }\n /**\n * Load the audio file as an audio buffer.\n * Decodes the audio asynchronously and invokes\n * the callback once the audio buffer loads.\n * Note: this does not need to be called if a url\n * was passed in to the constructor. Only use this\n * if you want to manually load a new url.\n * @param url The url of the buffer to load. Filetype support depends on the browser.\n */\n load(url) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n yield this._buffer.load(url);\n this._onload();\n return this;\n });\n }\n /**\n * Internal callback when the buffer is loaded.\n */\n _onload(callback = Interface_noOp) {\n callback();\n if (this.autostart) {\n this.start();\n }\n }\n /**\n * Internal callback when the buffer is done playing.\n */\n _onSourceEnd(source) {\n // invoke the onstop function\n this.onstop(this);\n // delete the source from the active sources\n this._activeSources.delete(source);\n if (this._activeSources.size === 0 && !this._synced &&\n this._state.getValueAtTime(this.now()) === "started") {\n // remove the \'implicitEnd\' event and replace with an explicit end\n this._state.cancel(this.now());\n this._state.setStateAtTime("stopped", this.now());\n }\n }\n /**\n * Play the buffer at the given startTime. Optionally add an offset\n * and/or duration which will play the buffer from a position\n * within the buffer for the given duration.\n *\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given, it will default to the full length of the sample (minus any offset)\n */\n start(time, offset, duration) {\n super.start(time, offset, duration);\n return this;\n }\n /**\n * Internal start method\n */\n _start(startTime, offset, duration) {\n // if it\'s a loop the default offset is the loopStart point\n if (this._loop) {\n offset = Defaults_defaultArg(offset, this._loopStart);\n }\n else {\n // otherwise the default offset is 0\n offset = Defaults_defaultArg(offset, 0);\n }\n // compute the values in seconds\n const computedOffset = this.toSeconds(offset);\n // compute the duration which is either the passed in duration of the buffer.duration - offset\n const origDuration = duration;\n duration = Defaults_defaultArg(duration, Math.max(this._buffer.duration - computedOffset, 0));\n let computedDuration = this.toSeconds(duration);\n // scale it by the playback rate\n computedDuration = computedDuration / this._playbackRate;\n // get the start time\n startTime = this.toSeconds(startTime);\n // make the source\n const source = new ToneBufferSource_ToneBufferSource({\n url: this._buffer,\n context: this.context,\n fadeIn: this.fadeIn,\n fadeOut: this.fadeOut,\n loop: this._loop,\n loopEnd: this._loopEnd,\n loopStart: this._loopStart,\n onended: this._onSourceEnd.bind(this),\n playbackRate: this._playbackRate,\n }).connect(this.output);\n // set the looping properties\n if (!this._loop && !this._synced) {\n // cancel the previous stop\n this._state.cancel(startTime + computedDuration);\n // if it\'s not looping, set the state change at the end of the sample\n this._state.setStateAtTime("stopped", startTime + computedDuration, {\n implicitEnd: true,\n });\n }\n // add it to the array of active sources\n this._activeSources.add(source);\n // start it\n if (this._loop && TypeCheck_isUndef(origDuration)) {\n source.start(startTime, computedOffset);\n }\n else {\n // subtract the fade out time\n source.start(startTime, computedOffset, computedDuration - this.toSeconds(this.fadeOut));\n }\n }\n /**\n * Stop playback.\n */\n _stop(time) {\n const computedTime = this.toSeconds(time);\n this._activeSources.forEach(source => source.stop(computedTime));\n }\n /**\n * Stop and then restart the player from the beginning (or offset)\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given,\n * \t\t\t\t\tit will default to the full length of the sample (minus any offset)\n */\n restart(time, offset, duration) {\n super.restart(time, offset, duration);\n return this;\n }\n _restart(time, offset, duration) {\n this._stop(time);\n this._start(time, offset, duration);\n }\n /**\n * Seek to a specific time in the player\'s buffer. If the\n * source is no longer playing at that time, it will stop.\n * @param offset The time to seek to.\n * @param when The time for the seek event to occur.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/gurgling_theremin_1.mp3", () => {\n * \tplayer.start();\n * \t// seek to the offset in 1 second from now\n * \tplayer.seek(0.4, "+1");\n * }).toDestination();\n */\n seek(offset, when) {\n const computedTime = this.toSeconds(when);\n if (this._state.getValueAtTime(computedTime) === "started") {\n const computedOffset = this.toSeconds(offset);\n // if it\'s currently playing, stop it\n this._stop(computedTime);\n // restart it at the given time\n this._start(computedTime, computedOffset);\n }\n return this;\n }\n /**\n * Set the loop start and end. Will only loop if loop is set to true.\n * @param loopStart The loop start time\n * @param loopEnd The loop end time\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/malevoices_aa2_F3.mp3").toDestination();\n * // loop between the given points\n * player.setLoopPoints(0.2, 0.3);\n * player.loop = true;\n * player.autostart = true;\n */\n setLoopPoints(loopStart, loopEnd) {\n this.loopStart = loopStart;\n this.loopEnd = loopEnd;\n return this;\n }\n /**\n * If loop is true, the loop will start at this position.\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(loopStart) {\n this._loopStart = loopStart;\n if (this.buffer.loaded) {\n Debug_assertRange(this.toSeconds(loopStart), 0, this.buffer.duration);\n }\n // get the current source\n this._activeSources.forEach(source => {\n source.loopStart = loopStart;\n });\n }\n /**\n * If loop is true, the loop will end at this position.\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(loopEnd) {\n this._loopEnd = loopEnd;\n if (this.buffer.loaded) {\n Debug_assertRange(this.toSeconds(loopEnd), 0, this.buffer.duration);\n }\n // get the current source\n this._activeSources.forEach(source => {\n source.loopEnd = loopEnd;\n });\n }\n /**\n * The audio buffer belonging to the player.\n */\n get buffer() {\n return this._buffer;\n }\n set buffer(buffer) {\n this._buffer.set(buffer);\n }\n /**\n * If the buffer should loop once it\'s over.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/drum-samples/breakbeat.mp3").toDestination();\n * player.loop = true;\n * player.autostart = true;\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n // if no change, do nothing\n if (this._loop === loop) {\n return;\n }\n this._loop = loop;\n // set the loop of all of the sources\n this._activeSources.forEach(source => {\n source.loop = loop;\n });\n if (loop) {\n // remove the next stopEvent\n const stopEvent = this._state.getNextState("stopped", this.now());\n if (stopEvent) {\n this._state.cancel(stopEvent.time);\n }\n }\n }\n /**\n * Normal speed is 1. The pitch will change with the playback rate.\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/femalevoices_aa2_A5.mp3").toDestination();\n * // play at 1/4 speed\n * player.playbackRate = 0.25;\n * // play as soon as the buffer is loaded\n * player.autostart = true;\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n const now = this.now();\n // cancel the stop event since it\'s at a different time now\n const stopEvent = this._state.getNextState("stopped", now);\n if (stopEvent && stopEvent.implicitEnd) {\n this._state.cancel(stopEvent.time);\n this._activeSources.forEach(source => source.cancelStop());\n }\n // set all the sources\n this._activeSources.forEach(source => {\n source.playbackRate.setValueAtTime(rate, now);\n });\n }\n /**\n * If the buffer should be reversed\n * @example\n * const player = new Tone.Player("https://tonejs.github.io/audio/berklee/chime_1.mp3").toDestination();\n * player.autostart = true;\n * player.reverse = true;\n */\n get reverse() {\n return this._buffer.reverse;\n }\n set reverse(rev) {\n this._buffer.reverse = rev;\n }\n /**\n * If the buffer is loaded\n */\n get loaded() {\n return this._buffer.loaded;\n }\n dispose() {\n super.dispose();\n // disconnect all of the players\n this._activeSources.forEach(source => source.dispose());\n this._activeSources.clear();\n this._buffer.dispose();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Player_Player.prototype, "fadeIn", void 0);\n__decorate([\n timeRange(0)\n], Player_Player.prototype, "fadeOut", void 0);\n//# sourceMappingURL=Player.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/Players.js\n\n\n\n\n\n\n\n\n/**\n * Players combines multiple [[Player]] objects.\n * @category Source\n */\nclass Players extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls"));\n this.name = "Players";\n /**\n * Players has no input.\n */\n this.input = undefined;\n /**\n * The container of all of the players\n */\n this._players = new Map();\n const options = optionsFromArguments(Players.getDefaults(), arguments, ["urls", "onload"], "urls");\n /**\n * The output volume node\n */\n this._volume = this.output = new Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n readOnly(this, "volume");\n this._buffers = new ToneAudioBuffers({\n urls: options.urls,\n onload: options.onload,\n baseUrl: options.baseUrl,\n onerror: options.onerror\n });\n // mute initially\n this.mute = options.mute;\n this._fadeIn = options.fadeIn;\n this._fadeOut = options.fadeOut;\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n baseUrl: "",\n fadeIn: 0,\n fadeOut: 0,\n mute: false,\n onload: noOp,\n onerror: noOp,\n urls: {},\n volume: 0,\n });\n }\n /**\n * Mute the output.\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n /**\n * The fadeIn time of the envelope applied to the source.\n */\n get fadeIn() {\n return this._fadeIn;\n }\n set fadeIn(fadeIn) {\n this._fadeIn = fadeIn;\n this._players.forEach(player => {\n player.fadeIn = fadeIn;\n });\n }\n /**\n * The fadeOut time of the each of the sources.\n */\n get fadeOut() {\n return this._fadeOut;\n }\n set fadeOut(fadeOut) {\n this._fadeOut = fadeOut;\n this._players.forEach(player => {\n player.fadeOut = fadeOut;\n });\n }\n /**\n * The state of the players object. Returns "started" if any of the players are playing.\n */\n get state() {\n const playing = Array.from(this._players).some(([_, player]) => player.state === "started");\n return playing ? "started" : "stopped";\n }\n /**\n * True if the buffers object has a buffer by that name.\n * @param name The key or index of the buffer.\n */\n has(name) {\n return this._buffers.has(name);\n }\n /**\n * Get a player by name.\n * @param name The players name as defined in the constructor object or `add` method.\n */\n player(name) {\n assert(this.has(name), `No Player with the name ${name} exists on this object`);\n if (!this._players.has(name)) {\n const player = new Player({\n context: this.context,\n fadeIn: this._fadeIn,\n fadeOut: this._fadeOut,\n url: this._buffers.get(name),\n }).connect(this.output);\n this._players.set(name, player);\n }\n return this._players.get(name);\n }\n /**\n * If all the buffers are loaded or not\n */\n get loaded() {\n return this._buffers.loaded;\n }\n /**\n * Add a player by name and url to the Players\n * @param name A unique name to give the player\n * @param url Either the url of the bufer or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n */\n add(name, url, callback) {\n assert(!this._buffers.has(name), "A buffer with that name already exists on this object");\n this._buffers.add(name, url, callback);\n return this;\n }\n /**\n * Stop all of the players at the given time\n * @param time The time to stop all of the players.\n */\n stopAll(time) {\n this._players.forEach(player => player.stop(time));\n return this;\n }\n dispose() {\n super.dispose();\n this._volume.dispose();\n this.volume.dispose();\n this._players.forEach(player => player.dispose());\n this._buffers.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Players.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/buffer/GrainPlayer.js\n\n\n\n\n\n\n\n\n/**\n * GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis).\n * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the\n * amount of time each small chunk of audio is played for and the overlap is the\n * amount of crossfading transition time between successive grains.\n * @category Source\n */\nclass GrainPlayer extends (/* unused pure expression or super */ null && (Source)) {\n constructor() {\n super(optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]));\n this.name = "GrainPlayer";\n /**\n * Internal loopStart value\n */\n this._loopStart = 0;\n /**\n * Internal loopStart value\n */\n this._loopEnd = 0;\n /**\n * All of the currently playing BufferSources\n */\n this._activeSources = [];\n const options = optionsFromArguments(GrainPlayer.getDefaults(), arguments, ["url", "onload"]);\n this.buffer = new ToneAudioBuffer({\n onload: options.onload,\n onerror: options.onerror,\n reverse: options.reverse,\n url: options.url,\n });\n this._clock = new Clock({\n context: this.context,\n callback: this._tick.bind(this),\n frequency: 1 / options.grainSize\n });\n this._playbackRate = options.playbackRate;\n this._grainSize = options.grainSize;\n this._overlap = options.overlap;\n this.detune = options.detune;\n // setup\n this.overlap = options.overlap;\n this.loop = options.loop;\n this.playbackRate = options.playbackRate;\n this.grainSize = options.grainSize;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this.reverse = options.reverse;\n this._clock.on("stop", this._onstop.bind(this));\n }\n static getDefaults() {\n return Object.assign(Source.getDefaults(), {\n onload: noOp,\n onerror: noOp,\n overlap: 0.1,\n grainSize: 0.2,\n playbackRate: 1,\n detune: 0,\n loop: false,\n loopStart: 0,\n loopEnd: 0,\n reverse: false\n });\n }\n /**\n * Internal start method\n */\n _start(time, offset, duration) {\n offset = defaultArg(offset, 0);\n offset = this.toSeconds(offset);\n time = this.toSeconds(time);\n const grainSize = 1 / this._clock.frequency.getValueAtTime(time);\n this._clock.start(time, offset / grainSize);\n if (duration) {\n this.stop(time + this.toSeconds(duration));\n }\n }\n /**\n * Stop and then restart the player from the beginning (or offset)\n * @param time When the player should start.\n * @param offset The offset from the beginning of the sample to start at.\n * @param duration How long the sample should play. If no duration is given,\n * \t\t\t\t\tit will default to the full length of the sample (minus any offset)\n */\n restart(time, offset, duration) {\n super.restart(time, offset, duration);\n return this;\n }\n _restart(time, offset, duration) {\n this._stop(time);\n this._start(time, offset, duration);\n }\n /**\n * Internal stop method\n */\n _stop(time) {\n this._clock.stop(time);\n }\n /**\n * Invoked when the clock is stopped\n */\n _onstop(time) {\n // stop the players\n this._activeSources.forEach((source) => {\n source.fadeOut = 0;\n source.stop(time);\n });\n this.onstop(this);\n }\n /**\n * Invoked on each clock tick. scheduled a new grain at this time.\n */\n _tick(time) {\n // check if it should stop looping\n const ticks = this._clock.getTicksAtTime(time);\n const offset = ticks * this._grainSize;\n this.log("offset", offset);\n if (!this.loop && offset > this.buffer.duration) {\n this.stop(time);\n return;\n }\n // at the beginning of the file, the fade in should be 0\n const fadeIn = offset < this._overlap ? 0 : this._overlap;\n // create a buffer source\n const source = new ToneBufferSource({\n context: this.context,\n url: this.buffer,\n fadeIn: fadeIn,\n fadeOut: this._overlap,\n loop: this.loop,\n loopStart: this._loopStart,\n loopEnd: this._loopEnd,\n // compute the playbackRate based on the detune\n playbackRate: intervalToFrequencyRatio(this.detune / 100)\n }).connect(this.output);\n source.start(time, this._grainSize * ticks);\n source.stop(time + this._grainSize / this.playbackRate);\n // add it to the active sources\n this._activeSources.push(source);\n // remove it when it\'s done\n source.onended = () => {\n const index = this._activeSources.indexOf(source);\n if (index !== -1) {\n this._activeSources.splice(index, 1);\n }\n };\n }\n /**\n * The playback rate of the sample\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n assertRange(rate, 0.001);\n this._playbackRate = rate;\n this.grainSize = this._grainSize;\n }\n /**\n * The loop start time.\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(time) {\n if (this.buffer.loaded) {\n assertRange(this.toSeconds(time), 0, this.buffer.duration);\n }\n this._loopStart = this.toSeconds(time);\n }\n /**\n * The loop end time.\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(time) {\n if (this.buffer.loaded) {\n assertRange(this.toSeconds(time), 0, this.buffer.duration);\n }\n this._loopEnd = this.toSeconds(time);\n }\n /**\n * The direction the buffer should play in\n */\n get reverse() {\n return this.buffer.reverse;\n }\n set reverse(rev) {\n this.buffer.reverse = rev;\n }\n /**\n * The size of each chunk of audio that the\n * buffer is chopped into and played back at.\n */\n get grainSize() {\n return this._grainSize;\n }\n set grainSize(size) {\n this._grainSize = this.toSeconds(size);\n this._clock.frequency.setValueAtTime(this._playbackRate / this._grainSize, this.now());\n }\n /**\n * The duration of the cross-fade between successive grains.\n */\n get overlap() {\n return this._overlap;\n }\n set overlap(time) {\n const computedTime = this.toSeconds(time);\n assertRange(computedTime, 0);\n this._overlap = computedTime;\n }\n /**\n * If all the buffer is loaded\n */\n get loaded() {\n return this.buffer.loaded;\n }\n dispose() {\n super.dispose();\n this.buffer.dispose();\n this._clock.dispose();\n this._activeSources.forEach((source) => source.dispose());\n return this;\n }\n}\n//# sourceMappingURL=GrainPlayer.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/source/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Abs.js\n\n\n/**\n * Return the absolute value of an incoming signal.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst abs = new Tone.Abs().toDestination();\n * \tconst signal = new Tone.Signal(1);\n * \tsignal.rampTo(-1, 0.5);\n * \tsignal.connect(abs);\n * }, 0.5, 1);\n * @category Signal\n */\nclass Abs_Abs extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "Abs";\n /**\n * The node which converts the audio ranges\n */\n this._abs = new WaveShaper({\n context: this.context,\n mapping: val => {\n if (Math.abs(val) < 0.001) {\n return 0;\n }\n else {\n return Math.abs(val);\n }\n },\n });\n /**\n * The AudioRange input [-1, 1]\n */\n this.input = this._abs;\n /**\n * The output range [0, 1]\n */\n this.output = this._abs;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._abs.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Abs.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GainToAudio.js\n\n\n/**\n * GainToAudio converts an input in NormalRange [0,1] to AudioRange [-1,1].\n * See [[AudioToGain]].\n * @category Signal\n */\nclass GainToAudio_GainToAudio extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "GainToAudio";\n /**\n * The node which converts the audio ranges\n */\n this._norm = new WaveShaper({\n context: this.context,\n mapping: x => Math.abs(x) * 2 - 1,\n });\n /**\n * The NormalRange input [0, 1]\n */\n this.input = this._norm;\n /**\n * The AudioRange output [-1, 1]\n */\n this.output = this._norm;\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this._norm.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GainToAudio.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Negate.js\n\n\n/**\n * Negate the incoming signal. i.e. an input signal of 10 will output -10\n *\n * @example\n * const neg = new Tone.Negate();\n * const sig = new Tone.Signal(-2).connect(neg);\n * // output of neg is positive 2.\n * @category Signal\n */\nclass Negate_Negate extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(...arguments);\n this.name = "Negate";\n /**\n * negation is done by multiplying by -1\n */\n this._multiply = new Multiply({\n context: this.context,\n value: -1,\n });\n /**\n * The input and output are equal to the multiply node\n */\n this.input = this._multiply;\n this.output = this._multiply;\n }\n /**\n * clean up\n * @returns {Negate} this\n */\n dispose() {\n super.dispose();\n this._multiply.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Negate.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Subtract.js\n\n\n\n\n\n/**\n * Subtract the signal connected to the input is subtracted from the signal connected\n * The subtrahend.\n *\n * @example\n * // subtract a scalar from a signal\n * const sub = new Tone.Subtract(1);\n * const sig = new Tone.Signal(4).connect(sub);\n * // the output of sub is 3.\n * @example\n * // subtract two signals\n * const sub = new Tone.Subtract();\n * const sigA = new Tone.Signal(10);\n * const sigB = new Tone.Signal(2.5);\n * sigA.connect(sub);\n * sigB.connect(sub.subtrahend);\n * // output of sub is 7.5\n * @category Signal\n */\nclass Subtract_Subtract extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Subtract_Subtract.getDefaults(), arguments, ["value"])));\n this.override = false;\n this.name = "Subtract";\n /**\n * the summing node\n */\n this._sum = new Gain({ context: this.context });\n this.input = this._sum;\n this.output = this._sum;\n /**\n * Negate the input of the second input before connecting it to the summing node.\n */\n this._neg = new Negate({ context: this.context });\n /**\n * The value which is subtracted from the main signal\n */\n this.subtrahend = this._param;\n connectSeries(this._constantSource, this._neg, this._sum);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._neg.dispose();\n this._sum.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Subtract.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GreaterThanZero.js\n\n\n\n\n/**\n * GreaterThanZero outputs 1 when the input is strictly greater than zero\n * @example\n * return Tone.Offline(() => {\n * \tconst gt0 = new Tone.GreaterThanZero().toDestination();\n * \tconst sig = new Tone.Signal(0.5).connect(gt0);\n * \tsig.setValueAtTime(-1, 0.05);\n * }, 0.1, 1);\n * @category Signal\n */\nclass GreaterThanZero_GreaterThanZero extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(GreaterThanZero_GreaterThanZero.getDefaults(), arguments)));\n this.name = "GreaterThanZero";\n this._thresh = this.output = new WaveShaper({\n context: this.context,\n length: 127,\n mapping: (val) => {\n if (val <= 0) {\n return 0;\n }\n else {\n return 1;\n }\n },\n });\n this._scale = this.input = new Multiply({\n context: this.context,\n value: 10000\n });\n // connections\n this._scale.connect(this._thresh);\n }\n dispose() {\n super.dispose();\n this._scale.dispose();\n this._thresh.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GreaterThanZero.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/GreaterThan.js\n\n\n\n\n\n/**\n * Output 1 if the signal is greater than the value, otherwise outputs 0.\n * can compare two signals or a signal and a number.\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst gt = new Tone.GreaterThan(2).toDestination();\n * \tconst sig = new Tone.Signal(4).connect(gt);\n * }, 0.1, 1);\n * @category Signal\n */\nclass GreaterThan_GreaterThan extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(Object.assign(optionsFromArguments(GreaterThan_GreaterThan.getDefaults(), arguments, ["value"])));\n this.name = "GreaterThan";\n this.override = false;\n const options = optionsFromArguments(GreaterThan_GreaterThan.getDefaults(), arguments, ["value"]);\n this._subtract = this.input = new Subtract({\n context: this.context,\n value: options.value\n });\n this._gtz = this.output = new GreaterThanZero({ context: this.context });\n this.comparator = this._param = this._subtract.subtrahend;\n readOnly(this, "comparator");\n // connect\n this._subtract.connect(this._gtz);\n }\n static getDefaults() {\n return Object.assign(Signal.getDefaults(), {\n value: 0,\n });\n }\n dispose() {\n super.dispose();\n this._gtz.dispose();\n this._subtract.dispose();\n this.comparator.dispose();\n return this;\n }\n}\n//# sourceMappingURL=GreaterThan.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/Pow.js\n\n\n\n/**\n * Pow applies an exponent to the incoming signal. The incoming signal must be AudioRange [-1, 1]\n *\n * @example\n * const pow = new Tone.Pow(2);\n * const sig = new Tone.Signal(0.5).connect(pow);\n * // output of pow is 0.25.\n * @category Signal\n */\nclass Pow_Pow extends (/* unused pure expression or super */ null && (SignalOperator)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Pow_Pow.getDefaults(), arguments, ["value"])));\n this.name = "Pow";\n const options = optionsFromArguments(Pow_Pow.getDefaults(), arguments, ["value"]);\n this._exponentScaler = this.input = this.output = new WaveShaper({\n context: this.context,\n mapping: this._expFunc(options.value),\n length: 8192,\n });\n this._exponent = options.value;\n }\n static getDefaults() {\n return Object.assign(SignalOperator.getDefaults(), {\n value: 1,\n });\n }\n /**\n * the function which maps the waveshaper\n * @param exponent exponent value\n */\n _expFunc(exponent) {\n return (val) => {\n return Math.pow(Math.abs(val), exponent);\n };\n }\n /**\n * The value of the exponent.\n */\n get value() {\n return this._exponent;\n }\n set value(exponent) {\n this._exponent = exponent;\n this._exponentScaler.setMap(this._expFunc(this._exponent));\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._exponentScaler.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Pow.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/ScaleExp.js\n\n\n\n/**\n * Performs an exponential scaling on an input signal.\n * Scales a NormalRange value [0,1] exponentially\n * to the output range of outputMin to outputMax.\n * @example\n * const scaleExp = new Tone.ScaleExp(0, 100, 2);\n * const signal = new Tone.Signal(0.5).connect(scaleExp);\n * @category Signal\n */\nclass ScaleExp_ScaleExp extends (/* unused pure expression or super */ null && (Scale)) {\n constructor() {\n super(Object.assign(optionsFromArguments(ScaleExp_ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"])));\n this.name = "ScaleExp";\n const options = optionsFromArguments(ScaleExp_ScaleExp.getDefaults(), arguments, ["min", "max", "exponent"]);\n this.input = this._exp = new Pow({\n context: this.context,\n value: options.exponent,\n });\n this._exp.connect(this._mult);\n }\n static getDefaults() {\n return Object.assign(Scale.getDefaults(), {\n exponent: 1,\n });\n }\n /**\n * Instead of interpolating linearly between the [[min]] and\n * [[max]] values, setting the exponent will interpolate between\n * the two values with an exponential curve.\n */\n get exponent() {\n return this._exp.value;\n }\n set exponent(exp) {\n this._exp.value = exp;\n }\n dispose() {\n super.dispose();\n this._exp.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ScaleExp.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/SyncedSignal.js\n\n\n\n\n/**\n * Adds the ability to synchronize the signal to the [[Transport]]\n */\nclass SyncedSignal extends (/* unused pure expression or super */ null && (Signal)) {\n constructor() {\n super(optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]));\n this.name = "SyncedSignal";\n /**\n * Don\'t override when something is connected to the input\n */\n this.override = false;\n const options = optionsFromArguments(Signal.getDefaults(), arguments, ["value", "units"]);\n this._lastVal = options.value;\n this._synced = this.context.transport.scheduleRepeat(this._onTick.bind(this), "1i");\n this._syncedCallback = this._anchorValue.bind(this);\n this.context.transport.on("start", this._syncedCallback);\n this.context.transport.on("pause", this._syncedCallback);\n this.context.transport.on("stop", this._syncedCallback);\n // disconnect the constant source from the output and replace it with another one\n this._constantSource.disconnect();\n this._constantSource.stop(0);\n // create a new one\n this._constantSource = this.output = new ToneConstantSource({\n context: this.context,\n offset: options.value,\n units: options.units,\n }).start(0);\n this.setValueAtTime(options.value, 0);\n }\n /**\n * Callback which is invoked every tick.\n */\n _onTick(time) {\n const val = super.getValueAtTime(this.context.transport.seconds);\n // approximate ramp curves with linear ramps\n if (this._lastVal !== val) {\n this._lastVal = val;\n this._constantSource.offset.setValueAtTime(val, time);\n }\n }\n /**\n * Anchor the value at the start and stop of the Transport\n */\n _anchorValue(time) {\n const val = super.getValueAtTime(this.context.transport.seconds);\n this._lastVal = val;\n this._constantSource.offset.cancelAndHoldAtTime(time);\n this._constantSource.offset.setValueAtTime(val, time);\n }\n getValueAtTime(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n return super.getValueAtTime(computedTime);\n }\n setValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.setValueAtTime(value, computedTime);\n return this;\n }\n linearRampToValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.linearRampToValueAtTime(value, computedTime);\n return this;\n }\n exponentialRampToValueAtTime(value, time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.exponentialRampToValueAtTime(value, computedTime);\n return this;\n }\n setTargetAtTime(value, startTime, timeConstant) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.setTargetAtTime(value, computedTime, timeConstant);\n return this;\n }\n cancelScheduledValues(startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.cancelScheduledValues(computedTime);\n return this;\n }\n setValueCurveAtTime(values, startTime, duration, scaling) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n duration = this.toSeconds(duration);\n super.setValueCurveAtTime(values, computedTime, duration, scaling);\n return this;\n }\n cancelAndHoldAtTime(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.cancelAndHoldAtTime(computedTime);\n return this;\n }\n setRampPoint(time) {\n const computedTime = new TransportTimeClass(this.context, time).toSeconds();\n super.setRampPoint(computedTime);\n return this;\n }\n exponentialRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.exponentialRampTo(value, rampTime, computedTime);\n return this;\n }\n linearRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.linearRampTo(value, rampTime, computedTime);\n return this;\n }\n targetRampTo(value, rampTime, startTime) {\n const computedTime = new TransportTimeClass(this.context, startTime).toSeconds();\n super.targetRampTo(value, rampTime, computedTime);\n return this;\n }\n dispose() {\n super.dispose();\n this.context.transport.clear(this._synced);\n this.context.transport.off("start", this._syncedCallback);\n this.context.transport.off("pause", this._syncedCallback);\n this.context.transport.off("stop", this._syncedCallback);\n this._constantSource.dispose();\n return this;\n }\n}\n//# sourceMappingURL=SyncedSignal.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/signal/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/Envelope.js\n\n\n\n\n\n\n\n\n/**\n * Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope)\n * envelope generator. Envelope outputs a signal which\n * can be connected to an AudioParam or Tone.Signal.\n * ```\n * /\\\n * / \\\n * / \\\n * / \\\n * / \\___________\n * / \\\n * / \\\n * / \\\n * / \\\n * ```\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\tattack: 0.1,\n * \t\tdecay: 0.2,\n * \t\tsustain: 0.5,\n * \t\trelease: 0.8,\n * \t}).toDestination();\n * \tenv.triggerAttackRelease(0.5);\n * }, 1.5, 1);\n * @category Component\n */\nclass Envelope_Envelope extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Envelope_Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "Envelope";\n /**\n * the signal which is output.\n */\n this._sig = new Signal_Signal({\n context: this.context,\n value: 0,\n });\n /**\n * The output signal of the envelope\n */\n this.output = this._sig;\n /**\n * Envelope has no input\n */\n this.input = undefined;\n const options = Defaults_optionsFromArguments(Envelope_Envelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]);\n this.attack = options.attack;\n this.decay = options.decay;\n this.sustain = options.sustain;\n this.release = options.release;\n this.attackCurve = options.attackCurve;\n this.releaseCurve = options.releaseCurve;\n this.decayCurve = options.decayCurve;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n attack: 0.01,\n attackCurve: "linear",\n decay: 0.1,\n decayCurve: "exponential",\n release: 1,\n releaseCurve: "exponential",\n sustain: 0.5,\n });\n }\n /**\n * Read the current value of the envelope. Useful for\n * synchronizing visual output to the envelope.\n */\n get value() {\n return this.getValueAtTime(this.now());\n }\n /**\n * Get the curve\n * @param curve\n * @param direction In/Out\n * @return The curve name\n */\n _getCurve(curve, direction) {\n if (TypeCheck_isString(curve)) {\n return curve;\n }\n else {\n // look up the name in the curves array\n let curveName;\n for (curveName in EnvelopeCurves) {\n if (EnvelopeCurves[curveName][direction] === curve) {\n return curveName;\n }\n }\n // return the custom curve\n return curve;\n }\n }\n /**\n * Assign a the curve to the given name using the direction\n * @param name\n * @param direction In/Out\n * @param curve\n */\n _setCurve(name, direction, curve) {\n // check if it\'s a valid type\n if (TypeCheck_isString(curve) && Reflect.has(EnvelopeCurves, curve)) {\n const curveDef = EnvelopeCurves[curve];\n if (TypeCheck_isObject(curveDef)) {\n if (name !== "_decayCurve") {\n this[name] = curveDef[direction];\n }\n }\n else {\n this[name] = curveDef;\n }\n }\n else if (TypeCheck_isArray(curve) && name !== "_decayCurve") {\n this[name] = curve;\n }\n else {\n throw new Error("Envelope: invalid curve: " + curve);\n }\n }\n /**\n * The shape of the attack.\n * Can be any of these strings:\n * * "linear"\n * * "exponential"\n * * "sine"\n * * "cosine"\n * * "bounce"\n * * "ripple"\n * * "step"\n *\n * Can also be an array which describes the curve. Values\n * in the array are evenly subdivided and linearly\n * interpolated over the duration of the attack.\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope(0.4).toDestination();\n * \tenv.attackCurve = "linear";\n * \tenv.triggerAttack();\n * }, 1, 1);\n */\n get attackCurve() {\n return this._getCurve(this._attackCurve, "In");\n }\n set attackCurve(curve) {\n this._setCurve("_attackCurve", "In", curve);\n }\n /**\n * The shape of the release. See the attack curve types.\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\trelease: 0.8\n * \t}).toDestination();\n * \tenv.triggerAttack();\n * \t// release curve could also be defined by an array\n * \tenv.releaseCurve = [1, 0.3, 0.4, 0.2, 0.7, 0];\n * \tenv.triggerRelease(0.2);\n * }, 1, 1);\n */\n get releaseCurve() {\n return this._getCurve(this._releaseCurve, "Out");\n }\n set releaseCurve(curve) {\n this._setCurve("_releaseCurve", "Out", curve);\n }\n /**\n * The shape of the decay either "linear" or "exponential"\n * @example\n * return Tone.Offline(() => {\n * \tconst env = new Tone.Envelope({\n * \t\tsustain: 0.1,\n * \t\tdecay: 0.5\n * \t}).toDestination();\n * \tenv.decayCurve = "linear";\n * \tenv.triggerAttack();\n * }, 1, 1);\n */\n get decayCurve() {\n return this._decayCurve;\n }\n set decayCurve(curve) {\n Debug_assert(["linear", "exponential"].some(c => c === curve), `Invalid envelope curve: ${curve}`);\n this._decayCurve = curve;\n }\n /**\n * Trigger the attack/decay portion of the ADSR envelope.\n * @param time When the attack should start.\n * @param velocity The velocity of the envelope scales the vales.\n * number between 0-1\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator().connect(env).start();\n * // trigger the attack 0.5 seconds from now with a velocity of 0.2\n * env.triggerAttack("+0.5", 0.2);\n */\n triggerAttack(time, velocity = 1) {\n this.log("triggerAttack", time, velocity);\n time = this.toSeconds(time);\n const originalAttack = this.toSeconds(this.attack);\n let attack = originalAttack;\n const decay = this.toSeconds(this.decay);\n // check if it\'s not a complete attack\n const currentValue = this.getValueAtTime(time);\n if (currentValue > 0) {\n // subtract the current value from the attack time\n const attackRate = 1 / attack;\n const remainingDistance = 1 - currentValue;\n // the attack is now the remaining time\n attack = remainingDistance / attackRate;\n }\n // attack\n if (attack < this.sampleTime) {\n this._sig.cancelScheduledValues(time);\n // case where the attack time is 0 should set instantly\n this._sig.setValueAtTime(velocity, time);\n }\n else if (this._attackCurve === "linear") {\n this._sig.linearRampTo(velocity, attack, time);\n }\n else if (this._attackCurve === "exponential") {\n this._sig.targetRampTo(velocity, attack, time);\n }\n else {\n this._sig.cancelAndHoldAtTime(time);\n let curve = this._attackCurve;\n // find the starting position in the curve\n for (let i = 1; i < curve.length; i++) {\n // the starting index is between the two values\n if (curve[i - 1] <= currentValue && currentValue <= curve[i]) {\n curve = this._attackCurve.slice(i);\n // the first index is the current value\n curve[0] = currentValue;\n break;\n }\n }\n this._sig.setValueCurveAtTime(curve, time, attack, velocity);\n }\n // decay\n if (decay && this.sustain < 1) {\n const decayValue = velocity * this.sustain;\n const decayStart = time + attack;\n this.log("decay", decayStart);\n if (this._decayCurve === "linear") {\n this._sig.linearRampToValueAtTime(decayValue, decay + decayStart);\n }\n else {\n this._sig.exponentialApproachValueAtTime(decayValue, decayStart, decay);\n }\n }\n return this;\n }\n /**\n * Triggers the release of the envelope.\n * @param time When the release portion of the envelope should start.\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator({\n * \ttype: "sawtooth"\n * }).connect(env).start();\n * env.triggerAttack();\n * // trigger the release half a second after the attack\n * env.triggerRelease("+0.5");\n */\n triggerRelease(time) {\n this.log("triggerRelease", time);\n time = this.toSeconds(time);\n const currentValue = this.getValueAtTime(time);\n if (currentValue > 0) {\n const release = this.toSeconds(this.release);\n if (release < this.sampleTime) {\n this._sig.setValueAtTime(0, time);\n }\n else if (this._releaseCurve === "linear") {\n this._sig.linearRampTo(0, release, time);\n }\n else if (this._releaseCurve === "exponential") {\n this._sig.targetRampTo(0, release, time);\n }\n else {\n Debug_assert(TypeCheck_isArray(this._releaseCurve), "releaseCurve must be either \'linear\', \'exponential\' or an array");\n this._sig.cancelAndHoldAtTime(time);\n this._sig.setValueCurveAtTime(this._releaseCurve, time, release, currentValue);\n }\n }\n return this;\n }\n /**\n * Get the scheduled value at the given time. This will\n * return the unconverted (raw) value.\n * @example\n * const env = new Tone.Envelope(0.5, 1, 0.4, 2);\n * env.triggerAttackRelease(2);\n * setInterval(() => console.log(env.getValueAtTime(Tone.now())), 100);\n */\n getValueAtTime(time) {\n return this._sig.getValueAtTime(time);\n }\n /**\n * triggerAttackRelease is shorthand for triggerAttack, then waiting\n * some duration, then triggerRelease.\n * @param duration The duration of the sustain.\n * @param time When the attack should be triggered.\n * @param velocity The velocity of the envelope.\n * @example\n * const env = new Tone.AmplitudeEnvelope().toDestination();\n * const osc = new Tone.Oscillator().connect(env).start();\n * // trigger the release 0.5 seconds after the attack\n * env.triggerAttackRelease(0.5);\n */\n triggerAttackRelease(duration, time, velocity = 1) {\n time = this.toSeconds(time);\n this.triggerAttack(time, velocity);\n this.triggerRelease(time + this.toSeconds(duration));\n return this;\n }\n /**\n * Cancels all scheduled envelope changes after the given time.\n */\n cancel(after) {\n this._sig.cancelScheduledValues(this.toSeconds(after));\n return this;\n }\n /**\n * Connect the envelope to a destination node.\n */\n connect(destination, outputNumber = 0, inputNumber = 0) {\n Signal_connectSignal(this, destination, outputNumber, inputNumber);\n return this;\n }\n /**\n * Render the envelope curve to an array of the given length.\n * Good for visualizing the envelope curve. Rescales the duration of the\n * envelope to fit the length.\n */\n asArray(length = 1024) {\n return tslib_es6_awaiter(this, void 0, void 0, function* () {\n const duration = length / this.context.sampleRate;\n const context = new OfflineContext_OfflineContext(1, duration, this.context.sampleRate);\n // normalize the ADSR for the given duration with 20% sustain time\n const attackPortion = this.toSeconds(this.attack) + this.toSeconds(this.decay);\n const envelopeDuration = attackPortion + this.toSeconds(this.release);\n const sustainTime = envelopeDuration * 0.1;\n const totalDuration = envelopeDuration + sustainTime;\n // @ts-ignore\n const clone = new this.constructor(Object.assign(this.get(), {\n attack: duration * this.toSeconds(this.attack) / totalDuration,\n decay: duration * this.toSeconds(this.decay) / totalDuration,\n release: duration * this.toSeconds(this.release) / totalDuration,\n context\n }));\n clone._sig.toDestination();\n clone.triggerAttackRelease(duration * (attackPortion + sustainTime) / totalDuration, 0);\n const buffer = yield context.render();\n return buffer.getChannelData(0);\n });\n }\n dispose() {\n super.dispose();\n this._sig.dispose();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "attack", void 0);\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "decay", void 0);\n__decorate([\n range(0, 1)\n], Envelope_Envelope.prototype, "sustain", void 0);\n__decorate([\n timeRange(0)\n], Envelope_Envelope.prototype, "release", void 0);\n/**\n * Generate some complex envelope curves.\n */\nconst EnvelopeCurves = (() => {\n const curveLen = 128;\n let i;\n let k;\n // cosine curve\n const cosineCurve = [];\n for (i = 0; i < curveLen; i++) {\n cosineCurve[i] = Math.sin((i / (curveLen - 1)) * (Math.PI / 2));\n }\n // ripple curve\n const rippleCurve = [];\n const rippleCurveFreq = 6.4;\n for (i = 0; i < curveLen - 1; i++) {\n k = (i / (curveLen - 1));\n const sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1;\n rippleCurve[i] = sineWave / 10 + k * 0.83;\n }\n rippleCurve[curveLen - 1] = 1;\n // stairs curve\n const stairsCurve = [];\n const steps = 5;\n for (i = 0; i < curveLen; i++) {\n stairsCurve[i] = Math.ceil((i / (curveLen - 1)) * steps) / steps;\n }\n // in-out easing curve\n const sineCurve = [];\n for (i = 0; i < curveLen; i++) {\n k = i / (curveLen - 1);\n sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k));\n }\n // a bounce curve\n const bounceCurve = [];\n for (i = 0; i < curveLen; i++) {\n k = i / (curveLen - 1);\n const freq = Math.pow(k, 3) * 4 + 0.2;\n const val = Math.cos(freq * Math.PI * 2 * k);\n bounceCurve[i] = Math.abs(val * (1 - k));\n }\n /**\n * Invert a value curve to make it work for the release\n */\n function invertCurve(curve) {\n const out = new Array(curve.length);\n for (let j = 0; j < curve.length; j++) {\n out[j] = 1 - curve[j];\n }\n return out;\n }\n /**\n * reverse the curve\n */\n function reverseCurve(curve) {\n return curve.slice(0).reverse();\n }\n /**\n * attack and release curve arrays\n */\n return {\n bounce: {\n In: invertCurve(bounceCurve),\n Out: bounceCurve,\n },\n cosine: {\n In: cosineCurve,\n Out: reverseCurve(cosineCurve),\n },\n exponential: "exponential",\n linear: "linear",\n ripple: {\n In: rippleCurve,\n Out: invertCurve(rippleCurve),\n },\n sine: {\n In: sineCurve,\n Out: invertCurve(sineCurve),\n },\n step: {\n In: stairsCurve,\n Out: invertCurve(stairsCurve),\n },\n };\n})();\n//# sourceMappingURL=Envelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Instrument.js\n\n\n\n\n/**\n * Base-class for all instruments\n */\nclass Instrument_Instrument extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Instrument_Instrument.getDefaults(), arguments));\n /**\n * Keep track of all events scheduled to the transport\n * when the instrument is \'synced\'\n */\n this._scheduledEvents = [];\n /**\n * If the instrument is currently synced\n */\n this._synced = false;\n this._original_triggerAttack = this.triggerAttack;\n this._original_triggerRelease = this.triggerRelease;\n const options = Defaults_optionsFromArguments(Instrument_Instrument.getDefaults(), arguments);\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n Interface_readOnly(this, "volume");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n volume: 0,\n });\n }\n /**\n * Sync the instrument to the Transport. All subsequent calls of\n * [[triggerAttack]] and [[triggerRelease]] will be scheduled along the transport.\n * @example\n * const fmSynth = new Tone.FMSynth().toDestination();\n * fmSynth.volume.value = -6;\n * fmSynth.sync();\n * // schedule 3 notes when the transport first starts\n * fmSynth.triggerAttackRelease("C4", "8n", 0);\n * fmSynth.triggerAttackRelease("E4", "8n", "8n");\n * fmSynth.triggerAttackRelease("G4", "8n", "4n");\n * // start the transport to hear the notes\n * Tone.Transport.start();\n */\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 0);\n }\n return this;\n }\n /**\n * set _sync\n */\n _syncState() {\n let changed = false;\n if (!this._synced) {\n this._synced = true;\n changed = true;\n }\n return changed;\n }\n /**\n * Wrap the given method so that it can be synchronized\n * @param method Which method to wrap and sync\n * @param timePosition What position the time argument appears in\n */\n _syncMethod(method, timePosition) {\n const originalMethod = this["_original_" + method] = this[method];\n this[method] = (...args) => {\n const time = args[timePosition];\n const id = this.context.transport.schedule((t) => {\n args[timePosition] = t;\n originalMethod.apply(this, args);\n }, time);\n this._scheduledEvents.push(id);\n };\n }\n /**\n * Unsync the instrument from the Transport\n */\n unsync() {\n this._scheduledEvents.forEach(id => this.context.transport.clear(id));\n this._scheduledEvents = [];\n if (this._synced) {\n this._synced = false;\n this.triggerAttack = this._original_triggerAttack;\n this.triggerRelease = this._original_triggerRelease;\n }\n return this;\n }\n /**\n * Trigger the attack and then the release after the duration.\n * @param note The note to trigger.\n * @param duration How long the note should be held for before\n * triggering the release. This value must be greater than 0.\n * @param time When the note should be triggered.\n * @param velocity The velocity the note should be triggered at.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // trigger "C4" for the duration of an 8th note\n * synth.triggerAttackRelease("C4", "8n");\n */\n triggerAttackRelease(note, duration, time, velocity) {\n const computedTime = this.toSeconds(time);\n const computedDuration = this.toSeconds(duration);\n this.triggerAttack(note, computedTime, velocity);\n this.triggerRelease(computedTime + computedDuration);\n return this;\n }\n /**\n * clean up\n * @returns {Instrument} this\n */\n dispose() {\n super.dispose();\n this._volume.dispose();\n this.unsync();\n this._scheduledEvents = [];\n return this;\n }\n}\n//# sourceMappingURL=Instrument.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Monophonic.js\n\n\n\n\n\n\n/**\n * Abstract base class for other monophonic instruments to extend.\n */\nclass Monophonic_Monophonic extends Instrument_Instrument {\n constructor() {\n super(Defaults_optionsFromArguments(Monophonic_Monophonic.getDefaults(), arguments));\n const options = Defaults_optionsFromArguments(Monophonic_Monophonic.getDefaults(), arguments);\n this.portamento = options.portamento;\n this.onsilence = options.onsilence;\n }\n static getDefaults() {\n return Object.assign(Instrument_Instrument.getDefaults(), {\n detune: 0,\n onsilence: Interface_noOp,\n portamento: 0,\n });\n }\n /**\n * Trigger the attack of the note optionally with a given velocity.\n * @param note The note to trigger.\n * @param time When the note should start.\n * @param velocity The velocity scaler determines how "loud" the note will be triggered.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // trigger the note a half second from now at half velocity\n * synth.triggerAttack("C4", "+0.5", 0.5);\n */\n triggerAttack(note, time, velocity = 1) {\n this.log("triggerAttack", note, time, velocity);\n const seconds = this.toSeconds(time);\n this._triggerEnvelopeAttack(seconds, velocity);\n this.setNote(note, seconds);\n return this;\n }\n /**\n * Trigger the release portion of the envelope\n * @param time If no time is given, the release happens immediatly\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttack("C4");\n * // trigger the release a second from now\n * synth.triggerRelease("+1");\n */\n triggerRelease(time) {\n this.log("triggerRelease", time);\n const seconds = this.toSeconds(time);\n this._triggerEnvelopeRelease(seconds);\n return this;\n }\n /**\n * Set the note at the given time. If no time is given, the note\n * will set immediately.\n * @param note The note to change to.\n * @param time The time when the note should be set.\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttack("C4");\n * // change to F#6 in one quarter note from now.\n * synth.setNote("F#6", "+4n");\n */\n setNote(note, time) {\n const computedTime = this.toSeconds(time);\n const computedFrequency = note instanceof Frequency_FrequencyClass ? note.toFrequency() : note;\n if (this.portamento > 0 && this.getLevelAtTime(computedTime) > 0.05) {\n const portTime = this.toSeconds(this.portamento);\n this.frequency.exponentialRampTo(computedFrequency, portTime, computedTime);\n }\n else {\n this.frequency.setValueAtTime(computedFrequency, computedTime);\n }\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Monophonic_Monophonic.prototype, "portamento", void 0);\n//# sourceMappingURL=Monophonic.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/AmplitudeEnvelope.js\n\n\n\n/**\n * AmplitudeEnvelope is a Tone.Envelope connected to a gain node.\n * Unlike Tone.Envelope, which outputs the envelope\'s value, AmplitudeEnvelope accepts\n * an audio signal as the input and will apply the envelope to the amplitude\n * of the signal.\n * Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope).\n *\n * @example\n * return Tone.Offline(() => {\n * \tconst ampEnv = new Tone.AmplitudeEnvelope({\n * \t\tattack: 0.1,\n * \t\tdecay: 0.2,\n * \t\tsustain: 1.0,\n * \t\trelease: 0.8\n * \t}).toDestination();\n * \t// create an oscillator and connect it\n * \tconst osc = new Tone.Oscillator().connect(ampEnv).start();\n * \t// trigger the envelopes attack and release "8t" apart\n * \tampEnv.triggerAttackRelease("8t");\n * }, 1.5, 1);\n * @category Component\n */\nclass AmplitudeEnvelope_AmplitudeEnvelope extends Envelope_Envelope {\n constructor() {\n super(Defaults_optionsFromArguments(AmplitudeEnvelope_AmplitudeEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "AmplitudeEnvelope";\n this._gainNode = new Gain_Gain({\n context: this.context,\n gain: 0,\n });\n this.output = this._gainNode;\n this.input = this._gainNode;\n this._sig.connect(this._gainNode.gain);\n this.output = this._gainNode;\n this.input = this._gainNode;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._gainNode.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AmplitudeEnvelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Synth.js\n\n\n\n\n\n\n\n\n/**\n * Synth is composed simply of a [[OmniOscillator]] routed through an [[AmplitudeEnvelope]].\n * ```\n * +----------------+ +-------------------+\n * | OmniOscillator +>--\x3e AmplitudeEnvelope +>--\x3e Output\n * +----------------+ +-------------------+\n * ```\n * @example\n * const synth = new Tone.Synth().toDestination();\n * synth.triggerAttackRelease("C4", "8n");\n * @category Instrument\n */\nclass Synth_Synth extends Monophonic_Monophonic {\n constructor() {\n super(Defaults_optionsFromArguments(Synth_Synth.getDefaults(), arguments));\n this.name = "Synth";\n const options = Defaults_optionsFromArguments(Synth_Synth.getDefaults(), arguments);\n this.oscillator = new OmniOscillator_OmniOscillator(Object.assign({\n context: this.context,\n detune: options.detune,\n onstop: () => this.onsilence(this),\n }, options.oscillator));\n this.frequency = this.oscillator.frequency;\n this.detune = this.oscillator.detune;\n this.envelope = new AmplitudeEnvelope_AmplitudeEnvelope(Object.assign({\n context: this.context,\n }, options.envelope));\n // connect the oscillators to the output\n this.oscillator.chain(this.envelope, this.output);\n Interface_readOnly(this, ["oscillator", "frequency", "detune", "envelope"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic_Monophonic.getDefaults(), {\n envelope: Object.assign(Defaults_omitFromObject(Envelope_Envelope.getDefaults(), Object.keys(ToneAudioNode_ToneAudioNode.getDefaults())), {\n attack: 0.005,\n decay: 0.1,\n release: 1,\n sustain: 0.3,\n }),\n oscillator: Object.assign(Defaults_omitFromObject(OmniOscillator_OmniOscillator.getDefaults(), [...Object.keys(Source_Source.getDefaults()), "frequency", "detune"]), {\n type: "triangle",\n }),\n });\n }\n /**\n * start the attack portion of the envelope\n * @param time the time the attack should start\n * @param velocity the velocity of the note (0-1)\n */\n _triggerEnvelopeAttack(time, velocity) {\n // the envelopes\n this.envelope.triggerAttack(time, velocity);\n this.oscillator.start(time);\n // if there is no release portion, stop the oscillator\n if (this.envelope.sustain === 0) {\n const computedAttack = this.toSeconds(this.envelope.attack);\n const computedDecay = this.toSeconds(this.envelope.decay);\n this.oscillator.stop(time + computedAttack + computedDecay);\n }\n }\n /**\n * start the release portion of the envelope\n * @param time the time the release should start\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this.oscillator.stop(time + this.toSeconds(this.envelope.release));\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n /**\n * clean up\n */\n dispose() {\n super.dispose();\n this.oscillator.dispose();\n this.envelope.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Synth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/ModulationSynth.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Base class for both AM and FM synths\n */\nclass ModulationSynth_ModulationSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(ModulationSynth_ModulationSynth.getDefaults(), arguments));\n this.name = "ModulationSynth";\n const options = optionsFromArguments(ModulationSynth_ModulationSynth.getDefaults(), arguments);\n this._carrier = new Synth({\n context: this.context,\n oscillator: options.oscillator,\n envelope: options.envelope,\n onsilence: () => this.onsilence(this),\n volume: -10,\n });\n this._modulator = new Synth({\n context: this.context,\n oscillator: options.modulation,\n envelope: options.modulationEnvelope,\n volume: -10,\n });\n this.oscillator = this._carrier.oscillator;\n this.envelope = this._carrier.envelope;\n this.modulation = this._modulator.oscillator;\n this.modulationEnvelope = this._modulator.envelope;\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n });\n this.detune = new Signal({\n context: this.context,\n value: options.detune,\n units: "cents"\n });\n this.harmonicity = new Multiply({\n context: this.context,\n value: options.harmonicity,\n minValue: 0,\n });\n this._modulationNode = new Gain({\n context: this.context,\n gain: 0,\n });\n readOnly(this, ["frequency", "harmonicity", "oscillator", "envelope", "modulation", "modulationEnvelope", "detune"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic.getDefaults(), {\n harmonicity: 3,\n oscillator: Object.assign(omitFromObject(OmniOscillator.getDefaults(), [\n ...Object.keys(Source.getDefaults()),\n "frequency",\n "detune"\n ]), {\n type: "sine"\n }),\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.01,\n decay: 0.01,\n sustain: 1,\n release: 0.5\n }),\n modulation: Object.assign(omitFromObject(OmniOscillator.getDefaults(), [\n ...Object.keys(Source.getDefaults()),\n "frequency",\n "detune"\n ]), {\n type: "square"\n }),\n modulationEnvelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.5,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n })\n });\n }\n /**\n * Trigger the attack portion of the note\n */\n _triggerEnvelopeAttack(time, velocity) {\n // @ts-ignore\n this._carrier._triggerEnvelopeAttack(time, velocity);\n // @ts-ignore\n this._modulator._triggerEnvelopeAttack(time, velocity);\n }\n /**\n * Trigger the release portion of the note\n */\n _triggerEnvelopeRelease(time) {\n // @ts-ignore\n this._carrier._triggerEnvelopeRelease(time);\n // @ts-ignore\n this._modulator._triggerEnvelopeRelease(time);\n return this;\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n dispose() {\n super.dispose();\n this._carrier.dispose();\n this._modulator.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this.harmonicity.dispose();\n this._modulationNode.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ModulationSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/AMSynth.js\n\n\n\n/**\n * AMSynth uses the output of one Tone.Synth to modulate the\n * amplitude of another Tone.Synth. The harmonicity (the ratio between\n * the two signals) affects the timbre of the output signal greatly.\n * Read more about Amplitude Modulation Synthesis on\n * [SoundOnSound](https://web.archive.org/web/20160404103653/http://www.soundonsound.com:80/sos/mar00/articles/synthsecrets.htm).\n *\n * @example\n * const synth = new Tone.AMSynth().toDestination();\n * synth.triggerAttackRelease("C4", "4n");\n *\n * @category Instrument\n */\nclass AMSynth extends (/* unused pure expression or super */ null && (ModulationSynth)) {\n constructor() {\n super(optionsFromArguments(AMSynth.getDefaults(), arguments));\n this.name = "AMSynth";\n this._modulationScale = new AudioToGain({\n context: this.context,\n });\n // control the two voices frequency\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.detune.fan(this._carrier.detune, this._modulator.detune);\n this._modulator.chain(this._modulationScale, this._modulationNode.gain);\n this._carrier.chain(this._modulationNode, this.output);\n }\n dispose() {\n super.dispose();\n this._modulationScale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AMSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/BiquadFilter.js\n\n\n\n\n/**\n * Thin wrapper around the native Web Audio [BiquadFilterNode](https://webaudio.github.io/web-audio-api/#biquadfilternode).\n * BiquadFilter is similar to [[Filter]] but doesn\'t have the option to set the "rolloff" value.\n * @category Component\n */\nclass BiquadFilter_BiquadFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(BiquadFilter_BiquadFilter.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "BiquadFilter";\n const options = optionsFromArguments(BiquadFilter_BiquadFilter.getDefaults(), arguments, ["frequency", "type"]);\n this._filter = this.context.createBiquadFilter();\n this.input = this.output = this._filter;\n this.Q = new Param({\n context: this.context,\n units: "number",\n value: options.Q,\n param: this._filter.Q,\n });\n this.frequency = new Param({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n param: this._filter.frequency,\n });\n this.detune = new Param({\n context: this.context,\n units: "cents",\n value: options.detune,\n param: this._filter.detune,\n });\n this.gain = new Param({\n context: this.context,\n units: "decibels",\n convert: false,\n value: options.gain,\n param: this._filter.gain,\n });\n this.type = options.type;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n type: "lowpass",\n frequency: 350,\n detune: 0,\n gain: 0,\n });\n }\n /**\n * The type of this BiquadFilterNode. For a complete list of types and their attributes, see the\n * [Web Audio API](https://webaudio.github.io/web-audio-api/#dom-biquadfiltertype-lowpass)\n */\n get type() {\n return this._filter.type;\n }\n set type(type) {\n const types = ["lowpass", "highpass", "bandpass",\n "lowshelf", "highshelf", "notch", "allpass", "peaking"];\n assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`);\n this._filter.type = type;\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n // start with all 1s\n const freqValues = new Float32Array(len);\n for (let i = 0; i < len; i++) {\n const norm = Math.pow(i / len, 2);\n const freq = norm * (20000 - 20) + 20;\n freqValues[i] = freq;\n }\n const magValues = new Float32Array(len);\n const phaseValues = new Float32Array(len);\n // clone the filter to remove any connections which may be changing the value\n const filterClone = this.context.createBiquadFilter();\n filterClone.type = this.type;\n filterClone.Q.value = this.Q.value;\n filterClone.frequency.value = this.frequency.value;\n filterClone.gain.value = this.gain.value;\n filterClone.getFrequencyResponse(freqValues, magValues, phaseValues);\n return magValues;\n }\n dispose() {\n super.dispose();\n this._filter.disconnect();\n this.Q.dispose();\n this.frequency.dispose();\n this.gain.dispose();\n this.detune.dispose();\n return this;\n }\n}\n//# sourceMappingURL=BiquadFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/Filter.js\n\n\n\n\n\n\n\n\n/**\n * Tone.Filter is a filter which allows for all of the same native methods\n * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface).\n * Tone.Filter has the added ability to set the filter rolloff at -12\n * (default), -24 and -48.\n * @example\n * const filter = new Tone.Filter(1500, "highpass").toDestination();\n * filter.frequency.rampTo(20000, 10);\n * const noise = new Tone.Noise().connect(filter).start();\n * @category Component\n */\nclass Filter_Filter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Filter_Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]));\n this.name = "Filter";\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this._filters = [];\n const options = optionsFromArguments(Filter_Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]);\n this._filters = [];\n this.Q = new Signal({\n context: this.context,\n units: "positive",\n value: options.Q,\n });\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n });\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this.gain = new Signal({\n context: this.context,\n units: "decibels",\n convert: false,\n value: options.gain,\n });\n this._type = options.type;\n this.rolloff = options.rolloff;\n readOnly(this, ["detune", "frequency", "gain", "Q"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n detune: 0,\n frequency: 350,\n gain: 0,\n rolloff: -12,\n type: "lowpass",\n });\n }\n /**\n * The type of the filter. Types: "lowpass", "highpass",\n * "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking".\n */\n get type() {\n return this._type;\n }\n set type(type) {\n const types = ["lowpass", "highpass", "bandpass",\n "lowshelf", "highshelf", "notch", "allpass", "peaking"];\n assert(types.indexOf(type) !== -1, `Invalid filter type: ${type}`);\n this._type = type;\n this._filters.forEach(filter => filter.type = type);\n }\n /**\n * The rolloff of the filter which is the drop in db\n * per octave. Implemented internally by cascading filters.\n * Only accepts the values -12, -24, -48 and -96.\n */\n get rolloff() {\n return this._rolloff;\n }\n set rolloff(rolloff) {\n const rolloffNum = isNumber(rolloff) ? rolloff : parseInt(rolloff, 10);\n const possibilities = [-12, -24, -48, -96];\n let cascadingCount = possibilities.indexOf(rolloffNum);\n // check the rolloff is valid\n assert(cascadingCount !== -1, `rolloff can only be ${possibilities.join(", ")}`);\n cascadingCount += 1;\n this._rolloff = rolloffNum;\n this.input.disconnect();\n this._filters.forEach(filter => filter.disconnect());\n this._filters = new Array(cascadingCount);\n for (let count = 0; count < cascadingCount; count++) {\n const filter = new BiquadFilter({\n context: this.context,\n });\n filter.type = this._type;\n this.frequency.connect(filter.frequency);\n this.detune.connect(filter.detune);\n this.Q.connect(filter.Q);\n this.gain.connect(filter.gain);\n this._filters[count] = filter;\n }\n this._internalChannels = this._filters;\n connectSeries(this.input, ...this._internalChannels, this.output);\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n const filterClone = new BiquadFilter({\n frequency: this.frequency.value,\n gain: this.gain.value,\n Q: this.Q.value,\n type: this._type,\n detune: this.detune.value,\n });\n // start with all 1s\n const totalResponse = new Float32Array(len).map(() => 1);\n this._filters.forEach(() => {\n const response = filterClone.getFrequencyResponse(len);\n response.forEach((val, i) => totalResponse[i] *= val);\n });\n filterClone.dispose();\n return totalResponse;\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._filters.forEach(filter => {\n filter.dispose();\n });\n writable(this, ["detune", "frequency", "gain", "Q"]);\n this.frequency.dispose();\n this.Q.dispose();\n this.detune.dispose();\n this.gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Filter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/envelope/FrequencyEnvelope.js\n\n\n\n\n\n/**\n * FrequencyEnvelope is an [[Envelope]] which ramps between [[baseFrequency]]\n * and [[octaves]]. It can also have an optional [[exponent]] to adjust the curve\n * which it ramps.\n * @example\n * const oscillator = new Tone.Oscillator().toDestination().start();\n * const freqEnv = new Tone.FrequencyEnvelope({\n * \tattack: 0.2,\n * \tbaseFrequency: "C2",\n * \toctaves: 4\n * });\n * freqEnv.connect(oscillator.frequency);\n * freqEnv.triggerAttack();\n * @category Component\n */\nclass FrequencyEnvelope_FrequencyEnvelope extends (/* unused pure expression or super */ null && (Envelope)) {\n constructor() {\n super(optionsFromArguments(FrequencyEnvelope_FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]));\n this.name = "FrequencyEnvelope";\n const options = optionsFromArguments(FrequencyEnvelope_FrequencyEnvelope.getDefaults(), arguments, ["attack", "decay", "sustain", "release"]);\n this._octaves = options.octaves;\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._exponent = this.input = new Pow({\n context: this.context,\n value: options.exponent\n });\n this._scale = this.output = new Scale({\n context: this.context,\n min: this._baseFrequency,\n max: this._baseFrequency * Math.pow(2, this._octaves),\n });\n this._sig.chain(this._exponent, this._scale);\n }\n static getDefaults() {\n return Object.assign(Envelope.getDefaults(), {\n baseFrequency: 200,\n exponent: 1,\n octaves: 4,\n });\n }\n /**\n * The envelope\'s minimum output value. This is the value which it\n * starts at.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(min) {\n const freq = this.toFrequency(min);\n assertRange(freq, 0);\n this._baseFrequency = freq;\n this._scale.min = this._baseFrequency;\n // update the max value when the min changes\n this.octaves = this._octaves;\n }\n /**\n * The number of octaves above the baseFrequency that the\n * envelope will scale to.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n this._scale.max = this._baseFrequency * Math.pow(2, octaves);\n }\n /**\n * The envelope\'s exponent value.\n */\n get exponent() {\n return this._exponent.value;\n }\n set exponent(exponent) {\n this._exponent.value = exponent;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._exponent.dispose();\n this._scale.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FrequencyEnvelope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MonoSynth.js\n\n\n\n\n\n\n\n\n\n\n/**\n * MonoSynth is composed of one `oscillator`, one `filter`, and two `envelopes`.\n * The amplitude of the Oscillator and the cutoff frequency of the\n * Filter are controlled by Envelopes.\n * <img src="https://docs.google.com/drawings/d/1gaY1DF9_Hzkodqf8JI1Cg2VZfwSElpFQfI94IQwad38/pub?w=924&h=240">\n * @example\n * const synth = new Tone.MonoSynth({\n * \toscillator: {\n * \t\ttype: "square"\n * \t},\n * \tenvelope: {\n * \t\tattack: 0.1\n * \t}\n * }).toDestination();\n * synth.triggerAttackRelease("C4", "8n");\n * @category Instrument\n */\nclass MonoSynth_MonoSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(MonoSynth_MonoSynth.getDefaults(), arguments));\n this.name = "MonoSynth";\n const options = optionsFromArguments(MonoSynth_MonoSynth.getDefaults(), arguments);\n this.oscillator = new OmniOscillator(Object.assign(options.oscillator, {\n context: this.context,\n detune: options.detune,\n onstop: () => this.onsilence(this),\n }));\n this.frequency = this.oscillator.frequency;\n this.detune = this.oscillator.detune;\n this.filter = new Filter(Object.assign(options.filter, { context: this.context }));\n this.filterEnvelope = new FrequencyEnvelope(Object.assign(options.filterEnvelope, { context: this.context }));\n this.envelope = new AmplitudeEnvelope(Object.assign(options.envelope, { context: this.context }));\n // connect the oscillators to the output\n this.oscillator.chain(this.filter, this.envelope, this.output);\n // connect the filter envelope\n this.filterEnvelope.connect(this.filter.frequency);\n readOnly(this, ["oscillator", "frequency", "detune", "filter", "filterEnvelope", "envelope"]);\n }\n static getDefaults() {\n return Object.assign(Monophonic.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.005,\n decay: 0.1,\n release: 1,\n sustain: 0.9,\n }),\n filter: Object.assign(omitFromObject(Filter.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n Q: 1,\n rolloff: -12,\n type: "lowpass",\n }),\n filterEnvelope: Object.assign(omitFromObject(FrequencyEnvelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.6,\n baseFrequency: 200,\n decay: 0.2,\n exponent: 2,\n octaves: 3,\n release: 2,\n sustain: 0.5,\n }),\n oscillator: Object.assign(omitFromObject(OmniOscillator.getDefaults(), Object.keys(Source.getDefaults())), {\n type: "sawtooth",\n }),\n });\n }\n /**\n * start the attack portion of the envelope\n * @param time the time the attack should start\n * @param velocity the velocity of the note (0-1)\n */\n _triggerEnvelopeAttack(time, velocity = 1) {\n this.envelope.triggerAttack(time, velocity);\n this.filterEnvelope.triggerAttack(time);\n this.oscillator.start(time);\n if (this.envelope.sustain === 0) {\n const computedAttack = this.toSeconds(this.envelope.attack);\n const computedDecay = this.toSeconds(this.envelope.decay);\n this.oscillator.stop(time + computedAttack + computedDecay);\n }\n }\n /**\n * start the release portion of the envelope\n * @param time the time the release should start\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this.filterEnvelope.triggerRelease(time);\n this.oscillator.stop(time + this.toSeconds(this.envelope.release));\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n dispose() {\n super.dispose();\n this.oscillator.dispose();\n this.envelope.dispose();\n this.filterEnvelope.dispose();\n this.filter.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MonoSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/DuoSynth.js\n\n\n\n\n\n\n\n\n/**\n * DuoSynth is a monophonic synth composed of two [[MonoSynths]] run in parallel with control over the\n * frequency ratio between the two voices and vibrato effect.\n * @example\n * const duoSynth = new Tone.DuoSynth().toDestination();\n * duoSynth.triggerAttackRelease("C4", "2n");\n * @category Instrument\n */\nclass DuoSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(DuoSynth.getDefaults(), arguments));\n this.name = "DuoSynth";\n const options = optionsFromArguments(DuoSynth.getDefaults(), arguments);\n this.voice0 = new MonoSynth(Object.assign(options.voice0, {\n context: this.context,\n onsilence: () => this.onsilence(this)\n }));\n this.voice1 = new MonoSynth(Object.assign(options.voice1, {\n context: this.context,\n }));\n this.harmonicity = new Multiply({\n context: this.context,\n units: "positive",\n value: options.harmonicity,\n });\n this._vibrato = new LFO({\n frequency: options.vibratoRate,\n context: this.context,\n min: -50,\n max: 50\n });\n // start the vibrato immediately\n this._vibrato.start();\n this.vibratoRate = this._vibrato.frequency;\n this._vibratoGain = new Gain({\n context: this.context,\n units: "normalRange",\n gain: options.vibratoAmount\n });\n this.vibratoAmount = this._vibratoGain.gain;\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: 440\n });\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune\n });\n // control the two voices frequency\n this.frequency.connect(this.voice0.frequency);\n this.frequency.chain(this.harmonicity, this.voice1.frequency);\n this._vibrato.connect(this._vibratoGain);\n this._vibratoGain.fan(this.voice0.detune, this.voice1.detune);\n this.detune.fan(this.voice0.detune, this.voice1.detune);\n this.voice0.connect(this.output);\n this.voice1.connect(this.output);\n readOnly(this, ["voice0", "voice1", "frequency", "vibratoAmount", "vibratoRate"]);\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.voice0.envelope.getValueAtTime(time) + this.voice1.envelope.getValueAtTime(time);\n }\n static getDefaults() {\n return deepMerge(Monophonic.getDefaults(), {\n vibratoAmount: 0.5,\n vibratoRate: 5,\n harmonicity: 1.5,\n voice0: deepMerge(omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), {\n filterEnvelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n },\n envelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n }\n }),\n voice1: deepMerge(omitFromObject(MonoSynth.getDefaults(), Object.keys(Monophonic.getDefaults())), {\n filterEnvelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n },\n envelope: {\n attack: 0.01,\n decay: 0.0,\n sustain: 1,\n release: 0.5\n }\n }),\n });\n }\n /**\n * Trigger the attack portion of the note\n */\n _triggerEnvelopeAttack(time, velocity) {\n // @ts-ignore\n this.voice0._triggerEnvelopeAttack(time, velocity);\n // @ts-ignore\n this.voice1._triggerEnvelopeAttack(time, velocity);\n }\n /**\n * Trigger the release portion of the note\n */\n _triggerEnvelopeRelease(time) {\n // @ts-ignore\n this.voice0._triggerEnvelopeRelease(time);\n // @ts-ignore\n this.voice1._triggerEnvelopeRelease(time);\n return this;\n }\n dispose() {\n super.dispose();\n this.voice0.dispose();\n this.voice1.dispose();\n this.frequency.dispose();\n this.detune.dispose();\n this._vibrato.dispose();\n this.vibratoRate.dispose();\n this._vibratoGain.dispose();\n this.harmonicity.dispose();\n return this;\n }\n}\n//# sourceMappingURL=DuoSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/FMSynth.js\n\n\n\n/**\n * FMSynth is composed of two Tone.Synths where one Tone.Synth modulates\n * the frequency of a second Tone.Synth. A lot of spectral content\n * can be explored using the modulationIndex parameter. Read more about\n * frequency modulation synthesis on Sound On Sound: [Part 1](https://web.archive.org/web/20160403123704/http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm), [Part 2](https://web.archive.org/web/20160403115835/http://www.soundonsound.com/sos/may00/articles/synth.htm).\n *\n * @example\n * const fmSynth = new Tone.FMSynth().toDestination();\n * fmSynth.triggerAttackRelease("C5", "4n");\n *\n * @category Instrument\n */\nclass FMSynth extends (/* unused pure expression or super */ null && (ModulationSynth)) {\n constructor() {\n super(optionsFromArguments(FMSynth.getDefaults(), arguments));\n this.name = "FMSynth";\n const options = optionsFromArguments(FMSynth.getDefaults(), arguments);\n this.modulationIndex = new Multiply({\n context: this.context,\n value: options.modulationIndex,\n });\n // control the two voices frequency\n this.frequency.connect(this._carrier.frequency);\n this.frequency.chain(this.harmonicity, this._modulator.frequency);\n this.frequency.chain(this.modulationIndex, this._modulationNode);\n this.detune.fan(this._carrier.detune, this._modulator.detune);\n this._modulator.connect(this._modulationNode.gain);\n this._modulationNode.connect(this._carrier.frequency);\n this._carrier.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(ModulationSynth.getDefaults(), {\n modulationIndex: 10,\n });\n }\n dispose() {\n super.dispose();\n this.modulationIndex.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FMSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MetalSynth.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Inharmonic ratio of frequencies based on the Roland TR-808\n * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model\n */\nconst inharmRatios = (/* unused pure expression or super */ null && ([1.0, 1.483, 1.932, 2.546, 2.630, 3.897]));\n/**\n * A highly inharmonic and spectrally complex source with a highpass filter\n * and amplitude envelope which is good for making metallophone sounds.\n * Based on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic).\n * Inspiration from [Sound on Sound](https://shorturl.at/rSZ12).\n * @category Instrument\n */\nclass MetalSynth extends (/* unused pure expression or super */ null && (Monophonic)) {\n constructor() {\n super(optionsFromArguments(MetalSynth.getDefaults(), arguments));\n this.name = "MetalSynth";\n /**\n * The array of FMOscillators\n */\n this._oscillators = [];\n /**\n * The frequency multipliers\n */\n this._freqMultipliers = [];\n const options = optionsFromArguments(MetalSynth.getDefaults(), arguments);\n this.detune = new Signal({\n context: this.context,\n units: "cents",\n value: options.detune,\n });\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n });\n this._amplitude = new Gain({\n context: this.context,\n gain: 0,\n }).connect(this.output);\n this._highpass = new Filter({\n // Q: -3.0102999566398125,\n Q: 0,\n context: this.context,\n type: "highpass",\n }).connect(this._amplitude);\n for (let i = 0; i < inharmRatios.length; i++) {\n const osc = new FMOscillator({\n context: this.context,\n harmonicity: options.harmonicity,\n modulationIndex: options.modulationIndex,\n modulationType: "square",\n onstop: i === 0 ? () => this.onsilence(this) : noOp,\n type: "square",\n });\n osc.connect(this._highpass);\n this._oscillators[i] = osc;\n const mult = new Multiply({\n context: this.context,\n value: inharmRatios[i],\n });\n this._freqMultipliers[i] = mult;\n this.frequency.chain(mult, osc.frequency);\n this.detune.connect(osc.detune);\n }\n this._filterFreqScaler = new Scale({\n context: this.context,\n max: 7000,\n min: this.toFrequency(options.resonance),\n });\n this.envelope = new Envelope({\n attack: options.envelope.attack,\n attackCurve: "linear",\n context: this.context,\n decay: options.envelope.decay,\n release: options.envelope.release,\n sustain: 0,\n });\n this.envelope.chain(this._filterFreqScaler, this._highpass.frequency);\n this.envelope.connect(this._amplitude.gain);\n // set the octaves\n this._octaves = options.octaves;\n this.octaves = options.octaves;\n }\n static getDefaults() {\n return deepMerge(Monophonic.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n attack: 0.001,\n decay: 1.4,\n release: 0.2,\n }),\n harmonicity: 5.1,\n modulationIndex: 32,\n octaves: 1.5,\n resonance: 4000,\n });\n }\n /**\n * Trigger the attack.\n * @param time When the attack should be triggered.\n * @param velocity The velocity that the envelope should be triggered at.\n */\n _triggerEnvelopeAttack(time, velocity = 1) {\n this.envelope.triggerAttack(time, velocity);\n this._oscillators.forEach(osc => osc.start(time));\n if (this.envelope.sustain === 0) {\n this._oscillators.forEach(osc => {\n osc.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));\n });\n }\n return this;\n }\n /**\n * Trigger the release of the envelope.\n * @param time When the release should be triggered.\n */\n _triggerEnvelopeRelease(time) {\n this.envelope.triggerRelease(time);\n this._oscillators.forEach(osc => osc.stop(time + this.toSeconds(this.envelope.release)));\n return this;\n }\n getLevelAtTime(time) {\n time = this.toSeconds(time);\n return this.envelope.getValueAtTime(time);\n }\n /**\n * The modulationIndex of the oscillators which make up the source.\n * see [[FMOscillator.modulationIndex]]\n * @min 1\n * @max 100\n */\n get modulationIndex() {\n return this._oscillators[0].modulationIndex.value;\n }\n set modulationIndex(val) {\n this._oscillators.forEach(osc => (osc.modulationIndex.value = val));\n }\n /**\n * The harmonicity of the oscillators which make up the source.\n * see Tone.FMOscillator.harmonicity\n * @min 0.1\n * @max 10\n */\n get harmonicity() {\n return this._oscillators[0].harmonicity.value;\n }\n set harmonicity(val) {\n this._oscillators.forEach(osc => (osc.harmonicity.value = val));\n }\n /**\n * The lower level of the highpass filter which is attached to the envelope.\n * This value should be between [0, 7000]\n * @min 0\n * @max 7000\n */\n get resonance() {\n return this._filterFreqScaler.min;\n }\n set resonance(val) {\n this._filterFreqScaler.min = this.toFrequency(val);\n this.octaves = this._octaves;\n }\n /**\n * The number of octaves above the "resonance" frequency\n * that the filter ramps during the attack/decay envelope\n * @min 0\n * @max 8\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(val) {\n this._octaves = val;\n this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, val);\n }\n dispose() {\n super.dispose();\n this._oscillators.forEach(osc => osc.dispose());\n this._freqMultipliers.forEach(freqMult => freqMult.dispose());\n this.frequency.dispose();\n this.detune.dispose();\n this._filterFreqScaler.dispose();\n this._amplitude.dispose();\n this.envelope.dispose();\n this._highpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MetalSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/MembraneSynth.js\n\n\n\n\n\n\n\n/**\n * MembraneSynth makes kick and tom sounds using a single oscillator\n * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator\n * is routed through a Tone.AmplitudeEnvelope to the output. The drum\n * quality of the sound comes from the frequency envelope applied\n * during MembraneSynth.triggerAttack(note). The frequency envelope\n * starts at <code>note * .octaves</code> and ramps to <code>note</code>\n * over the duration of <code>.pitchDecay</code>.\n * @example\n * const synth = new Tone.MembraneSynth().toDestination();\n * synth.triggerAttackRelease("C2", "8n");\n * @category Instrument\n */\nclass MembraneSynth extends Synth_Synth {\n constructor() {\n super(Defaults_optionsFromArguments(MembraneSynth.getDefaults(), arguments));\n this.name = "MembraneSynth";\n /**\n * Portamento is ignored in this synth. use pitch decay instead.\n */\n this.portamento = 0;\n const options = Defaults_optionsFromArguments(MembraneSynth.getDefaults(), arguments);\n this.pitchDecay = options.pitchDecay;\n this.octaves = options.octaves;\n Interface_readOnly(this, ["oscillator", "envelope"]);\n }\n static getDefaults() {\n return Defaults_deepMerge(Monophonic_Monophonic.getDefaults(), Synth_Synth.getDefaults(), {\n envelope: {\n attack: 0.001,\n attackCurve: "exponential",\n decay: 0.4,\n release: 1.4,\n sustain: 0.01,\n },\n octaves: 10,\n oscillator: {\n type: "sine",\n },\n pitchDecay: 0.05,\n });\n }\n setNote(note, time) {\n const seconds = this.toSeconds(time);\n const hertz = this.toFrequency(note instanceof Frequency_FrequencyClass ? note.toFrequency() : note);\n const maxNote = hertz * this.octaves;\n this.oscillator.frequency.setValueAtTime(maxNote, seconds);\n this.oscillator.frequency.exponentialRampToValueAtTime(hertz, seconds + this.toSeconds(this.pitchDecay));\n return this;\n }\n dispose() {\n super.dispose();\n return this;\n }\n}\n__decorate([\n range(0)\n], MembraneSynth.prototype, "octaves", void 0);\n__decorate([\n timeRange(0)\n], MembraneSynth.prototype, "pitchDecay", void 0);\n//# sourceMappingURL=MembraneSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/NoiseSynth.js\n\n\n\n\n\n\n\n/**\n * Tone.NoiseSynth is composed of [[Noise]] through an [[AmplitudeEnvelope]].\n * ```\n * +-------+ +-------------------+\n * | Noise +>--\x3e AmplitudeEnvelope +>--\x3e Output\n * +-------+ +-------------------+\n * ```\n * @example\n * const noiseSynth = new Tone.NoiseSynth().toDestination();\n * noiseSynth.triggerAttackRelease("8n", 0.05);\n * @category Instrument\n */\nclass NoiseSynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(NoiseSynth.getDefaults(), arguments));\n this.name = "NoiseSynth";\n const options = optionsFromArguments(NoiseSynth.getDefaults(), arguments);\n this.noise = new Noise(Object.assign({\n context: this.context,\n }, options.noise));\n this.envelope = new AmplitudeEnvelope(Object.assign({\n context: this.context,\n }, options.envelope));\n // connect the noise to the output\n this.noise.chain(this.envelope, this.output);\n }\n static getDefaults() {\n return Object.assign(Instrument.getDefaults(), {\n envelope: Object.assign(omitFromObject(Envelope.getDefaults(), Object.keys(ToneAudioNode.getDefaults())), {\n decay: 0.1,\n sustain: 0.0,\n }),\n noise: Object.assign(omitFromObject(Noise.getDefaults(), Object.keys(Source.getDefaults())), {\n type: "white",\n }),\n });\n }\n /**\n * Start the attack portion of the envelopes. Unlike other\n * instruments, Tone.NoiseSynth doesn\'t have a note.\n * @example\n * const noiseSynth = new Tone.NoiseSynth().toDestination();\n * noiseSynth.triggerAttack();\n */\n triggerAttack(time, velocity = 1) {\n time = this.toSeconds(time);\n // the envelopes\n this.envelope.triggerAttack(time, velocity);\n // start the noise\n this.noise.start(time);\n if (this.envelope.sustain === 0) {\n this.noise.stop(time + this.toSeconds(this.envelope.attack) + this.toSeconds(this.envelope.decay));\n }\n return this;\n }\n /**\n * Start the release portion of the envelopes.\n */\n triggerRelease(time) {\n time = this.toSeconds(time);\n this.envelope.triggerRelease(time);\n this.noise.stop(time + this.toSeconds(this.envelope.release));\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 0);\n this._syncMethod("triggerRelease", 0);\n }\n return this;\n }\n triggerAttackRelease(duration, time, velocity = 1) {\n time = this.toSeconds(time);\n duration = this.toSeconds(duration);\n this.triggerAttack(time, velocity);\n this.triggerRelease(time + duration);\n return this;\n }\n dispose() {\n super.dispose();\n this.noise.dispose();\n this.envelope.dispose();\n return this;\n }\n}\n//# sourceMappingURL=NoiseSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/WorkletGlobalScope.js\n/**\n * All of the classes or functions which are loaded into the AudioWorkletGlobalScope\n */\nconst workletContext = new Set();\n/**\n * Add a class to the AudioWorkletGlobalScope\n */\nfunction addToWorklet(classOrFunction) {\n workletContext.add(classOrFunction);\n}\n/**\n * Register a processor in the AudioWorkletGlobalScope with the given name\n */\nfunction registerProcessor(name, classDesc) {\n const processor = /* javascript */ `registerProcessor("${name}", ${classDesc})`;\n workletContext.add(processor);\n}\n/**\n * Get all of the modules which have been registered to the AudioWorkletGlobalScope\n */\nfunction WorkletGlobalScope_getWorkletGlobalScope() {\n return Array.from(workletContext).join("\\n");\n}\n//# sourceMappingURL=WorkletGlobalScope.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/ToneAudioWorklet.js\n\n\n\nclass ToneAudioWorklet_ToneAudioWorklet extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "ToneAudioWorklet";\n /**\n * The constructor options for the node\n */\n this.workletOptions = {};\n /**\n * Callback which is invoked when there is an error in the processing\n */\n this.onprocessorerror = noOp;\n const blobUrl = URL.createObjectURL(new Blob([getWorkletGlobalScope()], { type: "text/javascript" }));\n const name = this._audioWorkletName();\n this._dummyGain = this.context.createGain();\n this._dummyParam = this._dummyGain.gain;\n // Register the processor\n this.context.addAudioWorkletModule(blobUrl, name).then(() => {\n // create the worklet when it\'s read\n if (!this.disposed) {\n this._worklet = this.context.createAudioWorkletNode(name, this.workletOptions);\n this._worklet.onprocessorerror = this.onprocessorerror.bind(this);\n this.onReady(this._worklet);\n }\n });\n }\n dispose() {\n super.dispose();\n this._dummyGain.disconnect();\n if (this._worklet) {\n this._worklet.port.postMessage("dispose");\n this._worklet.disconnect();\n }\n return this;\n }\n}\n//# sourceMappingURL=ToneAudioWorklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/ToneAudioWorkletProcessor.worklet.js\n\nconst toneAudioWorkletProcessor = /* javascript */ `\n\t/**\n\t * The base AudioWorkletProcessor for use in Tone.js. Works with the [[ToneAudioWorklet]]. \n\t */\n\tclass ToneAudioWorkletProcessor extends AudioWorkletProcessor {\n\n\t\tconstructor(options) {\n\t\t\t\n\t\t\tsuper(options);\n\t\t\t/**\n\t\t\t * If the processor was disposed or not. Keep alive until it\'s disposed.\n\t\t\t */\n\t\t\tthis.disposed = false;\n\t\t \t/** \n\t\t\t * The number of samples in the processing block\n\t\t\t */\n\t\t\tthis.blockSize = 128;\n\t\t\t/**\n\t\t\t * the sample rate\n\t\t\t */\n\t\t\tthis.sampleRate = sampleRate;\n\n\t\t\tthis.port.onmessage = (event) => {\n\t\t\t\t// when it receives a dispose \n\t\t\t\tif (event.data === "dispose") {\n\t\t\t\t\tthis.disposed = true;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}\n`;\naddToWorklet(toneAudioWorkletProcessor);\n//# sourceMappingURL=ToneAudioWorkletProcessor.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/SingleIOProcessor.worklet.js\n\n\nconst singleIOProcess = /* javascript */ `\n\t/**\n\t * Abstract class for a single input/output processor. \n\t * has a \'generate\' function which processes one sample at a time\n\t */\n\tclass SingleIOProcessor extends ToneAudioWorkletProcessor {\n\n\t\tconstructor(options) {\n\t\t\tsuper(Object.assign(options, {\n\t\t\t\tnumberOfInputs: 1,\n\t\t\t\tnumberOfOutputs: 1\n\t\t\t}));\n\t\t\t/**\n\t\t\t * Holds the name of the parameter and a single value of that\n\t\t\t * parameter at the current sample\n\t\t\t * @type { [name: string]: number }\n\t\t\t */\n\t\t\tthis.params = {}\n\t\t}\n\n\t\t/**\n\t\t * Generate an output sample from the input sample and parameters\n\t\t * @abstract\n\t\t * @param input number\n\t\t * @param channel number\n\t\t * @param parameters { [name: string]: number }\n\t\t * @returns number\n\t\t */\n\t\tgenerate(){}\n\n\t\t/**\n\t\t * Update the private params object with the \n\t\t * values of the parameters at the given index\n\t\t * @param parameters { [name: string]: Float32Array },\n\t\t * @param index number\n\t\t */\n\t\tupdateParams(parameters, index) {\n\t\t\tfor (const paramName in parameters) {\n\t\t\t\tconst param = parameters[paramName];\n\t\t\t\tif (param.length > 1) {\n\t\t\t\t\tthis.params[paramName] = parameters[paramName][index];\n\t\t\t\t} else {\n\t\t\t\t\tthis.params[paramName] = parameters[paramName][0];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Process a single frame of the audio\n\t\t * @param inputs Float32Array[][]\n\t\t * @param outputs Float32Array[][]\n\t\t */\n\t\tprocess(inputs, outputs, parameters) {\n\t\t\tconst input = inputs[0];\n\t\t\tconst output = outputs[0];\n\t\t\t// get the parameter values\n\t\t\tconst channelCount = Math.max(input && input.length || 0, output.length);\n\t\t\tfor (let sample = 0; sample < this.blockSize; sample++) {\n\t\t\t\tthis.updateParams(parameters, sample);\n\t\t\t\tfor (let channel = 0; channel < channelCount; channel++) {\n\t\t\t\t\tconst inputSample = input && input.length ? input[channel][sample] : 0;\n\t\t\t\t\toutput[channel][sample] = this.generate(inputSample, channel, this.params);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn !this.disposed;\n\t\t}\n\t};\n`;\naddToWorklet(singleIOProcess);\n//# sourceMappingURL=SingleIOProcessor.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/worklet/DelayLine.worklet.js\n\nconst delayLine = /* javascript */ `\n\t/**\n\t * A multichannel buffer for use within an AudioWorkletProcessor as a delay line\n\t */\n\tclass DelayLine {\n\t\t\n\t\tconstructor(size, channels) {\n\t\t\tthis.buffer = [];\n\t\t\tthis.writeHead = []\n\t\t\tthis.size = size;\n\n\t\t\t// create the empty channels\n\t\t\tfor (let i = 0; i < channels; i++) {\n\t\t\t\tthis.buffer[i] = new Float32Array(this.size);\n\t\t\t\tthis.writeHead[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Push a value onto the end\n\t\t * @param channel number\n\t\t * @param value number\n\t\t */\n\t\tpush(channel, value) {\n\t\t\tthis.writeHead[channel] += 1;\n\t\t\tif (this.writeHead[channel] > this.size) {\n\t\t\t\tthis.writeHead[channel] = 0;\n\t\t\t}\n\t\t\tthis.buffer[channel][this.writeHead[channel]] = value;\n\t\t}\n\n\t\t/**\n\t\t * Get the recorded value of the channel given the delay\n\t\t * @param channel number\n\t\t * @param delay number delay samples\n\t\t */\n\t\tget(channel, delay) {\n\t\t\tlet readHead = this.writeHead[channel] - Math.floor(delay);\n\t\t\tif (readHead < 0) {\n\t\t\t\treadHead += this.size;\n\t\t\t}\n\t\t\treturn this.buffer[channel][readHead];\n\t\t}\n\t}\n`;\naddToWorklet(delayLine);\n//# sourceMappingURL=DelayLine.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/FeedbackCombFilter.worklet.js\n\n\n\nconst FeedbackCombFilter_worklet_workletName = "feedback-comb-filter";\nconst feedbackCombFilter = /* javascript */ `\n\tclass FeedbackCombFilterWorklet extends SingleIOProcessor {\n\n\t\tconstructor(options) {\n\t\t\tsuper(options);\n\t\t\tthis.delayLine = new DelayLine(this.sampleRate, options.channelCount || 2);\n\t\t}\n\n\t\tstatic get parameterDescriptors() {\n\t\t\treturn [{\n\t\t\t\tname: "delayTime",\n\t\t\t\tdefaultValue: 0.1,\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 1,\n\t\t\t\tautomationRate: "k-rate"\n\t\t\t}, {\n\t\t\t\tname: "feedback",\n\t\t\t\tdefaultValue: 0.5,\n\t\t\t\tminValue: 0,\n\t\t\t\tmaxValue: 0.9999,\n\t\t\t\tautomationRate: "k-rate"\n\t\t\t}];\n\t\t}\n\n\t\tgenerate(input, channel, parameters) {\n\t\t\tconst delayedSample = this.delayLine.get(channel, parameters.delayTime * this.sampleRate);\n\t\t\tthis.delayLine.push(channel, input + delayedSample * parameters.feedback);\n\t\t\treturn delayedSample;\n\t\t}\n\t}\n`;\nregisterProcessor(FeedbackCombFilter_worklet_workletName, feedbackCombFilter);\n//# sourceMappingURL=FeedbackCombFilter.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/FeedbackCombFilter.js\n\n\n\n\n\n\n\n/**\n * Comb filters are basic building blocks for physical modeling. Read more\n * about comb filters on [CCRMA\'s website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html).\n *\n * This comb filter is implemented with the AudioWorkletNode which allows it to have feedback delays less than the\n * Web Audio processing block of 128 samples. There is a polyfill for browsers that don\'t yet support the\n * AudioWorkletNode, but it will add some latency and have slower performance than the AudioWorkletNode.\n * @category Component\n */\nclass FeedbackCombFilter_FeedbackCombFilter extends (/* unused pure expression or super */ null && (ToneAudioWorklet)) {\n constructor() {\n super(optionsFromArguments(FeedbackCombFilter_FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]));\n this.name = "FeedbackCombFilter";\n const options = optionsFromArguments(FeedbackCombFilter_FeedbackCombFilter.getDefaults(), arguments, ["delayTime", "resonance"]);\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this.delayTime = new Param({\n context: this.context,\n value: options.delayTime,\n units: "time",\n minValue: 0,\n maxValue: 1,\n param: this._dummyParam,\n swappable: true,\n });\n this.resonance = new Param({\n context: this.context,\n value: options.resonance,\n units: "normalRange",\n param: this._dummyParam,\n swappable: true,\n });\n readOnly(this, ["resonance", "delayTime"]);\n }\n _audioWorkletName() {\n return workletName;\n }\n /**\n * The default parameters\n */\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n delayTime: 0.1,\n resonance: 0.5,\n });\n }\n onReady(node) {\n connectSeries(this.input, node, this.output);\n const delayTime = node.parameters.get("delayTime");\n ;\n this.delayTime.setParam(delayTime);\n const feedback = node.parameters.get("feedback");\n ;\n this.resonance.setParam(feedback);\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.delayTime.dispose();\n this.resonance.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackCombFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/OnePoleFilter.js\n\n\n\n/**\n * A one pole filter with 6db-per-octave rolloff. Either "highpass" or "lowpass".\n * Note that changing the type or frequency may result in a discontinuity which\n * can sound like a click or pop.\n * References:\n * * http://www.earlevel.com/main/2012/12/15/a-one-pole-filter/\n * * http://www.dspguide.com/ch19/2.htm\n * * https://github.com/vitaliy-bobrov/js-rocks/blob/master/src/app/audio/effects/one-pole-filters.ts\n * @category Component\n */\nclass OnePoleFilter_OnePoleFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(OnePoleFilter_OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]));\n this.name = "OnePoleFilter";\n const options = optionsFromArguments(OnePoleFilter_OnePoleFilter.getDefaults(), arguments, ["frequency", "type"]);\n this._frequency = options.frequency;\n this._type = options.type;\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this._createFilter();\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n frequency: 880,\n type: "lowpass"\n });\n }\n /**\n * Create a filter and dispose the old one\n */\n _createFilter() {\n const oldFilter = this._filter;\n const freq = this.toFrequency(this._frequency);\n const t = 1 / (2 * Math.PI * freq);\n if (this._type === "lowpass") {\n const a0 = 1 / (t * this.context.sampleRate);\n const b1 = a0 - 1;\n this._filter = this.context.createIIRFilter([a0, 0], [1, b1]);\n }\n else {\n const b1 = 1 / (t * this.context.sampleRate) - 1;\n this._filter = this.context.createIIRFilter([1, -1], [1, b1]);\n }\n this.input.chain(this._filter, this.output);\n if (oldFilter) {\n // dispose it on the next block\n this.context.setTimeout(() => {\n if (!this.disposed) {\n this.input.disconnect(oldFilter);\n oldFilter.disconnect();\n }\n }, this.blockTime);\n }\n }\n /**\n * The frequency value.\n */\n get frequency() {\n return this._frequency;\n }\n set frequency(fq) {\n this._frequency = fq;\n this._createFilter();\n }\n /**\n * The OnePole Filter type, either "highpass" or "lowpass"\n */\n get type() {\n return this._type;\n }\n set type(t) {\n this._type = t;\n this._createFilter();\n }\n /**\n * Get the frequency response curve. This curve represents how the filter\n * responses to frequencies between 20hz-20khz.\n * @param len The number of values to return\n * @return The frequency response curve between 20-20kHz\n */\n getFrequencyResponse(len = 128) {\n const freqValues = new Float32Array(len);\n for (let i = 0; i < len; i++) {\n const norm = Math.pow(i / len, 2);\n const freq = norm * (20000 - 20) + 20;\n freqValues[i] = freq;\n }\n const magValues = new Float32Array(len);\n const phaseValues = new Float32Array(len);\n this._filter.getFrequencyResponse(freqValues, magValues, phaseValues);\n return magValues;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this._filter.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=OnePoleFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/LowpassCombFilter.js\n\n\n\n\n/**\n * A lowpass feedback comb filter. It is similar to\n * [[FeedbackCombFilter]], but includes a lowpass filter.\n * @category Component\n */\nclass LowpassCombFilter_LowpassCombFilter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(LowpassCombFilter_LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]));\n this.name = "LowpassCombFilter";\n const options = optionsFromArguments(LowpassCombFilter_LowpassCombFilter.getDefaults(), arguments, ["delayTime", "resonance", "dampening"]);\n this._combFilter = this.output = new FeedbackCombFilter({\n context: this.context,\n delayTime: options.delayTime,\n resonance: options.resonance,\n });\n this.delayTime = this._combFilter.delayTime;\n this.resonance = this._combFilter.resonance;\n this._lowpass = this.input = new OnePoleFilter({\n context: this.context,\n frequency: options.dampening,\n type: "lowpass",\n });\n // connections\n this._lowpass.connect(this._combFilter);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n dampening: 3000,\n delayTime: 0.1,\n resonance: 0.5,\n });\n }\n /**\n * The dampening control of the feedback\n */\n get dampening() {\n return this._lowpass.frequency;\n }\n set dampening(fq) {\n this._lowpass.frequency = fq;\n }\n dispose() {\n super.dispose();\n this._combFilter.dispose();\n this._lowpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LowpassCombFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/PluckSynth.js\n\n\n\n\n\n/**\n * Karplus-String string synthesis.\n * @example\n * const plucky = new Tone.PluckSynth().toDestination();\n * plucky.triggerAttack("C4", "+0.5");\n * plucky.triggerAttack("C3", "+1");\n * plucky.triggerAttack("C2", "+1.5");\n * plucky.triggerAttack("C1", "+2");\n * @category Instrument\n */\nclass PluckSynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(PluckSynth.getDefaults(), arguments));\n this.name = "PluckSynth";\n const options = optionsFromArguments(PluckSynth.getDefaults(), arguments);\n this._noise = new Noise({\n context: this.context,\n type: "pink"\n });\n this.attackNoise = options.attackNoise;\n this._lfcf = new LowpassCombFilter({\n context: this.context,\n dampening: options.dampening,\n resonance: options.resonance,\n });\n this.resonance = options.resonance;\n this.release = options.release;\n this._noise.connect(this._lfcf);\n this._lfcf.connect(this.output);\n }\n static getDefaults() {\n return deepMerge(Instrument.getDefaults(), {\n attackNoise: 1,\n dampening: 4000,\n resonance: 0.7,\n release: 1,\n });\n }\n /**\n * The dampening control. i.e. the lowpass filter frequency of the comb filter\n * @min 0\n * @max 7000\n */\n get dampening() {\n return this._lfcf.dampening;\n }\n set dampening(fq) {\n this._lfcf.dampening = fq;\n }\n triggerAttack(note, time) {\n const freq = this.toFrequency(note);\n time = this.toSeconds(time);\n const delayAmount = 1 / freq;\n this._lfcf.delayTime.setValueAtTime(delayAmount, time);\n this._noise.start(time);\n this._noise.stop(time + delayAmount * this.attackNoise);\n this._lfcf.resonance.cancelScheduledValues(time);\n this._lfcf.resonance.setValueAtTime(this.resonance, time);\n return this;\n }\n /**\n * Ramp down the [[resonance]] to 0 over the duration of the release time.\n */\n triggerRelease(time) {\n this._lfcf.resonance.linearRampTo(0, this.release, time);\n return this;\n }\n dispose() {\n super.dispose();\n this._noise.dispose();\n this._lfcf.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PluckSynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/PolySynth.js\n\n\n\n\n\n\n/**\n * PolySynth handles voice creation and allocation for any\n * instruments passed in as the second paramter. PolySynth is\n * not a synthesizer by itself, it merely manages voices of\n * one of the other types of synths, allowing any of the\n * monophonic synthesizers to be polyphonic.\n *\n * @example\n * const synth = new Tone.PolySynth().toDestination();\n * // set the attributes across all the voices using \'set\'\n * synth.set({ detune: -1200 });\n * // play a chord\n * synth.triggerAttackRelease(["C4", "E4", "A4"], 1);\n * @category Instrument\n */\nclass PolySynth extends (/* unused pure expression or super */ null && (Instrument)) {\n constructor() {\n super(optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]));\n this.name = "PolySynth";\n /**\n * The voices which are not currently in use\n */\n this._availableVoices = [];\n /**\n * The currently active voices\n */\n this._activeVoices = [];\n /**\n * All of the allocated voices for this synth.\n */\n this._voices = [];\n /**\n * The GC timeout. Held so that it could be cancelled when the node is disposed.\n */\n this._gcTimeout = -1;\n /**\n * A moving average of the number of active voices\n */\n this._averageActiveVoices = 0;\n const options = optionsFromArguments(PolySynth.getDefaults(), arguments, ["voice", "options"]);\n // check against the old API (pre 14.3.0)\n assert(!isNumber(options.voice), "DEPRECATED: The polyphony count is no longer the first argument.");\n const defaults = options.voice.getDefaults();\n this.options = Object.assign(defaults, options.options);\n this.voice = options.voice;\n this.maxPolyphony = options.maxPolyphony;\n // create the first voice\n this._dummyVoice = this._getNextAvailableVoice();\n // remove it from the voices list\n const index = this._voices.indexOf(this._dummyVoice);\n this._voices.splice(index, 1);\n // kick off the GC interval\n this._gcTimeout = this.context.setInterval(this._collectGarbage.bind(this), 1);\n }\n static getDefaults() {\n return Object.assign(Instrument.getDefaults(), {\n maxPolyphony: 32,\n options: {},\n voice: Synth,\n });\n }\n /**\n * The number of active voices.\n */\n get activeVoices() {\n return this._activeVoices.length;\n }\n /**\n * Invoked when the source is done making sound, so that it can be\n * readded to the pool of available voices\n */\n _makeVoiceAvailable(voice) {\n this._availableVoices.push(voice);\n // remove the midi note from \'active voices\'\n const activeVoiceIndex = this._activeVoices.findIndex((e) => e.voice === voice);\n this._activeVoices.splice(activeVoiceIndex, 1);\n }\n /**\n * Get an available voice from the pool of available voices.\n * If one is not available and the maxPolyphony limit is reached,\n * steal a voice, otherwise return null.\n */\n _getNextAvailableVoice() {\n // if there are available voices, return the first one\n if (this._availableVoices.length) {\n return this._availableVoices.shift();\n }\n else if (this._voices.length < this.maxPolyphony) {\n // otherwise if there is still more maxPolyphony, make a new voice\n const voice = new this.voice(Object.assign(this.options, {\n context: this.context,\n onsilence: this._makeVoiceAvailable.bind(this),\n }));\n voice.connect(this.output);\n this._voices.push(voice);\n return voice;\n }\n else {\n warn("Max polyphony exceeded. Note dropped.");\n }\n }\n /**\n * Occasionally check if there are any allocated voices which can be cleaned up.\n */\n _collectGarbage() {\n this._averageActiveVoices = Math.max(this._averageActiveVoices * 0.95, this.activeVoices);\n if (this._availableVoices.length && this._voices.length > Math.ceil(this._averageActiveVoices + 1)) {\n // take off an available note\n const firstAvail = this._availableVoices.shift();\n const index = this._voices.indexOf(firstAvail);\n this._voices.splice(index, 1);\n if (!this.context.isOffline) {\n firstAvail.dispose();\n }\n }\n }\n /**\n * Internal method which triggers the attack\n */\n _triggerAttack(notes, time, velocity) {\n notes.forEach(note => {\n const midiNote = new MidiClass(this.context, note).toMidi();\n const voice = this._getNextAvailableVoice();\n if (voice) {\n voice.triggerAttack(note, time, velocity);\n this._activeVoices.push({\n midi: midiNote, voice, released: false,\n });\n this.log("triggerAttack", note, time);\n }\n });\n }\n /**\n * Internal method which triggers the release\n */\n _triggerRelease(notes, time) {\n notes.forEach(note => {\n const midiNote = new MidiClass(this.context, note).toMidi();\n const event = this._activeVoices.find(({ midi, released }) => midi === midiNote && !released);\n if (event) {\n // trigger release on that note\n event.voice.triggerRelease(time);\n // mark it as released\n event.released = true;\n this.log("triggerRelease", note, time);\n }\n });\n }\n /**\n * Schedule the attack/release events. If the time is in the future, then it should set a timeout\n * to wait for just-in-time scheduling\n */\n _scheduleEvent(type, notes, time, velocity) {\n assert(!this.disposed, "Synth was already disposed");\n // if the notes are greater than this amount of time in the future, they should be scheduled with setTimeout\n if (time <= this.now()) {\n // do it immediately\n if (type === "attack") {\n this._triggerAttack(notes, time, velocity);\n }\n else {\n this._triggerRelease(notes, time);\n }\n }\n else {\n // schedule it to start in the future\n this.context.setTimeout(() => {\n this._scheduleEvent(type, notes, time, velocity);\n }, time - this.now());\n }\n }\n /**\n * Trigger the attack portion of the note\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param time The start time of the note.\n * @param velocity The velocity of the note.\n * @example\n * const synth = new Tone.PolySynth(Tone.FMSynth).toDestination();\n * // trigger a chord immediately with a velocity of 0.2\n * synth.triggerAttack(["Ab3", "C4", "F5"], Tone.now(), 0.2);\n */\n triggerAttack(notes, time, velocity) {\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n const computedTime = this.toSeconds(time);\n this._scheduleEvent("attack", notes, computedTime, velocity);\n return this;\n }\n /**\n * Trigger the release of the note. Unlike monophonic instruments,\n * a note (or array of notes) needs to be passed in as the first argument.\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param time When the release will be triggered.\n * @example\n * @example\n * const poly = new Tone.PolySynth(Tone.AMSynth).toDestination();\n * poly.triggerAttack(["Ab3", "C4", "F5"]);\n * // trigger the release of the given notes.\n * poly.triggerRelease(["Ab3", "C4"], "+1");\n * poly.triggerRelease("F5", "+3");\n */\n triggerRelease(notes, time) {\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n const computedTime = this.toSeconds(time);\n this._scheduleEvent("release", notes, computedTime);\n return this;\n }\n /**\n * Trigger the attack and release after the specified duration\n * @param notes The notes to play. Accepts a single Frequency or an array of frequencies.\n * @param duration the duration of the note\n * @param time if no time is given, defaults to now\n * @param velocity the velocity of the attack (0-1)\n * @example\n * const poly = new Tone.PolySynth(Tone.AMSynth).toDestination();\n * // can pass in an array of durations as well\n * poly.triggerAttackRelease(["Eb3", "G4", "Bb4", "D5"], [4, 3, 2, 1]);\n */\n triggerAttackRelease(notes, duration, time, velocity) {\n const computedTime = this.toSeconds(time);\n this.triggerAttack(notes, computedTime, velocity);\n if (isArray(duration)) {\n assert(isArray(notes), "If the duration is an array, the notes must also be an array");\n notes = notes;\n for (let i = 0; i < notes.length; i++) {\n const d = duration[Math.min(i, duration.length - 1)];\n const durationSeconds = this.toSeconds(d);\n assert(durationSeconds > 0, "The duration must be greater than 0");\n this.triggerRelease(notes[i], computedTime + durationSeconds);\n }\n }\n else {\n const durationSeconds = this.toSeconds(duration);\n assert(durationSeconds > 0, "The duration must be greater than 0");\n this.triggerRelease(notes, computedTime + durationSeconds);\n }\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 1);\n }\n return this;\n }\n /**\n * Set a member/attribute of the voices\n * @example\n * const poly = new Tone.PolySynth().toDestination();\n * // set all of the voices using an options object for the synth type\n * poly.set({\n * \tenvelope: {\n * \t\tattack: 0.25\n * \t}\n * });\n * poly.triggerAttackRelease("Bb3", 0.2);\n */\n set(options) {\n // remove options which are controlled by the PolySynth\n const sanitizedOptions = omitFromObject(options, ["onsilence", "context"]);\n // store all of the options\n this.options = deepMerge(this.options, sanitizedOptions);\n this._voices.forEach(voice => voice.set(sanitizedOptions));\n this._dummyVoice.set(sanitizedOptions);\n return this;\n }\n get() {\n return this._dummyVoice.get();\n }\n /**\n * Trigger the release portion of all the currently active voices immediately.\n * Useful for silencing the synth.\n */\n releaseAll(time) {\n const computedTime = this.toSeconds(time);\n this._activeVoices.forEach(({ voice }) => {\n voice.triggerRelease(computedTime);\n });\n return this;\n }\n dispose() {\n super.dispose();\n this._dummyVoice.dispose();\n this._voices.forEach(v => v.dispose());\n this._activeVoices = [];\n this._availableVoices = [];\n this.context.clearInterval(this._gcTimeout);\n return this;\n }\n}\n//# sourceMappingURL=PolySynth.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/Sampler.js\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Pass in an object which maps the note\'s pitch or midi value to the url,\n * then you can trigger the attack and release of that note like other instruments.\n * By automatically repitching the samples, it is possible to play pitches which\n * were not explicitly included which can save loading time.\n *\n * For sample or buffer playback where repitching is not necessary,\n * use [[Player]].\n * @example\n * const sampler = new Tone.Sampler({\n * \turls: {\n * \t\tA1: "A1.mp3",\n * \t\tA2: "A2.mp3",\n * \t},\n * \tbaseUrl: "https://tonejs.github.io/audio/casio/",\n * \tonload: () => {\n * \t\tsampler.triggerAttackRelease(["C1", "E1", "G1", "B1"], 0.5);\n * \t}\n * }).toDestination();\n * @category Instrument\n */\nclass Sampler extends Instrument_Instrument {\n constructor() {\n super(Defaults_optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls"));\n this.name = "Sampler";\n /**\n * The object of all currently playing BufferSources\n */\n this._activeSources = new Map();\n const options = Defaults_optionsFromArguments(Sampler.getDefaults(), arguments, ["urls", "onload", "baseUrl"], "urls");\n const urlMap = {};\n Object.keys(options.urls).forEach((note) => {\n const noteNumber = parseInt(note, 10);\n Debug_assert(isNote(note)\n || (TypeCheck_isNumber(noteNumber) && isFinite(noteNumber)), `url key is neither a note or midi pitch: ${note}`);\n if (isNote(note)) {\n // convert the note name to MIDI\n const mid = new Frequency_FrequencyClass(this.context, note).toMidi();\n urlMap[mid] = options.urls[note];\n }\n else if (TypeCheck_isNumber(noteNumber) && isFinite(noteNumber)) {\n // otherwise if it\'s numbers assume it\'s midi\n urlMap[noteNumber] = options.urls[noteNumber];\n }\n });\n this._buffers = new ToneAudioBuffers_ToneAudioBuffers({\n urls: urlMap,\n onload: options.onload,\n baseUrl: options.baseUrl,\n onerror: options.onerror,\n });\n this.attack = options.attack;\n this.release = options.release;\n this.curve = options.curve;\n // invoke the callback if it\'s already loaded\n if (this._buffers.loaded) {\n // invoke onload deferred\n Promise.resolve().then(options.onload);\n }\n }\n static getDefaults() {\n return Object.assign(Instrument_Instrument.getDefaults(), {\n attack: 0,\n baseUrl: "",\n curve: "exponential",\n onload: Interface_noOp,\n onerror: Interface_noOp,\n release: 0.1,\n urls: {},\n });\n }\n /**\n * Returns the difference in steps between the given midi note at the closets sample.\n */\n _findClosest(midi) {\n // searches within 8 octaves of the given midi note\n const MAX_INTERVAL = 96;\n let interval = 0;\n while (interval < MAX_INTERVAL) {\n // check above and below\n if (this._buffers.has(midi + interval)) {\n return -interval;\n }\n else if (this._buffers.has(midi - interval)) {\n return interval;\n }\n interval++;\n }\n throw new Error(`No available buffers for note: ${midi}`);\n }\n /**\n * @param notes\tThe note to play, or an array of notes.\n * @param time When to play the note\n * @param velocity The velocity to play the sample back.\n */\n triggerAttack(notes, time, velocity = 1) {\n this.log("triggerAttack", notes, time, velocity);\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n notes.forEach(note => {\n const midiFloat = ftomf(new Frequency_FrequencyClass(this.context, note).toFrequency());\n const midi = Math.round(midiFloat);\n const remainder = midiFloat - midi;\n // find the closest note pitch\n const difference = this._findClosest(midi);\n const closestNote = midi - difference;\n const buffer = this._buffers.get(closestNote);\n const playbackRate = Conversions_intervalToFrequencyRatio(difference + remainder);\n // play that note\n const source = new ToneBufferSource_ToneBufferSource({\n url: buffer,\n context: this.context,\n curve: this.curve,\n fadeIn: this.attack,\n fadeOut: this.release,\n playbackRate,\n }).connect(this.output);\n source.start(time, 0, buffer.duration / playbackRate, velocity);\n // add it to the active sources\n if (!TypeCheck_isArray(this._activeSources.get(midi))) {\n this._activeSources.set(midi, []);\n }\n this._activeSources.get(midi).push(source);\n // remove it when it\'s done\n source.onended = () => {\n if (this._activeSources && this._activeSources.has(midi)) {\n const sources = this._activeSources.get(midi);\n const index = sources.indexOf(source);\n if (index !== -1) {\n sources.splice(index, 1);\n }\n }\n };\n });\n return this;\n }\n /**\n * @param notes\tThe note to release, or an array of notes.\n * @param time \tWhen to release the note.\n */\n triggerRelease(notes, time) {\n this.log("triggerRelease", notes, time);\n if (!Array.isArray(notes)) {\n notes = [notes];\n }\n notes.forEach(note => {\n const midi = new Frequency_FrequencyClass(this.context, note).toMidi();\n // find the note\n if (this._activeSources.has(midi) && this._activeSources.get(midi).length) {\n const sources = this._activeSources.get(midi);\n time = this.toSeconds(time);\n sources.forEach(source => {\n source.stop(time);\n });\n this._activeSources.set(midi, []);\n }\n });\n return this;\n }\n /**\n * Release all currently active notes.\n * @param time \tWhen to release the notes.\n */\n releaseAll(time) {\n const computedTime = this.toSeconds(time);\n this._activeSources.forEach(sources => {\n while (sources.length) {\n const source = sources.shift();\n source.stop(computedTime);\n }\n });\n return this;\n }\n sync() {\n if (this._syncState()) {\n this._syncMethod("triggerAttack", 1);\n this._syncMethod("triggerRelease", 1);\n }\n return this;\n }\n /**\n * Invoke the attack phase, then after the duration, invoke the release.\n * @param notes\tThe note to play and release, or an array of notes.\n * @param duration The time the note should be held\n * @param time When to start the attack\n * @param velocity The velocity of the attack\n */\n triggerAttackRelease(notes, duration, time, velocity = 1) {\n const computedTime = this.toSeconds(time);\n this.triggerAttack(notes, computedTime, velocity);\n if (TypeCheck_isArray(duration)) {\n Debug_assert(TypeCheck_isArray(notes), "notes must be an array when duration is array");\n notes.forEach((note, index) => {\n const d = duration[Math.min(index, duration.length - 1)];\n this.triggerRelease(note, computedTime + this.toSeconds(d));\n });\n }\n else {\n this.triggerRelease(notes, computedTime + this.toSeconds(duration));\n }\n return this;\n }\n /**\n * Add a note to the sampler.\n * @param note The buffer\'s pitch.\n * @param url Either the url of the buffer, or a buffer which will be added with the given name.\n * @param callback The callback to invoke when the url is loaded.\n */\n add(note, url, callback) {\n Debug_assert(isNote(note) || isFinite(note), `note must be a pitch or midi: ${note}`);\n if (isNote(note)) {\n // convert the note name to MIDI\n const mid = new Frequency_FrequencyClass(this.context, note).toMidi();\n this._buffers.add(mid, url, callback);\n }\n else {\n // otherwise if it\'s numbers assume it\'s midi\n this._buffers.add(note, url, callback);\n }\n return this;\n }\n /**\n * If the buffers are loaded or not\n */\n get loaded() {\n return this._buffers.loaded;\n }\n /**\n * Clean up\n */\n dispose() {\n super.dispose();\n this._buffers.dispose();\n this._activeSources.forEach(sources => {\n sources.forEach(source => source.dispose());\n });\n this._activeSources.clear();\n return this;\n }\n}\n__decorate([\n timeRange(0)\n], Sampler.prototype, "attack", void 0);\n__decorate([\n timeRange(0)\n], Sampler.prototype, "release", void 0);\n//# sourceMappingURL=Sampler.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/instrument/index.js\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/ToneEvent.js\n\n\n\n\n\n\n\n/**\n * ToneEvent abstracts away this.context.transport.schedule and provides a schedulable\n * callback for a single or repeatable events along the timeline.\n *\n * @example\n * const synth = new Tone.PolySynth().toDestination();\n * const chordEvent = new Tone.ToneEvent(((time, chord) => {\n * \t// the chord as well as the exact time of the event\n * \t// are passed in as arguments to the callback function\n * \tsynth.triggerAttackRelease(chord, 0.5, time);\n * }), ["D4", "E4", "F4"]);\n * // start the chord at the beginning of the transport timeline\n * chordEvent.start();\n * // loop it every measure for 8 measures\n * chordEvent.loop = 8;\n * chordEvent.loopEnd = "1m";\n * @category Event\n */\nclass ToneEvent_ToneEvent extends (/* unused pure expression or super */ null && (ToneWithContext)) {\n constructor() {\n super(optionsFromArguments(ToneEvent_ToneEvent.getDefaults(), arguments, ["callback", "value"]));\n this.name = "ToneEvent";\n /**\n * Tracks the scheduled events\n */\n this._state = new StateTimeline("stopped");\n /**\n * A delay time from when the event is scheduled to start\n */\n this._startOffset = 0;\n const options = optionsFromArguments(ToneEvent_ToneEvent.getDefaults(), arguments, ["callback", "value"]);\n this._loop = options.loop;\n this.callback = options.callback;\n this.value = options.value;\n this._loopStart = this.toTicks(options.loopStart);\n this._loopEnd = this.toTicks(options.loopEnd);\n this._playbackRate = options.playbackRate;\n this._probability = options.probability;\n this._humanize = options.humanize;\n this.mute = options.mute;\n this._playbackRate = options.playbackRate;\n this._state.increasing = true;\n // schedule the events for the first time\n this._rescheduleEvents();\n }\n static getDefaults() {\n return Object.assign(ToneWithContext.getDefaults(), {\n callback: noOp,\n humanize: false,\n loop: false,\n loopEnd: "1m",\n loopStart: 0,\n mute: false,\n playbackRate: 1,\n probability: 1,\n value: null,\n });\n }\n /**\n * Reschedule all of the events along the timeline\n * with the updated values.\n * @param after Only reschedules events after the given time.\n */\n _rescheduleEvents(after = -1) {\n // if no argument is given, schedules all of the events\n this._state.forEachFrom(after, event => {\n let duration;\n if (event.state === "started") {\n if (event.id !== -1) {\n this.context.transport.clear(event.id);\n }\n const startTick = event.time + Math.round(this.startOffset / this._playbackRate);\n if (this._loop === true || isNumber(this._loop) && this._loop > 1) {\n duration = Infinity;\n if (isNumber(this._loop)) {\n duration = (this._loop) * this._getLoopDuration();\n }\n const nextEvent = this._state.getAfter(startTick);\n if (nextEvent !== null) {\n duration = Math.min(duration, nextEvent.time - startTick);\n }\n if (duration !== Infinity) {\n // schedule a stop since it\'s finite duration\n this._state.setStateAtTime("stopped", startTick + duration + 1, { id: -1 });\n duration = new TicksClass(this.context, duration);\n }\n const interval = new TicksClass(this.context, this._getLoopDuration());\n event.id = this.context.transport.scheduleRepeat(this._tick.bind(this), interval, new TicksClass(this.context, startTick), duration);\n }\n else {\n event.id = this.context.transport.schedule(this._tick.bind(this), new TicksClass(this.context, startTick));\n }\n }\n });\n }\n /**\n * Returns the playback state of the note, either "started" or "stopped".\n */\n get state() {\n return this._state.getValueAtTime(this.context.transport.ticks);\n }\n /**\n * The start from the scheduled start time.\n */\n get startOffset() {\n return this._startOffset;\n }\n set startOffset(offset) {\n this._startOffset = offset;\n }\n /**\n * The probability of the notes being triggered.\n */\n get probability() {\n return this._probability;\n }\n set probability(prob) {\n this._probability = prob;\n }\n /**\n * If set to true, will apply small random variation\n * to the callback time. If the value is given as a time, it will randomize\n * by that amount.\n * @example\n * const event = new Tone.ToneEvent();\n * event.humanize = true;\n */\n get humanize() {\n return this._humanize;\n }\n set humanize(variation) {\n this._humanize = variation;\n }\n /**\n * Start the note at the given time.\n * @param time When the event should start.\n */\n start(time) {\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) === "stopped") {\n this._state.add({\n id: -1,\n state: "started",\n time: ticks,\n });\n this._rescheduleEvents(ticks);\n }\n return this;\n }\n /**\n * Stop the Event at the given time.\n * @param time When the event should stop.\n */\n stop(time) {\n this.cancel(time);\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) === "started") {\n this._state.setStateAtTime("stopped", ticks, { id: -1 });\n const previousEvent = this._state.getBefore(ticks);\n let reschedulTime = ticks;\n if (previousEvent !== null) {\n reschedulTime = previousEvent.time;\n }\n this._rescheduleEvents(reschedulTime);\n }\n return this;\n }\n /**\n * Cancel all scheduled events greater than or equal to the given time\n * @param time The time after which events will be cancel.\n */\n cancel(time) {\n time = defaultArg(time, -Infinity);\n const ticks = this.toTicks(time);\n this._state.forEachFrom(ticks, event => {\n this.context.transport.clear(event.id);\n });\n this._state.cancel(ticks);\n return this;\n }\n /**\n * The callback function invoker. Also\n * checks if the Event is done playing\n * @param time The time of the event in seconds\n */\n _tick(time) {\n const ticks = this.context.transport.getTicksAtTime(time);\n if (!this.mute && this._state.getValueAtTime(ticks) === "started") {\n if (this.probability < 1 && Math.random() > this.probability) {\n return;\n }\n if (this.humanize) {\n let variation = 0.02;\n if (!isBoolean(this.humanize)) {\n variation = this.toSeconds(this.humanize);\n }\n time += (Math.random() * 2 - 1) * variation;\n }\n this.callback(time, this.value);\n }\n }\n /**\n * Get the duration of the loop.\n */\n _getLoopDuration() {\n return Math.round((this._loopEnd - this._loopStart) / this._playbackRate);\n }\n /**\n * If the note should loop or not\n * between ToneEvent.loopStart and\n * ToneEvent.loopEnd. If set to true,\n * the event will loop indefinitely,\n * if set to a number greater than 1\n * it will play a specific number of\n * times, if set to false, 0 or 1, the\n * part will only play once.\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this._rescheduleEvents();\n }\n /**\n * The playback rate of the note. Defaults to 1.\n * @example\n * const note = new Tone.ToneEvent();\n * note.loop = true;\n * // repeat the note twice as fast\n * note.playbackRate = 2;\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n this._rescheduleEvents();\n }\n /**\n * The loopEnd point is the time the event will loop\n * if ToneEvent.loop is true.\n */\n get loopEnd() {\n return new TicksClass(this.context, this._loopEnd).toSeconds();\n }\n set loopEnd(loopEnd) {\n this._loopEnd = this.toTicks(loopEnd);\n if (this._loop) {\n this._rescheduleEvents();\n }\n }\n /**\n * The time when the loop should start.\n */\n get loopStart() {\n return new TicksClass(this.context, this._loopStart).toSeconds();\n }\n set loopStart(loopStart) {\n this._loopStart = this.toTicks(loopStart);\n if (this._loop) {\n this._rescheduleEvents();\n }\n }\n /**\n * The current progress of the loop interval.\n * Returns 0 if the event is not started yet or\n * it is not set to loop.\n */\n get progress() {\n if (this._loop) {\n const ticks = this.context.transport.ticks;\n const lastEvent = this._state.get(ticks);\n if (lastEvent !== null && lastEvent.state === "started") {\n const loopDuration = this._getLoopDuration();\n const progress = (ticks - lastEvent.time) % loopDuration;\n return progress / loopDuration;\n }\n else {\n return 0;\n }\n }\n else {\n return 0;\n }\n }\n dispose() {\n super.dispose();\n this.cancel();\n this._state.dispose();\n return this;\n }\n}\n//# sourceMappingURL=ToneEvent.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Loop.js\n\n\n\n\n/**\n * Loop creates a looped callback at the\n * specified interval. The callback can be\n * started, stopped and scheduled along\n * the Transport\'s timeline.\n * @example\n * const loop = new Tone.Loop((time) => {\n * \t// triggered every eighth note.\n * \tconsole.log(time);\n * }, "8n").start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Loop_Loop extends (/* unused pure expression or super */ null && (ToneWithContext)) {\n constructor() {\n super(optionsFromArguments(Loop_Loop.getDefaults(), arguments, ["callback", "interval"]));\n this.name = "Loop";\n const options = optionsFromArguments(Loop_Loop.getDefaults(), arguments, ["callback", "interval"]);\n this._event = new ToneEvent({\n context: this.context,\n callback: this._tick.bind(this),\n loop: true,\n loopEnd: options.interval,\n playbackRate: options.playbackRate,\n probability: options.probability\n });\n this.callback = options.callback;\n // set the iterations\n this.iterations = options.iterations;\n }\n static getDefaults() {\n return Object.assign(ToneWithContext.getDefaults(), {\n interval: "4n",\n callback: noOp,\n playbackRate: 1,\n iterations: Infinity,\n probability: 1,\n mute: false,\n humanize: false\n });\n }\n /**\n * Start the loop at the specified time along the Transport\'s timeline.\n * @param time When to start the Loop.\n */\n start(time) {\n this._event.start(time);\n return this;\n }\n /**\n * Stop the loop at the given time.\n * @param time When to stop the Loop.\n */\n stop(time) {\n this._event.stop(time);\n return this;\n }\n /**\n * Cancel all scheduled events greater than or equal to the given time\n * @param time The time after which events will be cancel.\n */\n cancel(time) {\n this._event.cancel(time);\n return this;\n }\n /**\n * Internal function called when the notes should be called\n * @param time The time the event occurs\n */\n _tick(time) {\n this.callback(time);\n }\n /**\n * The state of the Loop, either started or stopped.\n */\n get state() {\n return this._event.state;\n }\n /**\n * The progress of the loop as a value between 0-1. 0, when the loop is stopped or done iterating.\n */\n get progress() {\n return this._event.progress;\n }\n /**\n * The time between successive callbacks.\n * @example\n * const loop = new Tone.Loop();\n * loop.interval = "8n"; // loop every 8n\n */\n get interval() {\n return this._event.loopEnd;\n }\n set interval(interval) {\n this._event.loopEnd = interval;\n }\n /**\n * The playback rate of the loop. The normal playback rate is 1 (no change).\n * A `playbackRate` of 2 would be twice as fast.\n */\n get playbackRate() {\n return this._event.playbackRate;\n }\n set playbackRate(rate) {\n this._event.playbackRate = rate;\n }\n /**\n * Random variation +/-0.01s to the scheduled time.\n * Or give it a time value which it will randomize by.\n */\n get humanize() {\n return this._event.humanize;\n }\n set humanize(variation) {\n this._event.humanize = variation;\n }\n /**\n * The probably of the callback being invoked.\n */\n get probability() {\n return this._event.probability;\n }\n set probability(prob) {\n this._event.probability = prob;\n }\n /**\n * Muting the Loop means that no callbacks are invoked.\n */\n get mute() {\n return this._event.mute;\n }\n set mute(mute) {\n this._event.mute = mute;\n }\n /**\n * The number of iterations of the loop. The default value is `Infinity` (loop forever).\n */\n get iterations() {\n if (this._event.loop === true) {\n return Infinity;\n }\n else {\n return this._event.loop;\n }\n }\n set iterations(iters) {\n if (iters === Infinity) {\n this._event.loop = true;\n }\n else {\n this._event.loop = iters;\n }\n }\n dispose() {\n super.dispose();\n this._event.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Loop.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Part.js\n\n\n\n\n\n\n/**\n * Part is a collection ToneEvents which can be started/stopped and looped as a single unit.\n *\n * @example\n * const synth = new Tone.Synth().toDestination();\n * const part = new Tone.Part(((time, note) => {\n * \t// the notes given as the second element in the array\n * \t// will be passed in as the second argument\n * \tsynth.triggerAttackRelease(note, "8n", time);\n * }), [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]);\n * Tone.Transport.start();\n * @example\n * const synth = new Tone.Synth().toDestination();\n * // use an array of objects as long as the object has a "time" attribute\n * const part = new Tone.Part(((time, value) => {\n * \t// the value is an object which contains both the note and the velocity\n * \tsynth.triggerAttackRelease(value.note, "8n", time, value.velocity);\n * }), [{ time: 0, note: "C3", velocity: 0.9 },\n * \t{ time: "0:2", note: "C4", velocity: 0.5 }\n * ]).start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Part_Part extends (/* unused pure expression or super */ null && (ToneEvent)) {\n constructor() {\n super(optionsFromArguments(Part_Part.getDefaults(), arguments, ["callback", "events"]));\n this.name = "Part";\n /**\n * Tracks the scheduled events\n */\n this._state = new StateTimeline("stopped");\n /**\n * The events that belong to this part\n */\n this._events = new Set();\n const options = optionsFromArguments(Part_Part.getDefaults(), arguments, ["callback", "events"]);\n // make sure things are assigned in the right order\n this._state.increasing = true;\n // add the events\n options.events.forEach(event => {\n if (isArray(event)) {\n this.add(event[0], event[1]);\n }\n else {\n this.add(event);\n }\n });\n }\n static getDefaults() {\n return Object.assign(ToneEvent.getDefaults(), {\n events: [],\n });\n }\n /**\n * Start the part at the given time.\n * @param time When to start the part.\n * @param offset The offset from the start of the part to begin playing at.\n */\n start(time, offset) {\n const ticks = this.toTicks(time);\n if (this._state.getValueAtTime(ticks) !== "started") {\n offset = defaultArg(offset, this._loop ? this._loopStart : 0);\n if (this._loop) {\n offset = defaultArg(offset, this._loopStart);\n }\n else {\n offset = defaultArg(offset, 0);\n }\n const computedOffset = this.toTicks(offset);\n this._state.add({\n id: -1,\n offset: computedOffset,\n state: "started",\n time: ticks,\n });\n this._forEach(event => {\n this._startNote(event, ticks, computedOffset);\n });\n }\n return this;\n }\n /**\n * Start the event in the given event at the correct time given\n * the ticks and offset and looping.\n * @param event\n * @param ticks\n * @param offset\n */\n _startNote(event, ticks, offset) {\n ticks -= offset;\n if (this._loop) {\n if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) {\n if (event.startOffset < offset) {\n // start it on the next loop\n ticks += this._getLoopDuration();\n }\n event.start(new TicksClass(this.context, ticks));\n }\n else if (event.startOffset < this._loopStart && event.startOffset >= offset) {\n event.loop = false;\n event.start(new TicksClass(this.context, ticks));\n }\n }\n else if (event.startOffset >= offset) {\n event.start(new TicksClass(this.context, ticks));\n }\n }\n get startOffset() {\n return this._startOffset;\n }\n set startOffset(offset) {\n this._startOffset = offset;\n this._forEach(event => {\n event.startOffset += this._startOffset;\n });\n }\n /**\n * Stop the part at the given time.\n * @param time When to stop the part.\n */\n stop(time) {\n const ticks = this.toTicks(time);\n this._state.cancel(ticks);\n this._state.setStateAtTime("stopped", ticks);\n this._forEach(event => {\n event.stop(time);\n });\n return this;\n }\n /**\n * Get/Set an Event\'s value at the given time.\n * If a value is passed in and no event exists at\n * the given time, one will be created with that value.\n * If two events are at the same time, the first one will\n * be returned.\n * @example\n * const part = new Tone.Part();\n * part.at("1m"); // returns the part at the first measure\n * part.at("2m", "C2"); // set the value at "2m" to C2.\n * // if an event didn\'t exist at that time, it will be created.\n * @param time The time of the event to get or set.\n * @param value If a value is passed in, the value of the event at the given time will be set to it.\n */\n at(time, value) {\n const timeInTicks = new TransportTimeClass(this.context, time).toTicks();\n const tickTime = new TicksClass(this.context, 1).toSeconds();\n const iterator = this._events.values();\n let result = iterator.next();\n while (!result.done) {\n const event = result.value;\n if (Math.abs(timeInTicks - event.startOffset) < tickTime) {\n if (isDefined(value)) {\n event.value = value;\n }\n return event;\n }\n result = iterator.next();\n }\n // if there was no event at that time, create one\n if (isDefined(value)) {\n this.add(time, value);\n // return the new event\n return this.at(time);\n }\n else {\n return null;\n }\n }\n add(time, value) {\n // extract the parameters\n if (time instanceof Object && Reflect.has(time, "time")) {\n value = time;\n time = value.time;\n }\n const ticks = this.toTicks(time);\n let event;\n if (value instanceof ToneEvent) {\n event = value;\n event.callback = this._tick.bind(this);\n }\n else {\n event = new ToneEvent({\n callback: this._tick.bind(this),\n context: this.context,\n value,\n });\n }\n // the start offset\n event.startOffset = ticks;\n // initialize the values\n event.set({\n humanize: this.humanize,\n loop: this.loop,\n loopEnd: this.loopEnd,\n loopStart: this.loopStart,\n playbackRate: this.playbackRate,\n probability: this.probability,\n });\n this._events.add(event);\n // start the note if it should be played right now\n this._restartEvent(event);\n return this;\n }\n /**\n * Restart the given event\n */\n _restartEvent(event) {\n this._state.forEach((stateEvent) => {\n if (stateEvent.state === "started") {\n this._startNote(event, stateEvent.time, stateEvent.offset);\n }\n else {\n // stop the note\n event.stop(new TicksClass(this.context, stateEvent.time));\n }\n });\n }\n remove(time, value) {\n // extract the parameters\n if (isObject(time) && time.hasOwnProperty("time")) {\n value = time;\n time = value.time;\n }\n time = this.toTicks(time);\n this._events.forEach(event => {\n if (event.startOffset === time) {\n if (isUndef(value) || (isDefined(value) && event.value === value)) {\n this._events.delete(event);\n event.dispose();\n }\n }\n });\n return this;\n }\n /**\n * Remove all of the notes from the group.\n */\n clear() {\n this._forEach(event => event.dispose());\n this._events.clear();\n return this;\n }\n /**\n * Cancel scheduled state change events: i.e. "start" and "stop".\n * @param after The time after which to cancel the scheduled events.\n */\n cancel(after) {\n this._forEach(event => event.cancel(after));\n this._state.cancel(this.toTicks(after));\n return this;\n }\n /**\n * Iterate over all of the events\n */\n _forEach(callback) {\n if (this._events) {\n this._events.forEach(event => {\n if (event instanceof Part_Part) {\n event._forEach(callback);\n }\n else {\n callback(event);\n }\n });\n }\n return this;\n }\n /**\n * Set the attribute of all of the events\n * @param attr the attribute to set\n * @param value The value to set it to\n */\n _setAll(attr, value) {\n this._forEach(event => {\n event[attr] = value;\n });\n }\n /**\n * Internal tick method\n * @param time The time of the event in seconds\n */\n _tick(time, value) {\n if (!this.mute) {\n this.callback(time, value);\n }\n }\n /**\n * Determine if the event should be currently looping\n * given the loop boundries of this Part.\n * @param event The event to test\n */\n _testLoopBoundries(event) {\n if (this._loop && (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd)) {\n event.cancel(0);\n }\n else if (event.state === "stopped") {\n // reschedule it if it\'s stopped\n this._restartEvent(event);\n }\n }\n get probability() {\n return this._probability;\n }\n set probability(prob) {\n this._probability = prob;\n this._setAll("probability", prob);\n }\n get humanize() {\n return this._humanize;\n }\n set humanize(variation) {\n this._humanize = variation;\n this._setAll("humanize", variation);\n }\n /**\n * If the part should loop or not\n * between Part.loopStart and\n * Part.loopEnd. If set to true,\n * the part will loop indefinitely,\n * if set to a number greater than 1\n * it will play a specific number of\n * times, if set to false, 0 or 1, the\n * part will only play once.\n * @example\n * const part = new Tone.Part();\n * // loop the part 8 times\n * part.loop = 8;\n */\n get loop() {\n return this._loop;\n }\n set loop(loop) {\n this._loop = loop;\n this._forEach(event => {\n event.loopStart = this.loopStart;\n event.loopEnd = this.loopEnd;\n event.loop = loop;\n this._testLoopBoundries(event);\n });\n }\n /**\n * The loopEnd point determines when it will\n * loop if Part.loop is true.\n */\n get loopEnd() {\n return new TicksClass(this.context, this._loopEnd).toSeconds();\n }\n set loopEnd(loopEnd) {\n this._loopEnd = this.toTicks(loopEnd);\n if (this._loop) {\n this._forEach(event => {\n event.loopEnd = loopEnd;\n this._testLoopBoundries(event);\n });\n }\n }\n /**\n * The loopStart point determines when it will\n * loop if Part.loop is true.\n */\n get loopStart() {\n return new TicksClass(this.context, this._loopStart).toSeconds();\n }\n set loopStart(loopStart) {\n this._loopStart = this.toTicks(loopStart);\n if (this._loop) {\n this._forEach(event => {\n event.loopStart = this.loopStart;\n this._testLoopBoundries(event);\n });\n }\n }\n /**\n * The playback rate of the part\n */\n get playbackRate() {\n return this._playbackRate;\n }\n set playbackRate(rate) {\n this._playbackRate = rate;\n this._setAll("playbackRate", rate);\n }\n /**\n * The number of scheduled notes in the part.\n */\n get length() {\n return this._events.size;\n }\n dispose() {\n super.dispose();\n this.clear();\n return this;\n }\n}\n//# sourceMappingURL=Part.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/PatternGenerator.js\n\n\n/**\n * Start at the first value and go up to the last\n */\nfunction* upPatternGen(values) {\n let index = 0;\n while (index < values.length) {\n index = clampToArraySize(index, values);\n yield values[index];\n index++;\n }\n}\n/**\n * Start at the last value and go down to 0\n */\nfunction* downPatternGen(values) {\n let index = values.length - 1;\n while (index >= 0) {\n index = clampToArraySize(index, values);\n yield values[index];\n index--;\n }\n}\n/**\n * Infinitely yield the generator\n */\nfunction* infiniteGen(values, gen) {\n while (true) {\n yield* gen(values);\n }\n}\n/**\n * Make sure that the index is in the given range\n */\nfunction clampToArraySize(index, values) {\n return clamp(index, 0, values.length - 1);\n}\n/**\n * Alternate between two generators\n */\nfunction* alternatingGenerator(values, directionUp) {\n let index = directionUp ? 0 : values.length - 1;\n while (true) {\n index = clampToArraySize(index, values);\n yield values[index];\n if (directionUp) {\n index++;\n if (index >= values.length - 1) {\n directionUp = false;\n }\n }\n else {\n index--;\n if (index <= 0) {\n directionUp = true;\n }\n }\n }\n}\n/**\n * Starting from the bottom move up 2, down 1\n */\nfunction* jumpUp(values) {\n let index = 0;\n let stepIndex = 0;\n while (index < values.length) {\n index = clampToArraySize(index, values);\n yield values[index];\n stepIndex++;\n index += (stepIndex % 2 ? 2 : -1);\n }\n}\n/**\n * Starting from the top move down 2, up 1\n */\nfunction* jumpDown(values) {\n let index = values.length - 1;\n let stepIndex = 0;\n while (index >= 0) {\n index = clampToArraySize(index, values);\n yield values[index];\n stepIndex++;\n index += (stepIndex % 2 ? -2 : 1);\n }\n}\n/**\n * Choose a random index each time\n */\nfunction* randomGen(values) {\n while (true) {\n const randomIndex = Math.floor(Math.random() * values.length);\n yield values[randomIndex];\n }\n}\n/**\n * Randomly go through all of the values once before choosing a new random order\n */\nfunction* randomOnce(values) {\n // create an array of indices\n const copy = [];\n for (let i = 0; i < values.length; i++) {\n copy.push(i);\n }\n while (copy.length > 0) {\n // random choose an index, and then remove it so it\'s not chosen again\n const randVal = copy.splice(Math.floor(copy.length * Math.random()), 1);\n const index = clampToArraySize(randVal[0], values);\n yield values[index];\n }\n}\n/**\n * Randomly choose to walk up or down 1 index in the values array\n */\nfunction* randomWalk(values) {\n // randomly choose a starting index in the values array\n let index = Math.floor(Math.random() * values.length);\n while (true) {\n if (index === 0) {\n index++; // at bottom of array, so force upward step\n }\n else if (index === values.length - 1) {\n index--; // at top of array, so force downward step\n }\n else if (Math.random() < 0.5) { // else choose random downward or upward step\n index--;\n }\n else {\n index++;\n }\n yield values[index];\n }\n}\n/**\n * PatternGenerator returns a generator which will iterate over the given array\n * of values and yield the items according to the passed in pattern\n * @param values An array of values to iterate over\n * @param pattern The name of the pattern use when iterating over\n * @param index Where to start in the offset of the values array\n */\nfunction* PatternGenerator_PatternGenerator(values, pattern = "up", index = 0) {\n // safeguards\n assert(values.length > 0, "The array must have more than one value in it");\n switch (pattern) {\n case "up":\n yield* infiniteGen(values, upPatternGen);\n case "down":\n yield* infiniteGen(values, downPatternGen);\n case "upDown":\n yield* alternatingGenerator(values, true);\n case "downUp":\n yield* alternatingGenerator(values, false);\n case "alternateUp":\n yield* infiniteGen(values, jumpUp);\n case "alternateDown":\n yield* infiniteGen(values, jumpDown);\n case "random":\n yield* randomGen(values);\n case "randomOnce":\n yield* infiniteGen(values, randomOnce);\n case "randomWalk":\n yield* randomWalk(values);\n }\n}\n//# sourceMappingURL=PatternGenerator.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Pattern.js\n\n\n\n\n/**\n * Pattern arpeggiates between the given notes\n * in a number of patterns.\n * @example\n * const pattern = new Tone.Pattern((time, note) => {\n * \t// the order of the notes passed in depends on the pattern\n * }, ["C2", "D4", "E5", "A6"], "upDown");\n * @category Event\n */\nclass Pattern extends (/* unused pure expression or super */ null && (Loop)) {\n constructor() {\n super(optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]));\n this.name = "Pattern";\n const options = optionsFromArguments(Pattern.getDefaults(), arguments, ["callback", "values", "pattern"]);\n this.callback = options.callback;\n this._values = options.values;\n this._pattern = PatternGenerator(options.values, options.pattern);\n this._type = options.pattern;\n }\n static getDefaults() {\n return Object.assign(Loop.getDefaults(), {\n pattern: "up",\n values: [],\n callback: noOp,\n });\n }\n /**\n * Internal function called when the notes should be called\n */\n _tick(time) {\n const value = this._pattern.next();\n this._value = value.value;\n this.callback(time, this._value);\n }\n /**\n * The array of events.\n */\n get values() {\n return this._values;\n }\n set values(val) {\n this._values = val;\n // reset the pattern\n this.pattern = this._type;\n }\n /**\n * The current value of the pattern.\n */\n get value() {\n return this._value;\n }\n /**\n * The pattern type. See Tone.CtrlPattern for the full list of patterns.\n */\n get pattern() {\n return this._type;\n }\n set pattern(pattern) {\n this._type = pattern;\n this._pattern = PatternGenerator(this._values, this._type);\n }\n}\n//# sourceMappingURL=Pattern.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/Sequence.js\n\n\n\n\n\n/**\n * A sequence is an alternate notation of a part. Instead\n * of passing in an array of [time, event] pairs, pass\n * in an array of events which will be spaced at the\n * given subdivision. Sub-arrays will subdivide that beat\n * by the number of items are in the array.\n * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/)\n * @example\n * const synth = new Tone.Synth().toDestination();\n * const seq = new Tone.Sequence((time, note) => {\n * \tsynth.triggerAttackRelease(note, 0.1, time);\n * \t// subdivisions are given as subarrays\n * }, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]]).start(0);\n * Tone.Transport.start();\n * @category Event\n */\nclass Sequence extends (/* unused pure expression or super */ null && (ToneEvent)) {\n constructor() {\n super(optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]));\n this.name = "Sequence";\n /**\n * The object responsible for scheduling all of the events\n */\n this._part = new Part({\n callback: this._seqCallback.bind(this),\n context: this.context,\n });\n /**\n * private reference to all of the sequence proxies\n */\n this._events = [];\n /**\n * The proxied array\n */\n this._eventsArray = [];\n const options = optionsFromArguments(Sequence.getDefaults(), arguments, ["callback", "events", "subdivision"]);\n this._subdivision = this.toTicks(options.subdivision);\n this.events = options.events;\n // set all of the values\n this.loop = options.loop;\n this.loopStart = options.loopStart;\n this.loopEnd = options.loopEnd;\n this.playbackRate = options.playbackRate;\n this.probability = options.probability;\n this.humanize = options.humanize;\n this.mute = options.mute;\n this.playbackRate = options.playbackRate;\n }\n static getDefaults() {\n return Object.assign(omitFromObject(ToneEvent.getDefaults(), ["value"]), {\n events: [],\n loop: true,\n loopEnd: 0,\n loopStart: 0,\n subdivision: "8n",\n });\n }\n /**\n * The internal callback for when an event is invoked\n */\n _seqCallback(time, value) {\n if (value !== null) {\n this.callback(time, value);\n }\n }\n /**\n * The sequence\n */\n get events() {\n return this._events;\n }\n set events(s) {\n this.clear();\n this._eventsArray = s;\n this._events = this._createSequence(this._eventsArray);\n this._eventsUpdated();\n }\n /**\n * Start the part at the given time.\n * @param time When to start the part.\n * @param offset The offset index to start at\n */\n start(time, offset) {\n this._part.start(time, offset ? this._indexTime(offset) : offset);\n return this;\n }\n /**\n * Stop the part at the given time.\n * @param time When to stop the part.\n */\n stop(time) {\n this._part.stop(time);\n return this;\n }\n /**\n * The subdivision of the sequence. This can only be\n * set in the constructor. The subdivision is the\n * interval between successive steps.\n */\n get subdivision() {\n return new TicksClass(this.context, this._subdivision).toSeconds();\n }\n /**\n * Create a sequence proxy which can be monitored to create subsequences\n */\n _createSequence(array) {\n return new Proxy(array, {\n get: (target, property) => {\n // property is index in this case\n return target[property];\n },\n set: (target, property, value) => {\n if (isString(property) && isFinite(parseInt(property, 10))) {\n if (isArray(value)) {\n target[property] = this._createSequence(value);\n }\n else {\n target[property] = value;\n }\n }\n else {\n target[property] = value;\n }\n this._eventsUpdated();\n // return true to accept the changes\n return true;\n },\n });\n }\n /**\n * When the sequence has changed, all of the events need to be recreated\n */\n _eventsUpdated() {\n this._part.clear();\n this._rescheduleSequence(this._eventsArray, this._subdivision, this.startOffset);\n // update the loopEnd\n this.loopEnd = this.loopEnd;\n }\n /**\n * reschedule all of the events that need to be rescheduled\n */\n _rescheduleSequence(sequence, subdivision, startOffset) {\n sequence.forEach((value, index) => {\n const eventOffset = index * (subdivision) + startOffset;\n if (isArray(value)) {\n this._rescheduleSequence(value, subdivision / value.length, eventOffset);\n }\n else {\n const startTime = new TicksClass(this.context, eventOffset, "i").toSeconds();\n this._part.add(startTime, value);\n }\n });\n }\n /**\n * Get the time of the index given the Sequence\'s subdivision\n * @param index\n * @return The time of that index\n */\n _indexTime(index) {\n return new TicksClass(this.context, index * (this._subdivision) + this.startOffset).toSeconds();\n }\n /**\n * Clear all of the events\n */\n clear() {\n this._part.clear();\n return this;\n }\n dispose() {\n super.dispose();\n this._part.dispose();\n return this;\n }\n //-------------------------------------\n // PROXY CALLS\n //-------------------------------------\n get loop() {\n return this._part.loop;\n }\n set loop(l) {\n this._part.loop = l;\n }\n /**\n * The index at which the sequence should start looping\n */\n get loopStart() {\n return this._loopStart;\n }\n set loopStart(index) {\n this._loopStart = index;\n this._part.loopStart = this._indexTime(index);\n }\n /**\n * The index at which the sequence should end looping\n */\n get loopEnd() {\n return this._loopEnd;\n }\n set loopEnd(index) {\n this._loopEnd = index;\n if (index === 0) {\n this._part.loopEnd = this._indexTime(this._eventsArray.length);\n }\n else {\n this._part.loopEnd = this._indexTime(index);\n }\n }\n get startOffset() {\n return this._part.startOffset;\n }\n set startOffset(start) {\n this._part.startOffset = start;\n }\n get playbackRate() {\n return this._part.playbackRate;\n }\n set playbackRate(rate) {\n this._part.playbackRate = rate;\n }\n get probability() {\n return this._part.probability;\n }\n set probability(prob) {\n this._part.probability = prob;\n }\n get progress() {\n return this._part.progress;\n }\n get humanize() {\n return this._part.humanize;\n }\n set humanize(variation) {\n this._part.humanize = variation;\n }\n /**\n * The number of scheduled events\n */\n get length() {\n return this._part.length;\n }\n}\n//# sourceMappingURL=Sequence.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/event/index.js\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/CrossFade.js\n\n\n\n\n\n\n/**\n * Tone.Crossfade provides equal power fading between two inputs.\n * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading).\n * ```\n * +---------+\n * +> input a +>--+\n * +-----------+ +---------------------+ | | |\n * | 1s signal +>--\x3e stereoPannerNode L +>----\x3e gain | |\n * +-----------+ | | +---------+ |\n * +-> pan R +>-+ | +--------+\n * | +---------------------+ | +---\x3e output +>\n * +------+ | | +---------+ | +--------+\n * | fade +>----+ | +> input b +>--+\n * +------+ | | |\n * +--\x3e gain |\n * +---------+\n * ```\n * @example\n * const crossFade = new Tone.CrossFade().toDestination();\n * // connect two inputs Tone.to a/b\n * const inputA = new Tone.Oscillator(440, "square").connect(crossFade.a).start();\n * const inputB = new Tone.Oscillator(440, "sine").connect(crossFade.b).start();\n * // use the fade to control the mix between the two\n * crossFade.fade.value = 0.5;\n * @category Component\n */\nclass CrossFade_CrossFade extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(CrossFade_CrossFade.getDefaults(), arguments, ["fade"])));\n this.name = "CrossFade";\n /**\n * The crossfading is done by a StereoPannerNode\n */\n this._panner = this.context.createStereoPanner();\n /**\n * Split the output of the panner node into two values used to control the gains.\n */\n this._split = this.context.createChannelSplitter(2);\n /**\n * Convert the fade value into an audio range value so it can be connected\n * to the panner.pan AudioParam\n */\n this._g2a = new GainToAudio({ context: this.context });\n /**\n * The input which is at full level when fade = 0\n */\n this.a = new Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The input which is at full level when fade = 1\n */\n this.b = new Gain({\n context: this.context,\n gain: 0,\n });\n /**\n * The output is a mix between `a` and `b` at the ratio of `fade`\n */\n this.output = new Gain({ context: this.context });\n this._internalChannels = [this.a, this.b];\n const options = optionsFromArguments(CrossFade_CrossFade.getDefaults(), arguments, ["fade"]);\n this.fade = new Signal({\n context: this.context,\n units: "normalRange",\n value: options.fade,\n });\n readOnly(this, "fade");\n this.context.getConstant(1).connect(this._panner);\n this._panner.connect(this._split);\n // this is necessary for standardized-audio-context\n // doesn\'t make any difference for the native AudioContext\n // https://github.com/chrisguttandin/standardized-audio-context/issues/647\n this._panner.channelCount = 1;\n this._panner.channelCountMode = "explicit";\n connect(this._split, this.a.gain, 0);\n connect(this._split, this.b.gain, 1);\n this.fade.chain(this._g2a, this._panner.pan);\n this.a.connect(this.output);\n this.b.connect(this.output);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n fade: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.a.dispose();\n this.b.dispose();\n this.output.dispose();\n this.fade.dispose();\n this._g2a.dispose();\n this._panner.disconnect();\n this._split.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=CrossFade.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Effect.js\n\n\n\n\n/**\n * Effect is the base class for effects. Connect the effect between\n * the effectSend and effectReturn GainNodes, then control the amount of\n * effect which goes to the output using the wet control.\n */\nclass Effect_Effect extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "Effect";\n /**\n * the drywet knob to control the amount of effect\n */\n this._dryWet = new CrossFade({ context: this.context });\n /**\n * The wet control is how much of the effected\n * will pass through to the output. 1 = 100% effected\n * signal, 0 = 100% dry signal.\n */\n this.wet = this._dryWet.fade;\n /**\n * connect the effectSend to the input of hte effect\n */\n this.effectSend = new Gain({ context: this.context });\n /**\n * connect the output of the effect to the effectReturn\n */\n this.effectReturn = new Gain({ context: this.context });\n /**\n * The effect input node\n */\n this.input = new Gain({ context: this.context });\n /**\n * The effect output\n */\n this.output = this._dryWet;\n // connections\n this.input.fan(this._dryWet.a, this.effectSend);\n this.effectReturn.connect(this._dryWet.b);\n this.wet.setValueAtTime(options.wet, 0);\n this._internalChannels = [this.effectReturn, this.effectSend];\n readOnly(this, "wet");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n wet: 1,\n });\n }\n /**\n * chains the effect in between the effectSend and effectReturn\n */\n connectEffect(effect) {\n // add it to the internal channels\n this._internalChannels.push(effect);\n this.effectSend.chain(effect, this.effectReturn);\n return this;\n }\n dispose() {\n super.dispose();\n this._dryWet.dispose();\n this.effectSend.dispose();\n this.effectReturn.dispose();\n this.wet.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Effect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/LFOEffect.js\n\n\n\n/**\n * Base class for LFO-based effects.\n */\nclass LFOEffect_LFOEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "LFOEffect";\n this._lfo = new LFO({\n context: this.context,\n frequency: options.frequency,\n amplitude: options.depth,\n });\n this.depth = this._lfo.amplitude;\n this.frequency = this._lfo.frequency;\n this.type = options.type;\n readOnly(this, ["frequency", "depth"]);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n frequency: 1,\n type: "sine",\n depth: 1,\n });\n }\n /**\n * Start the effect.\n */\n start(time) {\n this._lfo.start(time);\n return this;\n }\n /**\n * Stop the lfo\n */\n stop(time) {\n this._lfo.stop(time);\n return this;\n }\n /**\n * Sync the filter to the transport. See [[LFO.sync]]\n */\n sync() {\n this._lfo.sync();\n return this;\n }\n /**\n * Unsync the filter from the transport.\n */\n unsync() {\n this._lfo.unsync();\n return this;\n }\n /**\n * The type of the LFO\'s oscillator: See [[Oscillator.type]]\n * @example\n * const autoFilter = new Tone.AutoFilter().start().toDestination();\n * const noise = new Tone.Noise().start().connect(autoFilter);\n * autoFilter.type = "square";\n */\n get type() {\n return this._lfo.type;\n }\n set type(type) {\n this._lfo.type = type;\n }\n dispose() {\n super.dispose();\n this._lfo.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=LFOEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoFilter.js\n\n\n\n/**\n * AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency.\n * Setting the LFO rate and depth allows for control over the filter modulation rate\n * and depth.\n *\n * @example\n * // create an autofilter and start it\'s LFO\n * const autoFilter = new Tone.AutoFilter("4n").toDestination().start();\n * // route an oscillator through the filter and start it\n * const oscillator = new Tone.Oscillator().connect(autoFilter).start();\n * @category Effect\n */\nclass AutoFilter extends (/* unused pure expression or super */ null && (LFOEffect)) {\n constructor() {\n super(optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]));\n this.name = "AutoFilter";\n const options = optionsFromArguments(AutoFilter.getDefaults(), arguments, ["frequency", "baseFrequency", "octaves"]);\n this.filter = new Filter(Object.assign(options.filter, {\n context: this.context,\n }));\n // connections\n this.connectEffect(this.filter);\n this._lfo.connect(this.filter.frequency);\n this.octaves = options.octaves;\n this.baseFrequency = options.baseFrequency;\n }\n static getDefaults() {\n return Object.assign(LFOEffect.getDefaults(), {\n baseFrequency: 200,\n octaves: 2.6,\n filter: {\n type: "lowpass",\n rolloff: -12,\n Q: 1,\n }\n });\n }\n /**\n * The minimum value of the filter\'s cutoff frequency.\n */\n get baseFrequency() {\n return this._lfo.min;\n }\n set baseFrequency(freq) {\n this._lfo.min = this.toFrequency(freq);\n // and set the max\n this.octaves = this._octaves;\n }\n /**\n * The maximum value of the filter\'s cutoff frequency.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(oct) {\n this._octaves = oct;\n this._lfo.max = this._lfo.min * Math.pow(2, oct);\n }\n dispose() {\n super.dispose();\n this.filter.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoFilter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Panner.js\n\n\n\n\n/**\n * Panner is an equal power Left/Right Panner. It is a wrapper around the StereoPannerNode.\n * @example\n * return Tone.Offline(() => {\n * // move the input signal from right to left\n * \tconst panner = new Tone.Panner(1).toDestination();\n * \tpanner.pan.rampTo(-1, 0.5);\n * \tconst osc = new Tone.Oscillator(100).connect(panner).start();\n * }, 0.5, 2);\n * @category Component\n */\nclass Panner_Panner extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Object.assign(Defaults_optionsFromArguments(Panner_Panner.getDefaults(), arguments, ["pan"])));\n this.name = "Panner";\n /**\n * the panner node\n */\n this._panner = this.context.createStereoPanner();\n this.input = this._panner;\n this.output = this._panner;\n const options = Defaults_optionsFromArguments(Panner_Panner.getDefaults(), arguments, ["pan"]);\n this.pan = new Param_Param({\n context: this.context,\n param: this._panner.pan,\n value: options.pan,\n minValue: -1,\n maxValue: 1,\n });\n // this is necessary for standardized-audio-context\n // doesn\'t make any difference for the native AudioContext\n // https://github.com/chrisguttandin/standardized-audio-context/issues/647\n this._panner.channelCount = options.channelCount;\n this._panner.channelCountMode = "explicit";\n // initial value\n Interface_readOnly(this, "pan");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n pan: 0,\n channelCount: 1,\n });\n }\n dispose() {\n super.dispose();\n this._panner.disconnect();\n this.pan.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Panner.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoPanner.js\n\n\n\n/**\n * AutoPanner is a [[Panner]] with an [[LFO]] connected to the pan amount.\n * [Related Reading](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/).\n *\n * @example\n * // create an autopanner and start it\n * const autoPanner = new Tone.AutoPanner("4n").toDestination().start();\n * // route an oscillator through the panner and start it\n * const oscillator = new Tone.Oscillator().connect(autoPanner).start();\n * @category Effect\n */\nclass AutoPanner extends (/* unused pure expression or super */ null && (LFOEffect)) {\n constructor() {\n super(optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]));\n this.name = "AutoPanner";\n const options = optionsFromArguments(AutoPanner.getDefaults(), arguments, ["frequency"]);\n this._panner = new Panner({\n context: this.context,\n channelCount: options.channelCount\n });\n // connections\n this.connectEffect(this._panner);\n this._lfo.connect(this._panner.pan);\n this._lfo.min = -1;\n this._lfo.max = 1;\n }\n static getDefaults() {\n return Object.assign(LFOEffect.getDefaults(), {\n channelCount: 1\n });\n }\n dispose() {\n super.dispose();\n this._panner.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoPanner.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Follower.js\n\n\n\n\n/**\n * Follower is a simple envelope follower.\n * It\'s implemented by applying a lowpass filter to the absolute value of the incoming signal.\n * ```\n * +-----+ +---------------+\n * Input +--\x3e Abs +----\x3e OnePoleFilter +--\x3e Output\n * +-----+ +---------------+\n * ```\n * @category Component\n */\nclass Follower_Follower extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Follower_Follower.getDefaults(), arguments, ["smoothing"]));\n this.name = "Follower";\n const options = optionsFromArguments(Follower_Follower.getDefaults(), arguments, ["smoothing"]);\n this._abs = this.input = new Abs({ context: this.context });\n this._lowpass = this.output = new OnePoleFilter({\n context: this.context,\n frequency: 1 / this.toSeconds(options.smoothing),\n type: "lowpass"\n });\n this._abs.connect(this._lowpass);\n this._smoothing = options.smoothing;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n smoothing: 0.05\n });\n }\n /**\n * The amount of time it takes a value change to arrive at the updated value.\n */\n get smoothing() {\n return this._smoothing;\n }\n set smoothing(smoothing) {\n this._smoothing = smoothing;\n this._lowpass.frequency = 1 / this.toSeconds(this.smoothing);\n }\n dispose() {\n super.dispose();\n this._abs.dispose();\n this._lowpass.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Follower.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/AutoWah.js\n\n\n\n\n\n\n\n\n/**\n * AutoWah connects a [[Follower]] to a [[Filter]].\n * The frequency of the filter, follows the input amplitude curve.\n * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna).\n *\n * @example\n * const autoWah = new Tone.AutoWah(50, 6, -30).toDestination();\n * // initialize the synth and connect to autowah\n * const synth = new Tone.Synth().connect(autoWah);\n * // Q value influences the effect of the wah - default is 2\n * autoWah.Q.value = 6;\n * // more audible on higher notes\n * synth.triggerAttackRelease("C4", "8n");\n * @category Effect\n */\nclass AutoWah extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]));\n this.name = "AutoWah";\n const options = optionsFromArguments(AutoWah.getDefaults(), arguments, ["baseFrequency", "octaves", "sensitivity"]);\n this._follower = new Follower({\n context: this.context,\n smoothing: options.follower,\n });\n this._sweepRange = new ScaleExp({\n context: this.context,\n min: 0,\n max: 1,\n exponent: 0.5,\n });\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._octaves = options.octaves;\n this._inputBoost = new Gain({ context: this.context });\n this._bandpass = new Filter({\n context: this.context,\n rolloff: -48,\n frequency: 0,\n Q: options.Q,\n });\n this._peaking = new Filter({\n context: this.context,\n type: "peaking"\n });\n this._peaking.gain.value = options.gain;\n this.gain = this._peaking.gain;\n this.Q = this._bandpass.Q;\n // the control signal path\n this.effectSend.chain(this._inputBoost, this._follower, this._sweepRange);\n this._sweepRange.connect(this._bandpass.frequency);\n this._sweepRange.connect(this._peaking.frequency);\n // the filtered path\n this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);\n // set the initial value\n this._setSweepRange();\n this.sensitivity = options.sensitivity;\n readOnly(this, ["gain", "Q"]);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n baseFrequency: 100,\n octaves: 6,\n sensitivity: 0,\n Q: 2,\n gain: 2,\n follower: 0.2,\n });\n }\n /**\n * The number of octaves that the filter will sweep above the baseFrequency.\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n this._setSweepRange();\n }\n /**\n * The follower\'s smoothing time\n */\n get follower() {\n return this._follower.smoothing;\n }\n set follower(follower) {\n this._follower.smoothing = follower;\n }\n /**\n * The base frequency from which the sweep will start from.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(baseFreq) {\n this._baseFrequency = this.toFrequency(baseFreq);\n this._setSweepRange();\n }\n /**\n * The sensitivity to control how responsive to the input signal the filter is.\n */\n get sensitivity() {\n return gainToDb(1 / this._inputBoost.gain.value);\n }\n set sensitivity(sensitivity) {\n this._inputBoost.gain.value = 1 / dbToGain(sensitivity);\n }\n /**\n * sets the sweep range of the scaler\n */\n _setSweepRange() {\n this._sweepRange.min = this._baseFrequency;\n this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);\n }\n dispose() {\n super.dispose();\n this._follower.dispose();\n this._sweepRange.dispose();\n this._bandpass.dispose();\n this._peaking.dispose();\n this._inputBoost.dispose();\n return this;\n }\n}\n//# sourceMappingURL=AutoWah.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/BitCrusher.worklet.js\n\n\nconst BitCrusher_worklet_workletName = "bit-crusher";\nconst bitCrusherWorklet = /* javascript */ `\n\tclass BitCrusherWorklet extends SingleIOProcessor {\n\n\t\tstatic get parameterDescriptors() {\n\t\t\treturn [{\n\t\t\t\tname: "bits",\n\t\t\t\tdefaultValue: 12,\n\t\t\t\tminValue: 1,\n\t\t\t\tmaxValue: 16,\n\t\t\t\tautomationRate: \'k-rate\'\n\t\t\t}];\n\t\t}\n\n\t\tgenerate(input, _channel, parameters) {\n\t\t\tconst step = Math.pow(0.5, parameters.bits - 1);\n\t\t\tconst val = step * Math.floor(input / step + 0.5);\n\t\t\treturn val;\n\t\t}\n\t}\n`;\nregisterProcessor(BitCrusher_worklet_workletName, bitCrusherWorklet);\n//# sourceMappingURL=BitCrusher.worklet.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/BitCrusher.js\n\n\n\n\n\n\n\n/**\n * BitCrusher down-samples the incoming signal to a different bit depth.\n * Lowering the bit depth of the signal creates distortion. Read more about BitCrushing\n * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher).\n * @example\n * // initialize crusher and route a synth through it\n * const crusher = new Tone.BitCrusher(4).toDestination();\n * const synth = new Tone.Synth().connect(crusher);\n * synth.triggerAttackRelease("C2", 2);\n *\n * @category Effect\n */\nclass BitCrusher extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]));\n this.name = "BitCrusher";\n const options = optionsFromArguments(BitCrusher.getDefaults(), arguments, ["bits"]);\n this._bitCrusherWorklet = new BitCrusherWorklet({\n context: this.context,\n bits: options.bits,\n });\n // connect it up\n this.connectEffect(this._bitCrusherWorklet);\n this.bits = this._bitCrusherWorklet.bits;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n bits: 4,\n });\n }\n dispose() {\n super.dispose();\n this._bitCrusherWorklet.dispose();\n return this;\n }\n}\n/**\n * Internal class which creates an AudioWorklet to do the bit crushing\n */\nclass BitCrusherWorklet extends (/* unused pure expression or super */ null && (ToneAudioWorklet)) {\n constructor() {\n super(optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments));\n this.name = "BitCrusherWorklet";\n const options = optionsFromArguments(BitCrusherWorklet.getDefaults(), arguments);\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n this.bits = new Param({\n context: this.context,\n value: options.bits,\n units: "positive",\n minValue: 1,\n maxValue: 16,\n param: this._dummyParam,\n swappable: true,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioWorklet.getDefaults(), {\n bits: 12,\n });\n }\n _audioWorkletName() {\n return workletName;\n }\n onReady(node) {\n connectSeries(this.input, node, this.output);\n const bits = node.parameters.get("bits");\n this.bits.setParam(bits);\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.bits.dispose();\n return this;\n }\n}\n//# sourceMappingURL=BitCrusher.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Chebyshev.js\n\n\n\n/**\n * Chebyshev is a waveshaper which is good\n * for making different types of distortion sounds.\n * Note that odd orders sound very different from even ones,\n * and order = 1 is no change.\n * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php).\n * @example\n * // create a new cheby\n * const cheby = new Tone.Chebyshev(50).toDestination();\n * // create a monosynth connected to our cheby\n * const synth = new Tone.MonoSynth().connect(cheby);\n * synth.triggerAttackRelease("C2", 0.4);\n * @category Effect\n */\nclass Chebyshev extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]));\n this.name = "Chebyshev";\n const options = optionsFromArguments(Chebyshev.getDefaults(), arguments, ["order"]);\n this._shaper = new WaveShaper({\n context: this.context,\n length: 4096\n });\n this._order = options.order;\n this.connectEffect(this._shaper);\n this.order = options.order;\n this.oversample = options.oversample;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n order: 1,\n oversample: "none"\n });\n }\n /**\n * get the coefficient for that degree\n * @param x the x value\n * @param degree\n * @param memo memoize the computed value. this speeds up computation greatly.\n */\n _getCoefficient(x, degree, memo) {\n if (memo.has(degree)) {\n return memo.get(degree);\n }\n else if (degree === 0) {\n memo.set(degree, 0);\n }\n else if (degree === 1) {\n memo.set(degree, x);\n }\n else {\n memo.set(degree, 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo));\n }\n return memo.get(degree);\n }\n /**\n * The order of the Chebyshev polynomial which creates the equation which is applied to the incoming\n * signal through a Tone.WaveShaper. The equations are in the form:\n * ```\n * order 2: 2x^2 + 1\n * order 3: 4x^3 + 3x\n * ```\n * @min 1\n * @max 100\n */\n get order() {\n return this._order;\n }\n set order(order) {\n this._order = order;\n this._shaper.setMap((x => {\n return this._getCoefficient(x, order, new Map());\n }));\n }\n /**\n * The oversampling of the effect. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n this._shaper.oversample = oversampling;\n }\n dispose() {\n super.dispose();\n this._shaper.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Chebyshev.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Split.js\n\n\n/**\n * Split splits an incoming signal into the number of given channels.\n *\n * @example\n * const split = new Tone.Split();\n * // stereoSignal.connect(split);\n * @category Component\n */\nclass Split_Split extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Split_Split.getDefaults(), arguments, ["channels"]));\n this.name = "Split";\n const options = optionsFromArguments(Split_Split.getDefaults(), arguments, ["channels"]);\n this._splitter = this.input = this.output = this.context.createChannelSplitter(options.channels);\n this._internalChannels = [this._splitter];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n channels: 2,\n });\n }\n dispose() {\n super.dispose();\n this._splitter.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Split.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Merge.js\n\n\n/**\n * Merge brings multiple mono input channels into a single multichannel output channel.\n *\n * @example\n * const merge = new Tone.Merge().toDestination();\n * // routing a sine tone in the left channel\n * const osc = new Tone.Oscillator().connect(merge, 0, 0).start();\n * // and noise in the right channel\n * const noise = new Tone.Noise().connect(merge, 0, 1).start();;\n * @category Component\n */\nclass Merge_Merge extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Merge_Merge.getDefaults(), arguments, ["channels"]));\n this.name = "Merge";\n const options = optionsFromArguments(Merge_Merge.getDefaults(), arguments, ["channels"]);\n this._merger = this.output = this.input = this.context.createChannelMerger(options.channels);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n channels: 2,\n });\n }\n dispose() {\n super.dispose();\n this._merger.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Merge.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoEffect.js\n\n\n\n\n\n\n/**\n * Base class for Stereo effects.\n */\nclass StereoEffect_StereoEffect extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "StereoEffect";\n this.input = new Gain({ context: this.context });\n // force mono sources to be stereo\n this.input.channelCount = 2;\n this.input.channelCountMode = "explicit";\n this._dryWet = this.output = new CrossFade({\n context: this.context,\n fade: options.wet\n });\n this.wet = this._dryWet.fade;\n this._split = new Split({ context: this.context, channels: 2 });\n this._merge = new Merge({ context: this.context, channels: 2 });\n // connections\n this.input.connect(this._split);\n // dry wet connections\n this.input.connect(this._dryWet.a);\n this._merge.connect(this._dryWet.b);\n readOnly(this, ["wet"]);\n }\n /**\n * Connect the left part of the effect\n */\n connectEffectLeft(...nodes) {\n this._split.connect(nodes[0], 0, 0);\n connectSeries(...nodes);\n connect(nodes[nodes.length - 1], this._merge, 0, 0);\n }\n /**\n * Connect the right part of the effect\n */\n connectEffectRight(...nodes) {\n this._split.connect(nodes[0], 1, 0);\n connectSeries(...nodes);\n connect(nodes[nodes.length - 1], this._merge, 0, 1);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n wet: 1,\n });\n }\n dispose() {\n super.dispose();\n this._dryWet.dispose();\n this._split.dispose();\n this._merge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoFeedbackEffect.js\n\n\n\n\n\n\n/**\n * Base class for stereo feedback effects where the effectReturn is fed back into the same channel.\n */\nclass StereoFeedbackEffect_StereoFeedbackEffect extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor(options) {\n super(options);\n this.feedback = new Signal({\n context: this.context,\n value: options.feedback,\n units: "normalRange"\n });\n this._feedbackL = new Gain({ context: this.context });\n this._feedbackR = new Gain({ context: this.context });\n this._feedbackSplit = new Split({ context: this.context, channels: 2 });\n this._feedbackMerge = new Merge({ context: this.context, channels: 2 });\n this._merge.connect(this._feedbackSplit);\n this._feedbackMerge.connect(this._split);\n // the left output connected to the left input\n this._feedbackSplit.connect(this._feedbackL, 0, 0);\n this._feedbackL.connect(this._feedbackMerge, 0, 0);\n // the right output connected to the right input\n this._feedbackSplit.connect(this._feedbackR, 1, 0);\n this._feedbackR.connect(this._feedbackMerge, 0, 1);\n // the feedback control\n this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);\n readOnly(this, ["feedback"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n feedback: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.feedback.dispose();\n this._feedbackL.dispose();\n this._feedbackR.dispose();\n this._feedbackSplit.dispose();\n this._feedbackMerge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoFeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Chorus.js\n\n\n\n\n\n/**\n * Chorus is a stereo chorus effect composed of a left and right delay with an [[LFO]] applied to the delayTime of each channel.\n * When [[feedback]] is set to a value larger than 0, you also get Flanger-type effects.\n * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js).\n * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm).\n *\n * @example\n * const chorus = new Tone.Chorus(4, 2.5, 0.5).toDestination().start();\n * const synth = new Tone.PolySynth().connect(chorus);\n * synth.triggerAttackRelease(["C3", "E3", "G3"], "8n");\n *\n * @category Effect\n */\nclass Chorus extends (/* unused pure expression or super */ null && (StereoFeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]));\n this.name = "Chorus";\n const options = optionsFromArguments(Chorus.getDefaults(), arguments, ["frequency", "delayTime", "depth"]);\n this._depth = options.depth;\n this._delayTime = options.delayTime / 1000;\n this._lfoL = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n });\n this._lfoR = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n phase: 180\n });\n this._delayNodeL = new Delay({ context: this.context });\n this._delayNodeR = new Delay({ context: this.context });\n this.frequency = this._lfoL.frequency;\n readOnly(this, ["frequency"]);\n // have one LFO frequency control the other\n this._lfoL.frequency.connect(this._lfoR.frequency);\n // connections\n this.connectEffectLeft(this._delayNodeL);\n this.connectEffectRight(this._delayNodeR);\n // lfo setup\n this._lfoL.connect(this._delayNodeL.delayTime);\n this._lfoR.connect(this._delayNodeR.delayTime);\n // set the initial values\n this.depth = this._depth;\n this.type = options.type;\n this.spread = options.spread;\n }\n static getDefaults() {\n return Object.assign(StereoFeedbackEffect.getDefaults(), {\n frequency: 1.5,\n delayTime: 3.5,\n depth: 0.7,\n type: "sine",\n spread: 180,\n feedback: 0,\n wet: 0.5,\n });\n }\n /**\n * The depth of the effect. A depth of 1 makes the delayTime\n * modulate between 0 and 2*delayTime (centered around the delayTime).\n */\n get depth() {\n return this._depth;\n }\n set depth(depth) {\n this._depth = depth;\n const deviation = this._delayTime * depth;\n this._lfoL.min = Math.max(this._delayTime - deviation, 0);\n this._lfoL.max = this._delayTime + deviation;\n this._lfoR.min = Math.max(this._delayTime - deviation, 0);\n this._lfoR.max = this._delayTime + deviation;\n }\n /**\n * The delayTime in milliseconds of the chorus. A larger delayTime\n * will give a more pronounced effect. Nominal range a delayTime\n * is between 2 and 20ms.\n */\n get delayTime() {\n return this._delayTime * 1000;\n }\n set delayTime(delayTime) {\n this._delayTime = delayTime / 1000;\n this.depth = this._depth;\n }\n /**\n * The oscillator type of the LFO.\n */\n get type() {\n return this._lfoL.type;\n }\n set type(type) {\n this._lfoL.type = type;\n this._lfoR.type = type;\n }\n /**\n * Amount of stereo spread. When set to 0, both LFO\'s will be panned centrally.\n * When set to 180, LFO\'s will be panned hard left and right respectively.\n */\n get spread() {\n return this._lfoR.phase - this._lfoL.phase;\n }\n set spread(spread) {\n this._lfoL.phase = 90 - (spread / 2);\n this._lfoR.phase = (spread / 2) + 90;\n }\n /**\n * Start the effect.\n */\n start(time) {\n this._lfoL.start(time);\n this._lfoR.start(time);\n return this;\n }\n /**\n * Stop the lfo\n */\n stop(time) {\n this._lfoL.stop(time);\n this._lfoR.stop(time);\n return this;\n }\n /**\n * Sync the filter to the transport. See [[LFO.sync]]\n */\n sync() {\n this._lfoL.sync();\n this._lfoR.sync();\n return this;\n }\n /**\n * Unsync the filter from the transport.\n */\n unsync() {\n this._lfoL.unsync();\n this._lfoR.unsync();\n return this;\n }\n dispose() {\n super.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._delayNodeL.dispose();\n this._delayNodeR.dispose();\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Chorus.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Distortion.js\n\n\n\n/**\n * A simple distortion effect using Tone.WaveShaper.\n * Algorithm from [this stackoverflow answer](http://stackoverflow.com/a/22313408).\n *\n * @example\n * const dist = new Tone.Distortion(0.8).toDestination();\n * const fm = new Tone.FMSynth().connect(dist);\n * fm.triggerAttackRelease("A1", "8n");\n * @category Effect\n */\nclass Distortion extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]));\n this.name = "Distortion";\n const options = optionsFromArguments(Distortion.getDefaults(), arguments, ["distortion"]);\n this._shaper = new WaveShaper({\n context: this.context,\n length: 4096,\n });\n this._distortion = options.distortion;\n this.connectEffect(this._shaper);\n this.distortion = options.distortion;\n this.oversample = options.oversample;\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n distortion: 0.4,\n oversample: "none",\n });\n }\n /**\n * The amount of distortion. Nominal range is between 0 and 1.\n */\n get distortion() {\n return this._distortion;\n }\n set distortion(amount) {\n this._distortion = amount;\n const k = amount * 100;\n const deg = Math.PI / 180;\n this._shaper.setMap((x) => {\n if (Math.abs(x) < 0.001) {\n // should output 0 when input is 0\n return 0;\n }\n else {\n return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));\n }\n });\n }\n /**\n * The oversampling of the effect. Can either be "none", "2x" or "4x".\n */\n get oversample() {\n return this._shaper.oversample;\n }\n set oversample(oversampling) {\n this._shaper.oversample = oversampling;\n }\n dispose() {\n super.dispose();\n this._shaper.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Distortion.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FeedbackEffect.js\n\n\n\n/**\n * FeedbackEffect provides a loop between an audio source and its own output.\n * This is a base-class for feedback effects.\n */\nclass FeedbackEffect_FeedbackEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "FeedbackEffect";\n this._feedbackGain = new Gain({\n context: this.context,\n gain: options.feedback,\n units: "normalRange",\n });\n this.feedback = this._feedbackGain.gain;\n readOnly(this, "feedback");\n // the feedback loop\n this.effectReturn.chain(this._feedbackGain, this.effectSend);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n feedback: 0.125,\n });\n }\n dispose() {\n super.dispose();\n this._feedbackGain.dispose();\n this.feedback.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FeedbackDelay.js\n\n\n\n\n/**\n * FeedbackDelay is a DelayNode in which part of output signal is fed back into the delay.\n *\n * @param delayTime The delay applied to the incoming signal.\n * @param feedback The amount of the effected signal which is fed back through the delay.\n * @example\n * const feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toDestination();\n * const tom = new Tone.MembraneSynth({\n * \toctaves: 4,\n * \tpitchDecay: 0.1\n * }).connect(feedbackDelay);\n * tom.triggerAttackRelease("A2", "32n");\n * @category Effect\n */\nclass FeedbackDelay extends (/* unused pure expression or super */ null && (FeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]));\n this.name = "FeedbackDelay";\n const options = optionsFromArguments(FeedbackDelay.getDefaults(), arguments, ["delayTime", "feedback"]);\n this._delayNode = new Delay({\n context: this.context,\n delayTime: options.delayTime,\n maxDelay: options.maxDelay,\n });\n this.delayTime = this._delayNode.delayTime;\n // connect it up\n this.connectEffect(this._delayNode);\n readOnly(this, "delayTime");\n }\n static getDefaults() {\n return Object.assign(FeedbackEffect.getDefaults(), {\n delayTime: 0.25,\n maxDelay: 1,\n });\n }\n dispose() {\n super.dispose();\n this._delayNode.dispose();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FeedbackDelay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/PhaseShiftAllpass.js\n\n\n/**\n * PhaseShiftAllpass is an very efficient implementation of a Hilbert Transform\n * using two Allpass filter banks whose outputs have a phase difference of 90°.\n * Here the `offset90` phase is offset by +90° in relation to `output`.\n * Coefficients and structure was developed by Olli Niemitalo.\n * For more details see: http://yehar.com/blog/?p=368\n * @category Component\n */\nclass PhaseShiftAllpass_PhaseShiftAllpass extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor(options) {\n super(options);\n this.name = "PhaseShiftAllpass";\n this.input = new Gain({ context: this.context });\n /**\n * The phase shifted output\n */\n this.output = new Gain({ context: this.context });\n /**\n * The PhaseShifted allpass output\n */\n this.offset90 = new Gain({ context: this.context });\n const allpassBank1Values = [0.6923878, 0.9360654322959, 0.9882295226860, 0.9987488452737];\n const allpassBank2Values = [0.4021921162426, 0.8561710882420, 0.9722909545651, 0.9952884791278];\n this._bank0 = this._createAllPassFilterBank(allpassBank1Values);\n this._bank1 = this._createAllPassFilterBank(allpassBank2Values);\n this._oneSampleDelay = this.context.createIIRFilter([0.0, 1.0], [1.0, 0.0]);\n // connect Allpass filter banks\n connectSeries(this.input, ...this._bank0, this._oneSampleDelay, this.output);\n connectSeries(this.input, ...this._bank1, this.offset90);\n }\n /**\n * Create all of the IIR filters from an array of values using the coefficient calculation.\n */\n _createAllPassFilterBank(bankValues) {\n const nodes = bankValues.map(value => {\n const coefficients = [[value * value, 0, -1], [1, 0, -(value * value)]];\n return this.context.createIIRFilter(coefficients[0], coefficients[1]);\n });\n return nodes;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this.output.dispose();\n this.offset90.dispose();\n this._bank0.forEach(f => f.disconnect());\n this._bank1.forEach(f => f.disconnect());\n this._oneSampleDelay.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=PhaseShiftAllpass.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/FrequencyShifter.js\n\n\n\n\n\n\n\n\n\n/**\n * FrequencyShifter can be used to shift all frequencies of a signal by a fixed amount.\n * The amount can be changed at audio rate and the effect is applied in real time.\n * The frequency shifting is implemented with a technique called single side band modulation using a ring modulator.\n * Note: Contrary to pitch shifting, all frequencies are shifted by the same amount,\n * destroying the harmonic relationship between them. This leads to the classic ring modulator timbre distortion.\n * The algorithm will produces some aliasing towards the high end, especially if your source material\n * contains a lot of high frequencies. Unfortunatelly the webaudio API does not support resampling\n * buffers in real time, so it is not possible to fix it properly. Depending on the use case it might\n * be an option to low pass filter your input before frequency shifting it to get ride of the aliasing.\n * You can find a very detailed description of the algorithm here: https://larzeitlin.github.io/RMFS/\n *\n * @example\n * const input = new Tone.Oscillator(230, "sawtooth").start();\n * const shift = new Tone.FrequencyShifter(42).toDestination();\n * input.connect(shift);\n * @category Effect\n */\nclass FrequencyShifter extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]));\n this.name = "FrequencyShifter";\n const options = optionsFromArguments(FrequencyShifter.getDefaults(), arguments, ["frequency"]);\n this.frequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.frequency,\n minValue: -this.context.sampleRate / 2,\n maxValue: this.context.sampleRate / 2,\n });\n this._sine = new ToneOscillatorNode({\n context: this.context,\n type: "sine",\n });\n this._cosine = new Oscillator({\n context: this.context,\n phase: -90,\n type: "sine",\n });\n this._sineMultiply = new Multiply({ context: this.context });\n this._cosineMultiply = new Multiply({ context: this.context });\n this._negate = new Negate({ context: this.context });\n this._add = new Add({ context: this.context });\n this._phaseShifter = new PhaseShiftAllpass({ context: this.context });\n this.effectSend.connect(this._phaseShifter);\n // connect the carrier frequency signal to the two oscillators\n this.frequency.fan(this._sine.frequency, this._cosine.frequency);\n this._phaseShifter.offset90.connect(this._cosineMultiply);\n this._cosine.connect(this._cosineMultiply.factor);\n this._phaseShifter.connect(this._sineMultiply);\n this._sine.connect(this._sineMultiply.factor);\n this._sineMultiply.connect(this._negate);\n this._cosineMultiply.connect(this._add);\n this._negate.connect(this._add.addend);\n this._add.connect(this.effectReturn);\n // start the oscillators at the same time\n const now = this.immediate();\n this._sine.start(now);\n this._cosine.start(now);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n frequency: 0,\n });\n }\n dispose() {\n super.dispose();\n this.frequency.dispose();\n this._add.dispose();\n this._cosine.dispose();\n this._cosineMultiply.dispose();\n this._negate.dispose();\n this._phaseShifter.dispose();\n this._sine.dispose();\n this._sineMultiply.dispose();\n return this;\n }\n}\n//# sourceMappingURL=FrequencyShifter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Freeverb.js\n\n\n\n\n\n/**\n * An array of comb filter delay values from Freeverb implementation\n */\nconst combFilterTunings = (/* unused pure expression or super */ null && ([1557 / 44100, 1617 / 44100, 1491 / 44100, 1422 / 44100, 1277 / 44100, 1356 / 44100, 1188 / 44100, 1116 / 44100]));\n/**\n * An array of allpass filter frequency values from Freeverb implementation\n */\nconst allpassFilterFrequencies = (/* unused pure expression or super */ null && ([225, 556, 441, 341]));\n/**\n * Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html).\n * Read more on reverb on [Sound On Sound](https://web.archive.org/web/20160404083902/http://www.soundonsound.com:80/sos/feb01/articles/synthsecrets.asp).\n * Freeverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]].\n * @example\n * const freeverb = new Tone.Freeverb().toDestination();\n * freeverb.dampening = 1000;\n * // routing synth through the reverb\n * const synth = new Tone.NoiseSynth().connect(freeverb);\n * synth.triggerAttackRelease(0.05);\n * @category Effect\n */\nclass Freeverb extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]));\n this.name = "Freeverb";\n /**\n * the comb filters\n */\n this._combFilters = [];\n /**\n * the allpass filters on the left\n */\n this._allpassFiltersL = [];\n /**\n * the allpass filters on the right\n */\n this._allpassFiltersR = [];\n const options = optionsFromArguments(Freeverb.getDefaults(), arguments, ["roomSize", "dampening"]);\n this.roomSize = new Signal({\n context: this.context,\n value: options.roomSize,\n units: "normalRange",\n });\n // make the allpass filters on the right\n this._allpassFiltersL = allpassFilterFrequencies.map(freq => {\n const allpassL = this.context.createBiquadFilter();\n allpassL.type = "allpass";\n allpassL.frequency.value = freq;\n return allpassL;\n });\n // make the allpass filters on the left\n this._allpassFiltersR = allpassFilterFrequencies.map(freq => {\n const allpassR = this.context.createBiquadFilter();\n allpassR.type = "allpass";\n allpassR.frequency.value = freq;\n return allpassR;\n });\n // make the comb filters\n this._combFilters = combFilterTunings.map((delayTime, index) => {\n const lfpf = new LowpassCombFilter({\n context: this.context,\n dampening: options.dampening,\n delayTime,\n });\n if (index < combFilterTunings.length / 2) {\n this.connectEffectLeft(lfpf, ...this._allpassFiltersL);\n }\n else {\n this.connectEffectRight(lfpf, ...this._allpassFiltersR);\n }\n this.roomSize.connect(lfpf.resonance);\n return lfpf;\n });\n readOnly(this, ["roomSize"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n roomSize: 0.7,\n dampening: 3000\n });\n }\n /**\n * The amount of dampening of the reverberant signal.\n */\n get dampening() {\n return this._combFilters[0].dampening;\n }\n set dampening(d) {\n this._combFilters.forEach(c => c.dampening = d);\n }\n dispose() {\n super.dispose();\n this._allpassFiltersL.forEach(al => al.disconnect());\n this._allpassFiltersR.forEach(ar => ar.disconnect());\n this._combFilters.forEach(cf => cf.dispose());\n this.roomSize.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Freeverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/JCReverb.js\n\n\n\n\n\n\n/**\n * an array of the comb filter delay time values\n */\nconst combFilterDelayTimes = (/* unused pure expression or super */ null && ([1687 / 25000, 1601 / 25000, 2053 / 25000, 2251 / 25000]));\n/**\n * the resonances of each of the comb filters\n */\nconst combFilterResonances = (/* unused pure expression or super */ null && ([0.773, 0.802, 0.753, 0.733]));\n/**\n * the allpass filter frequencies\n */\nconst allpassFilterFreqs = (/* unused pure expression or super */ null && ([347, 113, 37]));\n/**\n * JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html)\n * tuned by John Chowning in 1970.\n * It is made up of three allpass filters and four [[FeedbackCombFilter]].\n * JCReverb is now implemented with an AudioWorkletNode which may result on performance degradation on some platforms. Consider using [[Reverb]].\n * @example\n * const reverb = new Tone.JCReverb(0.4).toDestination();\n * const delay = new Tone.FeedbackDelay(0.5);\n * // connecting the synth to reverb through delay\n * const synth = new Tone.DuoSynth().chain(delay, reverb);\n * synth.triggerAttackRelease("A4", "8n");\n *\n * @category Effect\n */\nclass JCReverb extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]));\n this.name = "JCReverb";\n /**\n * a series of allpass filters\n */\n this._allpassFilters = [];\n /**\n * parallel feedback comb filters\n */\n this._feedbackCombFilters = [];\n const options = optionsFromArguments(JCReverb.getDefaults(), arguments, ["roomSize"]);\n this.roomSize = new Signal({\n context: this.context,\n value: options.roomSize,\n units: "normalRange",\n });\n this._scaleRoomSize = new Scale({\n context: this.context,\n min: -0.733,\n max: 0.197,\n });\n // make the allpass filters\n this._allpassFilters = allpassFilterFreqs.map(freq => {\n const allpass = this.context.createBiquadFilter();\n allpass.type = "allpass";\n allpass.frequency.value = freq;\n return allpass;\n });\n // and the comb filters\n this._feedbackCombFilters = combFilterDelayTimes.map((delayTime, index) => {\n const fbcf = new FeedbackCombFilter({\n context: this.context,\n delayTime,\n });\n this._scaleRoomSize.connect(fbcf.resonance);\n fbcf.resonance.value = combFilterResonances[index];\n if (index < combFilterDelayTimes.length / 2) {\n this.connectEffectLeft(...this._allpassFilters, fbcf);\n }\n else {\n this.connectEffectRight(...this._allpassFilters, fbcf);\n }\n return fbcf;\n });\n // chain the allpass filters together\n this.roomSize.connect(this._scaleRoomSize);\n readOnly(this, ["roomSize"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n roomSize: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this._allpassFilters.forEach(apf => apf.disconnect());\n this._feedbackCombFilters.forEach(fbcf => fbcf.dispose());\n this.roomSize.dispose();\n this._scaleRoomSize.dispose();\n return this;\n }\n}\n//# sourceMappingURL=JCReverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoXFeedbackEffect.js\n\n\n/**\n * Just like a [[StereoFeedbackEffect]], but the feedback is routed from left to right\n * and right to left instead of on the same channel.\n * ```\n * +--------------------------------+ feedbackL <-----------------------------------+\n * | |\n * +--\x3e +-----\x3e +----\x3e +-----+\n * feedbackMerge +--\x3e split (EFFECT) merge +--\x3e feedbackSplit | |\n * +--\x3e +-----\x3e +----\x3e +---+ |\n * | |\n * +--------------------------------+ feedbackR <-------------------------------------+\n * ```\n */\nclass StereoXFeedbackEffect_StereoXFeedbackEffect extends (/* unused pure expression or super */ null && (StereoFeedbackEffect)) {\n constructor(options) {\n super(options);\n // the left output connected to the right input\n this._feedbackL.disconnect();\n this._feedbackL.connect(this._feedbackMerge, 0, 1);\n // the left output connected to the right input\n this._feedbackR.disconnect();\n this._feedbackR.connect(this._feedbackMerge, 0, 0);\n readOnly(this, ["feedback"]);\n }\n}\n//# sourceMappingURL=StereoXFeedbackEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/PingPongDelay.js\n\n\n\n\n\n/**\n * PingPongDelay is a feedback delay effect where the echo is heard\n * first in one channel and next in the opposite channel. In a stereo\n * system these are the right and left channels.\n * PingPongDelay in more simplified terms is two Tone.FeedbackDelays\n * with independent delay values. Each delay is routed to one channel\n * (left or right), and the channel triggered second will always\n * trigger at the same interval after the first.\n * @example\n * const pingPong = new Tone.PingPongDelay("4n", 0.2).toDestination();\n * const drum = new Tone.MembraneSynth().connect(pingPong);\n * drum.triggerAttackRelease("C4", "32n");\n * @category Effect\n */\nclass PingPongDelay extends (/* unused pure expression or super */ null && (StereoXFeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]));\n this.name = "PingPongDelay";\n const options = optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]);\n this._leftDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay,\n });\n this._rightDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay\n });\n this._rightPreDelay = new Delay({\n context: this.context,\n maxDelay: options.maxDelay\n });\n this.delayTime = new Signal({\n context: this.context,\n units: "time",\n value: options.delayTime,\n });\n // connect it up\n this.connectEffectLeft(this._leftDelay);\n this.connectEffectRight(this._rightPreDelay, this._rightDelay);\n this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime);\n // rearranged the feedback to be after the rightPreDelay\n this._feedbackL.disconnect();\n this._feedbackL.connect(this._rightDelay);\n readOnly(this, ["delayTime"]);\n }\n static getDefaults() {\n return Object.assign(StereoXFeedbackEffect.getDefaults(), {\n delayTime: 0.25,\n maxDelay: 1\n });\n }\n dispose() {\n super.dispose();\n this._leftDelay.dispose();\n this._rightDelay.dispose();\n this._rightPreDelay.dispose();\n this.delayTime.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PingPongDelay.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/PitchShift.js\n\n\n\n\n\n\n\n\n/**\n * PitchShift does near-realtime pitch shifting to the incoming signal.\n * The effect is achieved by speeding up or slowing down the delayTime\n * of a DelayNode using a sawtooth wave.\n * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf).\n * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html).\n * @category Effect\n */\nclass PitchShift extends (/* unused pure expression or super */ null && (FeedbackEffect)) {\n constructor() {\n super(optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]));\n this.name = "PitchShift";\n const options = optionsFromArguments(PitchShift.getDefaults(), arguments, ["pitch"]);\n this._frequency = new Signal({ context: this.context });\n this._delayA = new Delay({\n maxDelay: 1,\n context: this.context\n });\n this._lfoA = new LFO({\n context: this.context,\n min: 0,\n max: 0.1,\n type: "sawtooth"\n }).connect(this._delayA.delayTime);\n this._delayB = new Delay({\n maxDelay: 1,\n context: this.context\n });\n this._lfoB = new LFO({\n context: this.context,\n min: 0,\n max: 0.1,\n type: "sawtooth",\n phase: 180\n }).connect(this._delayB.delayTime);\n this._crossFade = new CrossFade({ context: this.context });\n this._crossFadeLFO = new LFO({\n context: this.context,\n min: 0,\n max: 1,\n type: "triangle",\n phase: 90\n }).connect(this._crossFade.fade);\n this._feedbackDelay = new Delay({\n delayTime: options.delayTime,\n context: this.context,\n });\n this.delayTime = this._feedbackDelay.delayTime;\n readOnly(this, "delayTime");\n this._pitch = options.pitch;\n this._windowSize = options.windowSize;\n // connect the two delay lines up\n this._delayA.connect(this._crossFade.a);\n this._delayB.connect(this._crossFade.b);\n // connect the frequency\n this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency);\n // route the input\n this.effectSend.fan(this._delayA, this._delayB);\n this._crossFade.chain(this._feedbackDelay, this.effectReturn);\n // start the LFOs at the same time\n const now = this.now();\n this._lfoA.start(now);\n this._lfoB.start(now);\n this._crossFadeLFO.start(now);\n // set the initial value\n this.windowSize = this._windowSize;\n }\n static getDefaults() {\n return Object.assign(FeedbackEffect.getDefaults(), {\n pitch: 0,\n windowSize: 0.1,\n delayTime: 0,\n feedback: 0\n });\n }\n /**\n * Repitch the incoming signal by some interval (measured in semi-tones).\n * @example\n * const pitchShift = new Tone.PitchShift().toDestination();\n * const osc = new Tone.Oscillator().connect(pitchShift).start().toDestination();\n * pitchShift.pitch = -12; // down one octave\n * pitchShift.pitch = 7; // up a fifth\n */\n get pitch() {\n return this._pitch;\n }\n set pitch(interval) {\n this._pitch = interval;\n let factor = 0;\n if (interval < 0) {\n this._lfoA.min = 0;\n this._lfoA.max = this._windowSize;\n this._lfoB.min = 0;\n this._lfoB.max = this._windowSize;\n factor = intervalToFrequencyRatio(interval - 1) + 1;\n }\n else {\n this._lfoA.min = this._windowSize;\n this._lfoA.max = 0;\n this._lfoB.min = this._windowSize;\n this._lfoB.max = 0;\n factor = intervalToFrequencyRatio(interval) - 1;\n }\n this._frequency.value = factor * (1.2 / this._windowSize);\n }\n /**\n * The window size corresponds roughly to the sample length in a looping sampler.\n * Smaller values are desirable for a less noticeable delay time of the pitch shifted\n * signal, but larger values will result in smoother pitch shifting for larger intervals.\n * A nominal range of 0.03 to 0.1 is recommended.\n */\n get windowSize() {\n return this._windowSize;\n }\n set windowSize(size) {\n this._windowSize = this.toSeconds(size);\n this.pitch = this._pitch;\n }\n dispose() {\n super.dispose();\n this._frequency.dispose();\n this._delayA.dispose();\n this._delayB.dispose();\n this._lfoA.dispose();\n this._lfoB.dispose();\n this._crossFade.dispose();\n this._crossFadeLFO.dispose();\n this._feedbackDelay.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PitchShift.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Phaser.js\n\n\n\n\n\n/**\n * Phaser is a phaser effect. Phasers work by changing the phase\n * of different frequency components of an incoming signal. Read more on\n * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)).\n * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/).\n * @example\n * const phaser = new Tone.Phaser({\n * \tfrequency: 15,\n * \toctaves: 5,\n * \tbaseFrequency: 1000\n * }).toDestination();\n * const synth = new Tone.FMSynth().connect(phaser);\n * synth.triggerAttackRelease("E3", "2n");\n * @category Effect\n */\nclass Phaser extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]));\n this.name = "Phaser";\n const options = optionsFromArguments(Phaser.getDefaults(), arguments, ["frequency", "octaves", "baseFrequency"]);\n this._lfoL = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1\n });\n this._lfoR = new LFO({\n context: this.context,\n frequency: options.frequency,\n min: 0,\n max: 1,\n phase: 180,\n });\n this._baseFrequency = this.toFrequency(options.baseFrequency);\n this._octaves = options.octaves;\n this.Q = new Signal({\n context: this.context,\n value: options.Q,\n units: "positive",\n });\n this._filtersL = this._makeFilters(options.stages, this._lfoL);\n this._filtersR = this._makeFilters(options.stages, this._lfoR);\n this.frequency = this._lfoL.frequency;\n this.frequency.value = options.frequency;\n // connect them up\n this.connectEffectLeft(...this._filtersL);\n this.connectEffectRight(...this._filtersR);\n // control the frequency with one LFO\n this._lfoL.frequency.connect(this._lfoR.frequency);\n // set the options\n this.baseFrequency = options.baseFrequency;\n this.octaves = options.octaves;\n // start the lfo\n this._lfoL.start();\n this._lfoR.start();\n readOnly(this, ["frequency", "Q"]);\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n frequency: 0.5,\n octaves: 3,\n stages: 10,\n Q: 10,\n baseFrequency: 350,\n });\n }\n _makeFilters(stages, connectToFreq) {\n const filters = [];\n // make all the filters\n for (let i = 0; i < stages; i++) {\n const filter = this.context.createBiquadFilter();\n filter.type = "allpass";\n this.Q.connect(filter.Q);\n connectToFreq.connect(filter.frequency);\n filters.push(filter);\n }\n return filters;\n }\n /**\n * The number of octaves the phase goes above the baseFrequency\n */\n get octaves() {\n return this._octaves;\n }\n set octaves(octaves) {\n this._octaves = octaves;\n const max = this._baseFrequency * Math.pow(2, octaves);\n this._lfoL.max = max;\n this._lfoR.max = max;\n }\n /**\n * The the base frequency of the filters.\n */\n get baseFrequency() {\n return this._baseFrequency;\n }\n set baseFrequency(freq) {\n this._baseFrequency = this.toFrequency(freq);\n this._lfoL.min = this._baseFrequency;\n this._lfoR.min = this._baseFrequency;\n this.octaves = this._octaves;\n }\n dispose() {\n super.dispose();\n this.Q.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._filtersL.forEach(f => f.disconnect());\n this._filtersR.forEach(f => f.disconnect());\n this.frequency.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Phaser.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Reverb.js\n\n\n\n\n\n\n\n\n\n/**\n * Simple convolution created with decaying noise.\n * Generates an Impulse Response Buffer\n * with Tone.Offline then feeds the IR into ConvolverNode.\n * The impulse response generation is async, so you have\n * to wait until [[ready]] resolves before it will make a sound.\n *\n * Inspiration from [ReverbGen](https://github.com/adelespinasse/reverbGen).\n * Copyright (c) 2014 Alan deLespinasse Apache 2.0 License.\n *\n * @category Effect\n */\nclass Reverb extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]));\n this.name = "Reverb";\n /**\n * Convolver node\n */\n this._convolver = this.context.createConvolver();\n /**\n * Resolves when the reverb buffer is generated. Whenever either [[decay]]\n * or [[preDelay]] are set, you have to wait until [[ready]] resolves\n * before the IR is generated with the latest values.\n */\n this.ready = Promise.resolve();\n const options = optionsFromArguments(Reverb.getDefaults(), arguments, ["decay"]);\n this._decay = options.decay;\n this._preDelay = options.preDelay;\n this.generate();\n this.connectEffect(this._convolver);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n decay: 1.5,\n preDelay: 0.01,\n });\n }\n /**\n * The duration of the reverb.\n */\n get decay() {\n return this._decay;\n }\n set decay(time) {\n time = this.toSeconds(time);\n assertRange(time, 0.001);\n this._decay = time;\n this.generate();\n }\n /**\n * The amount of time before the reverb is fully ramped in.\n */\n get preDelay() {\n return this._preDelay;\n }\n set preDelay(time) {\n time = this.toSeconds(time);\n assertRange(time, 0);\n this._preDelay = time;\n this.generate();\n }\n /**\n * Generate the Impulse Response. Returns a promise while the IR is being generated.\n * @return Promise which returns this object.\n */\n generate() {\n return __awaiter(this, void 0, void 0, function* () {\n const previousReady = this.ready;\n // create a noise burst which decays over the duration in each channel\n const context = new OfflineContext(2, this._decay + this._preDelay, this.context.sampleRate);\n const noiseL = new Noise({ context });\n const noiseR = new Noise({ context });\n const merge = new Merge({ context });\n noiseL.connect(merge, 0, 0);\n noiseR.connect(merge, 0, 1);\n const gainNode = new Gain({ context }).toDestination();\n merge.connect(gainNode);\n noiseL.start(0);\n noiseR.start(0);\n // predelay\n gainNode.gain.setValueAtTime(0, 0);\n gainNode.gain.setValueAtTime(1, this._preDelay);\n // decay\n gainNode.gain.exponentialApproachValueAtTime(0, this._preDelay, this.decay);\n // render the buffer\n const renderPromise = context.render();\n this.ready = renderPromise.then(noOp);\n // wait for the previous `ready` to resolve\n yield previousReady;\n // set the buffer\n this._convolver.buffer = (yield renderPromise).get();\n return this;\n });\n }\n dispose() {\n super.dispose();\n this._convolver.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Reverb.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MidSideSplit.js\n\n\n\n\n\n\n/**\n * Mid/Side processing separates the the \'mid\' signal (which comes out of both the left and the right channel)\n * and the \'side\' (which only comes out of the the side channels).\n * ```\n * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right\n * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right\n * ```\n * @category Component\n */\nclass MidSideSplit_MidSideSplit extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MidSideSplit_MidSideSplit.getDefaults(), arguments));\n this.name = "MidSideSplit";\n this._split = this.input = new Split({\n channels: 2,\n context: this.context\n });\n this._midAdd = new Add({ context: this.context });\n this.mid = new Multiply({\n context: this.context,\n value: Math.SQRT1_2,\n });\n this._sideSubtract = new Subtract({ context: this.context });\n this.side = new Multiply({\n context: this.context,\n value: Math.SQRT1_2,\n });\n this._split.connect(this._midAdd, 0);\n this._split.connect(this._midAdd.addend, 1);\n this._split.connect(this._sideSubtract, 0);\n this._split.connect(this._sideSubtract.subtrahend, 1);\n this._midAdd.connect(this.mid);\n this._sideSubtract.connect(this.side);\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._midAdd.dispose();\n this._sideSubtract.dispose();\n this._split.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideSplit.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MidSideMerge.js\n\n\n\n\n\n\n\n/**\n * MidSideMerge merges the mid and side signal after they\'ve been separated by [[MidSideSplit]]\n * ```\n * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right\n * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and right\n * ```\n * @category Component\n */\nclass MidSideMerge_MidSideMerge extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MidSideMerge_MidSideMerge.getDefaults(), arguments));\n this.name = "MidSideMerge";\n this.mid = new Gain({ context: this.context });\n this.side = new Gain({ context: this.context });\n this._left = new Add({ context: this.context });\n this._leftMult = new Multiply({\n context: this.context,\n value: Math.SQRT1_2\n });\n this._right = new Subtract({ context: this.context });\n this._rightMult = new Multiply({\n context: this.context,\n value: Math.SQRT1_2\n });\n this._merge = this.output = new Merge({ context: this.context });\n this.mid.fan(this._left);\n this.side.connect(this._left.addend);\n this.mid.connect(this._right);\n this.side.connect(this._right.subtrahend);\n this._left.connect(this._leftMult);\n this._right.connect(this._rightMult);\n this._leftMult.connect(this._merge, 0, 0);\n this._rightMult.connect(this._merge, 0, 1);\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._leftMult.dispose();\n this._rightMult.dispose();\n this._left.dispose();\n this._right.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideMerge.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/MidSideEffect.js\n\n\n\n/**\n * Mid/Side processing separates the the \'mid\' signal\n * (which comes out of both the left and the right channel)\n * and the \'side\' (which only comes out of the the side channels)\n * and effects them separately before being recombined.\n * Applies a Mid/Side seperation and recombination.\n * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n * This is a base-class for Mid/Side Effects.\n * @category Effect\n */\nclass MidSideEffect_MidSideEffect extends (/* unused pure expression or super */ null && (Effect)) {\n constructor(options) {\n super(options);\n this.name = "MidSideEffect";\n this._midSideMerge = new MidSideMerge({ context: this.context });\n this._midSideSplit = new MidSideSplit({ context: this.context });\n this._midSend = this._midSideSplit.mid;\n this._sideSend = this._midSideSplit.side;\n this._midReturn = this._midSideMerge.mid;\n this._sideReturn = this._midSideMerge.side;\n // the connections\n this.effectSend.connect(this._midSideSplit);\n this._midSideMerge.connect(this.effectReturn);\n }\n /**\n * Connect the mid chain of the effect\n */\n connectEffectMid(...nodes) {\n this._midSend.chain(...nodes, this._midReturn);\n }\n /**\n * Connect the side chain of the effect\n */\n connectEffectSide(...nodes) {\n this._sideSend.chain(...nodes, this._sideReturn);\n }\n dispose() {\n super.dispose();\n this._midSideSplit.dispose();\n this._midSideMerge.dispose();\n this._midSend.dispose();\n this._sideSend.dispose();\n this._midReturn.dispose();\n this._sideReturn.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideEffect.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/StereoWidener.js\n\n\n\n\n\n\n\n/**\n * Applies a width factor to the mid/side seperation.\n * 0 is all mid and 1 is all side.\n * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587).\n * ```\n * Mid *= 2*(1-width)<br>\n * Side *= 2*width\n * ```\n * @category Effect\n */\nclass StereoWidener extends (/* unused pure expression or super */ null && (MidSideEffect)) {\n constructor() {\n super(optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]));\n this.name = "StereoWidener";\n const options = optionsFromArguments(StereoWidener.getDefaults(), arguments, ["width"]);\n this.width = new Signal({\n context: this.context,\n value: options.width,\n units: "normalRange",\n });\n readOnly(this, ["width"]);\n this._twoTimesWidthMid = new Multiply({\n context: this.context,\n value: 2,\n });\n this._twoTimesWidthSide = new Multiply({\n context: this.context,\n value: 2,\n });\n this._midMult = new Multiply({ context: this.context });\n this._twoTimesWidthMid.connect(this._midMult.factor);\n this.connectEffectMid(this._midMult);\n this._oneMinusWidth = new Subtract({ context: this.context });\n this._oneMinusWidth.connect(this._twoTimesWidthMid);\n connect(this.context.getConstant(1), this._oneMinusWidth);\n this.width.connect(this._oneMinusWidth.subtrahend);\n this._sideMult = new Multiply({ context: this.context });\n this.width.connect(this._twoTimesWidthSide);\n this._twoTimesWidthSide.connect(this._sideMult.factor);\n this.connectEffectSide(this._sideMult);\n }\n static getDefaults() {\n return Object.assign(MidSideEffect.getDefaults(), {\n width: 0.5,\n });\n }\n dispose() {\n super.dispose();\n this.width.dispose();\n this._midMult.dispose();\n this._sideMult.dispose();\n this._twoTimesWidthMid.dispose();\n this._twoTimesWidthSide.dispose();\n this._oneMinusWidth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=StereoWidener.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Tremolo.js\n\n\n\n\n\n\n/**\n * Tremolo modulates the amplitude of an incoming signal using an [[LFO]].\n * The effect is a stereo effect where the modulation phase is inverted in each channel.\n *\n * @example\n * // create a tremolo and start it\'s LFO\n * const tremolo = new Tone.Tremolo(9, 0.75).toDestination().start();\n * // route an oscillator through the tremolo and start it\n * const oscillator = new Tone.Oscillator().connect(tremolo).start();\n *\n * @category Effect\n */\nclass Tremolo extends (/* unused pure expression or super */ null && (StereoEffect)) {\n constructor() {\n super(optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]));\n this.name = "Tremolo";\n const options = optionsFromArguments(Tremolo.getDefaults(), arguments, ["frequency", "depth"]);\n this._lfoL = new LFO({\n context: this.context,\n type: options.type,\n min: 1,\n max: 0,\n });\n this._lfoR = new LFO({\n context: this.context,\n type: options.type,\n min: 1,\n max: 0,\n });\n this._amplitudeL = new Gain({ context: this.context });\n this._amplitudeR = new Gain({ context: this.context });\n this.frequency = new Signal({\n context: this.context,\n value: options.frequency,\n units: "frequency",\n });\n this.depth = new Signal({\n context: this.context,\n value: options.depth,\n units: "normalRange",\n });\n readOnly(this, ["frequency", "depth"]);\n this.connectEffectLeft(this._amplitudeL);\n this.connectEffectRight(this._amplitudeR);\n this._lfoL.connect(this._amplitudeL.gain);\n this._lfoR.connect(this._amplitudeR.gain);\n this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency);\n this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude);\n this.spread = options.spread;\n }\n static getDefaults() {\n return Object.assign(StereoEffect.getDefaults(), {\n frequency: 10,\n type: "sine",\n depth: 0.5,\n spread: 180,\n });\n }\n /**\n * Start the tremolo.\n */\n start(time) {\n this._lfoL.start(time);\n this._lfoR.start(time);\n return this;\n }\n /**\n * Stop the tremolo.\n */\n stop(time) {\n this._lfoL.stop(time);\n this._lfoR.stop(time);\n return this;\n }\n /**\n * Sync the effect to the transport.\n */\n sync() {\n this._lfoL.sync();\n this._lfoR.sync();\n this.context.transport.syncSignal(this.frequency);\n return this;\n }\n /**\n * Unsync the filter from the transport\n */\n unsync() {\n this._lfoL.unsync();\n this._lfoR.unsync();\n this.context.transport.unsyncSignal(this.frequency);\n return this;\n }\n /**\n * The oscillator type.\n */\n get type() {\n return this._lfoL.type;\n }\n set type(type) {\n this._lfoL.type = type;\n this._lfoR.type = type;\n }\n /**\n * Amount of stereo spread. When set to 0, both LFO\'s will be panned centrally.\n * When set to 180, LFO\'s will be panned hard left and right respectively.\n */\n get spread() {\n return this._lfoR.phase - this._lfoL.phase; // 180\n }\n set spread(spread) {\n this._lfoL.phase = 90 - (spread / 2);\n this._lfoR.phase = (spread / 2) + 90;\n }\n dispose() {\n super.dispose();\n this._lfoL.dispose();\n this._lfoR.dispose();\n this._amplitudeL.dispose();\n this._amplitudeR.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Tremolo.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/Vibrato.js\n\n\n\n\n\n/**\n * A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO\n * modulates the delayTime of the delay, causing the pitch to rise and fall.\n * @category Effect\n */\nclass Vibrato extends (/* unused pure expression or super */ null && (Effect)) {\n constructor() {\n super(optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]));\n this.name = "Vibrato";\n const options = optionsFromArguments(Vibrato.getDefaults(), arguments, ["frequency", "depth"]);\n this._delayNode = new Delay({\n context: this.context,\n delayTime: 0,\n maxDelay: options.maxDelay,\n });\n this._lfo = new LFO({\n context: this.context,\n type: options.type,\n min: 0,\n max: options.maxDelay,\n frequency: options.frequency,\n phase: -90 // offse the phase so the resting position is in the center\n }).start().connect(this._delayNode.delayTime);\n this.frequency = this._lfo.frequency;\n this.depth = this._lfo.amplitude;\n this.depth.value = options.depth;\n readOnly(this, ["frequency", "depth"]);\n this.effectSend.chain(this._delayNode, this.effectReturn);\n }\n static getDefaults() {\n return Object.assign(Effect.getDefaults(), {\n maxDelay: 0.005,\n frequency: 5,\n depth: 0.1,\n type: "sine"\n });\n }\n /**\n * Type of oscillator attached to the Vibrato.\n */\n get type() {\n return this._lfo.type;\n }\n set type(type) {\n this._lfo.type = type;\n }\n dispose() {\n super.dispose();\n this._delayNode.dispose();\n this._lfo.dispose();\n this.frequency.dispose();\n this.depth.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Vibrato.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/effect/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Analyser.js\n\n\n\n\n\n/**\n * Wrapper around the native Web Audio\'s [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).\n * Extracts FFT or Waveform data from the incoming signal.\n * @category Component\n */\nclass Analyser_Analyser extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Analyser_Analyser.getDefaults(), arguments, ["type", "size"]));\n this.name = "Analyser";\n /**\n * The analyser node.\n */\n this._analysers = [];\n /**\n * The buffer that the FFT data is written to\n */\n this._buffers = [];\n const options = optionsFromArguments(Analyser_Analyser.getDefaults(), arguments, ["type", "size"]);\n this.input = this.output = this._gain = new Gain({ context: this.context });\n this._split = new Split({\n context: this.context,\n channels: options.channels,\n });\n this.input.connect(this._split);\n assertRange(options.channels, 1);\n // create the analysers\n for (let channel = 0; channel < options.channels; channel++) {\n this._analysers[channel] = this.context.createAnalyser();\n this._split.connect(this._analysers[channel], channel, 0);\n }\n // set the values initially\n this.size = options.size;\n this.type = options.type;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n size: 1024,\n smoothing: 0.8,\n type: "fft",\n channels: 1,\n });\n }\n /**\n * Run the analysis given the current settings. If [[channels]] = 1,\n * it will return a Float32Array. If [[channels]] > 1, it will\n * return an array of Float32Arrays where each index in the array\n * represents the analysis done on a channel.\n */\n getValue() {\n this._analysers.forEach((analyser, index) => {\n const buffer = this._buffers[index];\n if (this._type === "fft") {\n analyser.getFloatFrequencyData(buffer);\n }\n else if (this._type === "waveform") {\n analyser.getFloatTimeDomainData(buffer);\n }\n });\n if (this.channels === 1) {\n return this._buffers[0];\n }\n else {\n return this._buffers;\n }\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n */\n get size() {\n return this._analysers[0].frequencyBinCount;\n }\n set size(size) {\n this._analysers.forEach((analyser, index) => {\n analyser.fftSize = size * 2;\n this._buffers[index] = new Float32Array(size);\n });\n }\n /**\n * The number of channels the analyser does the analysis on. Channel\n * separation is done using [[Split]]\n */\n get channels() {\n return this._analysers.length;\n }\n /**\n * The analysis function returned by analyser.getValue(), either "fft" or "waveform".\n */\n get type() {\n return this._type;\n }\n set type(type) {\n assert(type === "waveform" || type === "fft", `Analyser: invalid type: ${type}`);\n this._type = type;\n }\n /**\n * 0 represents no time averaging with the last analysis frame.\n */\n get smoothing() {\n return this._analysers[0].smoothingTimeConstant;\n }\n set smoothing(val) {\n this._analysers.forEach(a => a.smoothingTimeConstant = val);\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n this._analysers.forEach(a => a.disconnect());\n this._split.dispose();\n this._gain.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Analyser.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/MeterBase.js\n\n\n\n/**\n * The base class for Metering classes.\n */\nclass MeterBase_MeterBase extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MeterBase_MeterBase.getDefaults(), arguments));\n this.name = "MeterBase";\n this.input = this.output = this._analyser = new Analyser({\n context: this.context,\n size: 256,\n type: "waveform",\n });\n }\n dispose() {\n super.dispose();\n this._analyser.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MeterBase.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Meter.js\n\n\n\n\n\n/**\n * Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)\n * of an input signal. It can also get the raw value of the input signal.\n *\n * @example\n * const meter = new Tone.Meter();\n * const mic = new Tone.UserMedia();\n * mic.open();\n * // connect mic to the meter\n * mic.connect(meter);\n * // the current level of the mic\n * setInterval(() => console.log(meter.getValue()), 100);\n * @category Component\n */\nclass Meter extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]));\n this.name = "Meter";\n /**\n * The previous frame\'s value\n */\n this._rms = 0;\n const options = optionsFromArguments(Meter.getDefaults(), arguments, ["smoothing"]);\n this.input = this.output = this._analyser = new Analyser({\n context: this.context,\n size: 256,\n type: "waveform",\n channels: options.channels,\n });\n this.smoothing = options.smoothing,\n this.normalRange = options.normalRange;\n }\n static getDefaults() {\n return Object.assign(MeterBase.getDefaults(), {\n smoothing: 0.8,\n normalRange: false,\n channels: 1,\n });\n }\n /**\n * Use [[getValue]] instead. For the previous getValue behavior, use DCMeter.\n * @deprecated\n */\n getLevel() {\n warn("\'getLevel\' has been changed to \'getValue\'");\n return this.getValue();\n }\n /**\n * Get the current value of the incoming signal.\n * Output is in decibels when [[normalRange]] is `false`.\n * If [[channels]] = 1, then the output is a single number\n * representing the value of the input signal. When [[channels]] > 1,\n * then each channel is returned as a value in a number array.\n */\n getValue() {\n const aValues = this._analyser.getValue();\n const channelValues = this.channels === 1 ? [aValues] : aValues;\n const vals = channelValues.map(values => {\n const totalSquared = values.reduce((total, current) => total + current * current, 0);\n const rms = Math.sqrt(totalSquared / values.length);\n // the rms can only fall at the rate of the smoothing\n // but can jump up instantly\n this._rms = Math.max(rms, this._rms * this.smoothing);\n return this.normalRange ? this._rms : gainToDb(this._rms);\n });\n if (this.channels === 1) {\n return vals[0];\n }\n else {\n return vals;\n }\n }\n /**\n * The number of channels of analysis.\n */\n get channels() {\n return this._analyser.channels;\n }\n dispose() {\n super.dispose();\n this._analyser.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Meter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/FFT.js\n\n\n\n\n\n/**\n * Get the current frequency data of the connected audio source using a fast Fourier transform.\n * @category Component\n */\nclass FFT extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(FFT.getDefaults(), arguments, ["size"]));\n this.name = "FFT";\n const options = optionsFromArguments(FFT.getDefaults(), arguments, ["size"]);\n this.normalRange = options.normalRange;\n this._analyser.type = "fft";\n this.size = options.size;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n normalRange: false,\n size: 1024,\n smoothing: 0.8,\n });\n }\n /**\n * Gets the current frequency data from the connected audio source.\n * Returns the frequency data of length [[size]] as a Float32Array of decibel values.\n */\n getValue() {\n const values = this._analyser.getValue();\n return values.map(v => this.normalRange ? dbToGain(v) : v);\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n * Determines the size of the array returned by [[getValue]] (i.e. the number of\n * frequency bins). Large FFT sizes may be costly to compute.\n */\n get size() {\n return this._analyser.size;\n }\n set size(size) {\n this._analyser.size = size;\n }\n /**\n * 0 represents no time averaging with the last analysis frame.\n */\n get smoothing() {\n return this._analyser.smoothing;\n }\n set smoothing(val) {\n this._analyser.smoothing = val;\n }\n /**\n * Returns the frequency value in hertz of each of the indices of the FFT\'s [[getValue]] response.\n * @example\n * const fft = new Tone.FFT(32);\n * console.log([0, 1, 2, 3, 4].map(index => fft.getFrequencyOfIndex(index)));\n */\n getFrequencyOfIndex(index) {\n assert(0 <= index && index < this.size, `index must be greater than or equal to 0 and less than ${this.size}`);\n return index * this.context.sampleRate / (this.size * 2);\n }\n}\n//# sourceMappingURL=FFT.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/DCMeter.js\n\n\n/**\n * DCMeter gets the raw value of the input signal at the current time.\n *\n * @example\n * const meter = new Tone.DCMeter();\n * const mic = new Tone.UserMedia();\n * mic.open();\n * // connect mic to the meter\n * mic.connect(meter);\n * // the current level of the mic\n * const level = meter.getValue();\n * @category Component\n */\nclass DCMeter extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(DCMeter.getDefaults(), arguments));\n this.name = "DCMeter";\n this._analyser.type = "waveform";\n this._analyser.size = 256;\n }\n /**\n * Get the signal value of the incoming signal\n */\n getValue() {\n const value = this._analyser.getValue();\n return value[0];\n }\n}\n//# sourceMappingURL=DCMeter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/analysis/Waveform.js\n\n\n/**\n * Get the current waveform data of the connected audio source.\n * @category Component\n */\nclass Waveform extends (/* unused pure expression or super */ null && (MeterBase)) {\n constructor() {\n super(optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]));\n this.name = "Waveform";\n const options = optionsFromArguments(Waveform.getDefaults(), arguments, ["size"]);\n this._analyser.type = "waveform";\n this.size = options.size;\n }\n static getDefaults() {\n return Object.assign(MeterBase.getDefaults(), {\n size: 1024,\n });\n }\n /**\n * Return the waveform for the current time as a Float32Array where each value in the array\n * represents a sample in the waveform.\n */\n getValue() {\n return this._analyser.getValue();\n }\n /**\n * The size of analysis. This must be a power of two in the range 16 to 16384.\n * Determines the size of the array returned by [[getValue]].\n */\n get size() {\n return this._analyser.size;\n }\n set size(size) {\n this._analyser.size = size;\n }\n}\n//# sourceMappingURL=Waveform.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Solo.js\n\n\n\n/**\n * Solo lets you isolate a specific audio stream. When an instance is set to `solo=true`,\n * it will mute all other instances of Solo.\n * @example\n * const soloA = new Tone.Solo().toDestination();\n * const oscA = new Tone.Oscillator("C4", "sawtooth").connect(soloA);\n * const soloB = new Tone.Solo().toDestination();\n * const oscB = new Tone.Oscillator("E4", "square").connect(soloB);\n * soloA.solo = true;\n * // no audio will pass through soloB\n * @category Component\n */\nclass Solo extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]));\n this.name = "Solo";\n const options = Defaults_optionsFromArguments(Solo.getDefaults(), arguments, ["solo"]);\n this.input = this.output = new Gain_Gain({\n context: this.context,\n });\n if (!Solo._allSolos.has(this.context)) {\n Solo._allSolos.set(this.context, new Set());\n }\n Solo._allSolos.get(this.context).add(this);\n // set initially\n this.solo = options.solo;\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n solo: false,\n });\n }\n /**\n * Isolates this instance and mutes all other instances of Solo.\n * Only one instance can be soloed at a time. A soloed\n * instance will report `solo=false` when another instance is soloed.\n */\n get solo() {\n return this._isSoloed();\n }\n set solo(solo) {\n if (solo) {\n this._addSolo();\n }\n else {\n this._removeSolo();\n }\n Solo._allSolos.get(this.context).forEach(instance => instance._updateSolo());\n }\n /**\n * If the current instance is muted, i.e. another instance is soloed\n */\n get muted() {\n return this.input.gain.value === 0;\n }\n /**\n * Add this to the soloed array\n */\n _addSolo() {\n if (!Solo._soloed.has(this.context)) {\n Solo._soloed.set(this.context, new Set());\n }\n Solo._soloed.get(this.context).add(this);\n }\n /**\n * Remove this from the soloed array\n */\n _removeSolo() {\n if (Solo._soloed.has(this.context)) {\n Solo._soloed.get(this.context).delete(this);\n }\n }\n /**\n * Is this on the soloed array\n */\n _isSoloed() {\n return Solo._soloed.has(this.context) && Solo._soloed.get(this.context).has(this);\n }\n /**\n * Returns true if no one is soloed\n */\n _noSolos() {\n // either does not have any soloed added\n return !Solo._soloed.has(this.context) ||\n // or has a solo set but doesn\'t include any items\n (Solo._soloed.has(this.context) && Solo._soloed.get(this.context).size === 0);\n }\n /**\n * Solo the current instance and unsolo all other instances.\n */\n _updateSolo() {\n if (this._isSoloed()) {\n this.input.gain.value = 1;\n }\n else if (this._noSolos()) {\n // no one is soloed\n this.input.gain.value = 1;\n }\n else {\n this.input.gain.value = 0;\n }\n }\n dispose() {\n super.dispose();\n Solo._allSolos.get(this.context).delete(this);\n this._removeSolo();\n return this;\n }\n}\n/**\n * Hold all of the solo\'ed tracks belonging to a specific context\n */\nSolo._allSolos = new Map();\n/**\n * Hold the currently solo\'ed instance(s)\n */\nSolo._soloed = new Map();\n//# sourceMappingURL=Solo.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/PanVol.js\n\n\n\n\n\n/**\n * PanVol is a Tone.Panner and Tone.Volume in one.\n * @example\n * // pan the incoming signal left and drop the volume\n * const panVol = new Tone.PanVol(-0.25, -12).toDestination();\n * const osc = new Tone.Oscillator().connect(panVol).start();\n * @category Component\n */\nclass PanVol extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]));\n this.name = "PanVol";\n const options = Defaults_optionsFromArguments(PanVol.getDefaults(), arguments, ["pan", "volume"]);\n this._panner = this.input = new Panner_Panner({\n context: this.context,\n pan: options.pan,\n channelCount: options.channelCount,\n });\n this.pan = this._panner.pan;\n this._volume = this.output = new Volume_Volume({\n context: this.context,\n volume: options.volume,\n });\n this.volume = this._volume.volume;\n // connections\n this._panner.connect(this._volume);\n this.mute = options.mute;\n Interface_readOnly(this, ["pan", "volume"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n mute: false,\n pan: 0,\n volume: 0,\n channelCount: 1,\n });\n }\n /**\n * Mute/unmute the volume\n */\n get mute() {\n return this._volume.mute;\n }\n set mute(mute) {\n this._volume.mute = mute;\n }\n dispose() {\n super.dispose();\n this._panner.dispose();\n this.pan.dispose();\n this._volume.dispose();\n this.volume.dispose();\n return this;\n }\n}\n//# sourceMappingURL=PanVol.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Channel.js\n\n\n\n\n\n\n/**\n * Channel provides a channel strip interface with volume, pan, solo and mute controls.\n * See [[PanVol]] and [[Solo]]\n * @example\n * // pan the incoming signal left and drop the volume 12db\n * const channel = new Tone.Channel(-0.25, -12);\n * @category Component\n */\nclass Channel extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]));\n this.name = "Channel";\n const options = Defaults_optionsFromArguments(Channel.getDefaults(), arguments, ["volume", "pan"]);\n this._solo = this.input = new Solo({\n solo: options.solo,\n context: this.context,\n });\n this._panVol = this.output = new PanVol({\n context: this.context,\n pan: options.pan,\n volume: options.volume,\n mute: options.mute,\n channelCount: options.channelCount\n });\n this.pan = this._panVol.pan;\n this.volume = this._panVol.volume;\n this._solo.connect(this._panVol);\n Interface_readOnly(this, ["pan", "volume"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n pan: 0,\n volume: 0,\n mute: false,\n solo: false,\n channelCount: 1,\n });\n }\n /**\n * Solo/unsolo the channel. Soloing is only relative to other [[Channels]] and [[Solo]] instances\n */\n get solo() {\n return this._solo.solo;\n }\n set solo(solo) {\n this._solo.solo = solo;\n }\n /**\n * If the current instance is muted, i.e. another instance is soloed,\n * or the channel is muted\n */\n get muted() {\n return this._solo.muted || this.mute;\n }\n /**\n * Mute/unmute the volume\n */\n get mute() {\n return this._panVol.mute;\n }\n set mute(mute) {\n this._panVol.mute = mute;\n }\n /**\n * Get the gain node belonging to the bus name. Create it if\n * it doesn\'t exist\n * @param name The bus name\n */\n _getBus(name) {\n if (!Channel.buses.has(name)) {\n Channel.buses.set(name, new Gain_Gain({ context: this.context }));\n }\n return Channel.buses.get(name);\n }\n /**\n * Send audio to another channel using a string. `send` is a lot like\n * [[connect]], except it uses a string instead of an object. This can\n * be useful in large applications to decouple sections since [[send]]\n * and [[receive]] can be invoked separately in order to connect an object\n * @param name The channel name to send the audio\n * @param volume The amount of the signal to send.\n * \tDefaults to 0db, i.e. send the entire signal\n * @returns Returns the gain node of this connection.\n */\n send(name, volume = 0) {\n const bus = this._getBus(name);\n const sendKnob = new Gain_Gain({\n context: this.context,\n units: "decibels",\n gain: volume,\n });\n this.connect(sendKnob);\n sendKnob.connect(bus);\n return sendKnob;\n }\n /**\n * Receive audio from a channel which was connected with [[send]].\n * @param name The channel name to receive audio from.\n */\n receive(name) {\n const bus = this._getBus(name);\n bus.connect(this);\n return this;\n }\n dispose() {\n super.dispose();\n this._panVol.dispose();\n this.pan.dispose();\n this.volume.dispose();\n this._solo.dispose();\n return this;\n }\n}\n/**\n * Store the send/receive channels by name.\n */\nChannel.buses = new Map();\n//# sourceMappingURL=Channel.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Mono.js\n\n\n\n\n/**\n * Mono coerces the incoming mono or stereo signal into a mono signal\n * where both left and right channels have the same value. This can be useful\n * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging).\n * @category Component\n */\nclass Mono extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Mono.getDefaults(), arguments));\n this.name = "Mono";\n this.input = new Gain({ context: this.context });\n this._merge = this.output = new Merge({\n channels: 2,\n context: this.context,\n });\n this.input.connect(this._merge, 0, 0);\n this.input.connect(this._merge, 0, 1);\n }\n dispose() {\n super.dispose();\n this._merge.dispose();\n this.input.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Mono.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/MultibandSplit.js\n\n\n\n\n\n\n/**\n * Split the incoming signal into three bands (low, mid, high)\n * with two crossover frequency controls.\n * ```\n * +----------------------+\n * +-> input < lowFrequency +------------------\x3e low\n * | +----------------------+\n * |\n * | +--------------------------------------+\n * input ---+-> lowFrequency < input < highFrequency +--\x3e mid\n * | +--------------------------------------+\n * |\n * | +-----------------------+\n * +-> highFrequency < input +-----------------\x3e high\n * +-----------------------+\n * ```\n * @category Component\n */\nclass MultibandSplit_MultibandSplit extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(MultibandSplit_MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]));\n this.name = "MultibandSplit";\n /**\n * the input\n */\n this.input = new Gain({ context: this.context });\n /**\n * no output node, use either low, mid or high outputs\n */\n this.output = undefined;\n /**\n * The low band.\n */\n this.low = new Filter({\n context: this.context,\n frequency: 0,\n type: "lowpass",\n });\n /**\n * the lower filter of the mid band\n */\n this._lowMidFilter = new Filter({\n context: this.context,\n frequency: 0,\n type: "highpass",\n });\n /**\n * The mid band output.\n */\n this.mid = new Filter({\n context: this.context,\n frequency: 0,\n type: "lowpass",\n });\n /**\n * The high band output.\n */\n this.high = new Filter({\n context: this.context,\n frequency: 0,\n type: "highpass",\n });\n this._internalChannels = [this.low, this.mid, this.high];\n const options = optionsFromArguments(MultibandSplit_MultibandSplit.getDefaults(), arguments, ["lowFrequency", "highFrequency"]);\n this.lowFrequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.lowFrequency,\n });\n this.highFrequency = new Signal({\n context: this.context,\n units: "frequency",\n value: options.highFrequency,\n });\n this.Q = new Signal({\n context: this.context,\n units: "positive",\n value: options.Q,\n });\n this.input.fan(this.low, this.high);\n this.input.chain(this._lowMidFilter, this.mid);\n // the frequency control signal\n this.lowFrequency.fan(this.low.frequency, this._lowMidFilter.frequency);\n this.highFrequency.fan(this.mid.frequency, this.high.frequency);\n // the Q value\n this.Q.connect(this.low.Q);\n this.Q.connect(this._lowMidFilter.Q);\n this.Q.connect(this.mid.Q);\n this.Q.connect(this.high.Q);\n readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n Q: 1,\n highFrequency: 2500,\n lowFrequency: 400,\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n writable(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n this.low.dispose();\n this._lowMidFilter.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.lowFrequency.dispose();\n this.highFrequency.dispose();\n this.Q.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MultibandSplit.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/core/context/Listener.js\n\n\n\n/**\n * Tone.Listener is a thin wrapper around the AudioListener. Listener combined\n * with [[Panner3D]] makes up the Web Audio API\'s 3D panning system. Panner3D allows you\n * to place sounds in 3D and Listener allows you to navigate the 3D sound environment from\n * a first-person perspective. There is only one listener per audio context.\n */\nclass Listener extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(...arguments);\n this.name = "Listener";\n this.positionX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionX,\n });\n this.positionY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionY,\n });\n this.positionZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.positionZ,\n });\n this.forwardX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardX,\n });\n this.forwardY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardY,\n });\n this.forwardZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.forwardZ,\n });\n this.upX = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upX,\n });\n this.upY = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upY,\n });\n this.upZ = new Param_Param({\n context: this.context,\n param: this.context.rawContext.listener.upZ,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n forwardX: 0,\n forwardY: 0,\n forwardZ: -1,\n upX: 0,\n upY: 1,\n upZ: 0,\n });\n }\n dispose() {\n super.dispose();\n this.positionX.dispose();\n this.positionY.dispose();\n this.positionZ.dispose();\n this.forwardX.dispose();\n this.forwardY.dispose();\n this.forwardZ.dispose();\n this.upX.dispose();\n this.upY.dispose();\n this.upZ.dispose();\n return this;\n }\n}\n//-------------------------------------\n// \tINITIALIZATION\n//-------------------------------------\nonContextInit(context => {\n context.listener = new Listener({ context });\n});\nonContextClose(context => {\n context.listener.dispose();\n});\n//# sourceMappingURL=Listener.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Panner3D.js\n\n\n\n\n/**\n * A spatialized panner node which supports equalpower or HRTF panning.\n * @category Component\n */\nclass Panner3D extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]));\n this.name = "Panner3D";\n const options = optionsFromArguments(Panner3D.getDefaults(), arguments, ["positionX", "positionY", "positionZ"]);\n this._panner = this.input = this.output = this.context.createPanner();\n // set some values\n this.panningModel = options.panningModel;\n this.maxDistance = options.maxDistance;\n this.distanceModel = options.distanceModel;\n this.coneOuterGain = options.coneOuterGain;\n this.coneOuterAngle = options.coneOuterAngle;\n this.coneInnerAngle = options.coneInnerAngle;\n this.refDistance = options.refDistance;\n this.rolloffFactor = options.rolloffFactor;\n this.positionX = new Param({\n context: this.context,\n param: this._panner.positionX,\n value: options.positionX,\n });\n this.positionY = new Param({\n context: this.context,\n param: this._panner.positionY,\n value: options.positionY,\n });\n this.positionZ = new Param({\n context: this.context,\n param: this._panner.positionZ,\n value: options.positionZ,\n });\n this.orientationX = new Param({\n context: this.context,\n param: this._panner.orientationX,\n value: options.orientationX,\n });\n this.orientationY = new Param({\n context: this.context,\n param: this._panner.orientationY,\n value: options.orientationY,\n });\n this.orientationZ = new Param({\n context: this.context,\n param: this._panner.orientationZ,\n value: options.orientationZ,\n });\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: "inverse",\n maxDistance: 10000,\n orientationX: 0,\n orientationY: 0,\n orientationZ: 0,\n panningModel: "equalpower",\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n refDistance: 1,\n rolloffFactor: 1,\n });\n }\n /**\n * Sets the position of the source in 3d space.\n */\n setPosition(x, y, z) {\n this.positionX.value = x;\n this.positionY.value = y;\n this.positionZ.value = z;\n return this;\n }\n /**\n * Sets the orientation of the source in 3d space.\n */\n setOrientation(x, y, z) {\n this.orientationX.value = x;\n this.orientationY.value = y;\n this.orientationZ.value = z;\n return this;\n }\n /**\n * The panning model. Either "equalpower" or "HRTF".\n */\n get panningModel() {\n return this._panner.panningModel;\n }\n set panningModel(val) {\n this._panner.panningModel = val;\n }\n /**\n * A reference distance for reducing volume as source move further from the listener\n */\n get refDistance() {\n return this._panner.refDistance;\n }\n set refDistance(val) {\n this._panner.refDistance = val;\n }\n /**\n * Describes how quickly the volume is reduced as source moves away from listener.\n */\n get rolloffFactor() {\n return this._panner.rolloffFactor;\n }\n set rolloffFactor(val) {\n this._panner.rolloffFactor = val;\n }\n /**\n * The distance model used by, "linear", "inverse", or "exponential".\n */\n get distanceModel() {\n return this._panner.distanceModel;\n }\n set distanceModel(val) {\n this._panner.distanceModel = val;\n }\n /**\n * The angle, in degrees, inside of which there will be no volume reduction\n */\n get coneInnerAngle() {\n return this._panner.coneInnerAngle;\n }\n set coneInnerAngle(val) {\n this._panner.coneInnerAngle = val;\n }\n /**\n * The angle, in degrees, outside of which the volume will be reduced\n * to a constant value of coneOuterGain\n */\n get coneOuterAngle() {\n return this._panner.coneOuterAngle;\n }\n set coneOuterAngle(val) {\n this._panner.coneOuterAngle = val;\n }\n /**\n * The gain outside of the coneOuterAngle\n */\n get coneOuterGain() {\n return this._panner.coneOuterGain;\n }\n set coneOuterGain(val) {\n this._panner.coneOuterGain = val;\n }\n /**\n * The maximum distance between source and listener,\n * after which the volume will not be reduced any further.\n */\n get maxDistance() {\n return this._panner.maxDistance;\n }\n set maxDistance(val) {\n this._panner.maxDistance = val;\n }\n dispose() {\n super.dispose();\n this._panner.disconnect();\n this.orientationX.dispose();\n this.orientationY.dispose();\n this.orientationZ.dispose();\n this.positionX.dispose();\n this.positionY.dispose();\n this.positionZ.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Panner3D.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/channel/Recorder.js\n\n\n\n\n\n\n/**\n * A wrapper around the MediaRecorder API. Unlike the rest of Tone.js, this module does not offer\n * any sample-accurate scheduling because it is not a feature of the MediaRecorder API.\n * This is only natively supported in Chrome and Firefox.\n * For a cross-browser shim, install (audio-recorder-polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].\n * @example\n * const recorder = new Tone.Recorder();\n * const synth = new Tone.Synth().connect(recorder);\n * // start recording\n * recorder.start();\n * // generate a few notes\n * synth.triggerAttackRelease("C3", 0.5);\n * synth.triggerAttackRelease("C4", 0.5, "+1");\n * synth.triggerAttackRelease("C5", 0.5, "+2");\n * // wait for the notes to end and stop the recording\n * setTimeout(async () => {\n * \t// the recorded audio is returned as a blob\n * \tconst recording = await recorder.stop();\n * \t// download the recording by creating an anchor element and blob url\n * \tconst url = URL.createObjectURL(recording);\n * \tconst anchor = document.createElement("a");\n * \tanchor.download = "recording.webm";\n * \tanchor.href = url;\n * \tanchor.click();\n * }, 4000);\n * @category Component\n */\nclass Recorder extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Recorder.getDefaults(), arguments));\n this.name = "Recorder";\n const options = optionsFromArguments(Recorder.getDefaults(), arguments);\n this.input = new Gain({\n context: this.context\n });\n assert(Recorder.supported, "Media Recorder API is not available");\n this._stream = this.context.createMediaStreamDestination();\n this.input.connect(this._stream);\n this._recorder = new MediaRecorder(this._stream.stream, {\n mimeType: options.mimeType\n });\n }\n static getDefaults() {\n return ToneAudioNode.getDefaults();\n }\n /**\n * The mime type is the format that the audio is encoded in. For Chrome\n * that is typically webm encoded as "vorbis".\n */\n get mimeType() {\n return this._recorder.mimeType;\n }\n /**\n * Test if your platform supports the Media Recorder API. If it\'s not available,\n * try installing this (polyfill)[https://www.npmjs.com/package/audio-recorder-polyfill].\n */\n static get supported() {\n return theWindow !== null && Reflect.has(theWindow, "MediaRecorder");\n }\n /**\n * Get the playback state of the Recorder, either "started", "stopped" or "paused"\n */\n get state() {\n if (this._recorder.state === "inactive") {\n return "stopped";\n }\n else if (this._recorder.state === "paused") {\n return "paused";\n }\n else {\n return "started";\n }\n }\n /**\n * Start the Recorder. Returns a promise which resolves\n * when the recorder has started.\n */\n start() {\n return __awaiter(this, void 0, void 0, function* () {\n assert(this.state !== "started", "Recorder is already started");\n const startPromise = new Promise(done => {\n const handleStart = () => {\n this._recorder.removeEventListener("start", handleStart, false);\n done();\n };\n this._recorder.addEventListener("start", handleStart, false);\n });\n this._recorder.start();\n return yield startPromise;\n });\n }\n /**\n * Stop the recorder. Returns a promise with the recorded content until this point\n * encoded as [[mimeType]]\n */\n stop() {\n return __awaiter(this, void 0, void 0, function* () {\n assert(this.state !== "stopped", "Recorder is not started");\n const dataPromise = new Promise(done => {\n const handleData = (e) => {\n this._recorder.removeEventListener("dataavailable", handleData, false);\n done(e.data);\n };\n this._recorder.addEventListener("dataavailable", handleData, false);\n });\n this._recorder.stop();\n return yield dataPromise;\n });\n }\n /**\n * Pause the recorder\n */\n pause() {\n assert(this.state === "started", "Recorder must be started");\n this._recorder.pause();\n return this;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this._stream.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Recorder.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Compressor.js\n\n\n\n\n/**\n * Compressor is a thin wrapper around the Web Audio\n * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface).\n * Compression reduces the volume of loud sounds or amplifies quiet sounds\n * by narrowing or "compressing" an audio signal\'s dynamic range.\n * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression).\n * @example\n * const comp = new Tone.Compressor(-30, 3);\n * @category Component\n */\nclass Compressor_Compressor extends ToneAudioNode_ToneAudioNode {\n constructor() {\n super(Defaults_optionsFromArguments(Compressor_Compressor.getDefaults(), arguments, ["threshold", "ratio"]));\n this.name = "Compressor";\n /**\n * the compressor node\n */\n this._compressor = this.context.createDynamicsCompressor();\n this.input = this._compressor;\n this.output = this._compressor;\n const options = Defaults_optionsFromArguments(Compressor_Compressor.getDefaults(), arguments, ["threshold", "ratio"]);\n this.threshold = new Param_Param({\n minValue: this._compressor.threshold.minValue,\n maxValue: this._compressor.threshold.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.threshold,\n units: "decibels",\n value: options.threshold,\n });\n this.attack = new Param_Param({\n minValue: this._compressor.attack.minValue,\n maxValue: this._compressor.attack.maxValue,\n context: this.context,\n param: this._compressor.attack,\n units: "time",\n value: options.attack,\n });\n this.release = new Param_Param({\n minValue: this._compressor.release.minValue,\n maxValue: this._compressor.release.maxValue,\n context: this.context,\n param: this._compressor.release,\n units: "time",\n value: options.release,\n });\n this.knee = new Param_Param({\n minValue: this._compressor.knee.minValue,\n maxValue: this._compressor.knee.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.knee,\n units: "decibels",\n value: options.knee,\n });\n this.ratio = new Param_Param({\n minValue: this._compressor.ratio.minValue,\n maxValue: this._compressor.ratio.maxValue,\n context: this.context,\n convert: false,\n param: this._compressor.ratio,\n units: "positive",\n value: options.ratio,\n });\n // set the defaults\n Interface_readOnly(this, ["knee", "release", "attack", "ratio", "threshold"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode_ToneAudioNode.getDefaults(), {\n attack: 0.003,\n knee: 30,\n ratio: 12,\n release: 0.25,\n threshold: -24,\n });\n }\n /**\n * A read-only decibel value for metering purposes, representing the current amount of gain\n * reduction that the compressor is applying to the signal. If fed no signal the value will be 0 (no gain reduction).\n */\n get reduction() {\n return this._compressor.reduction;\n }\n dispose() {\n super.dispose();\n this._compressor.disconnect();\n this.attack.dispose();\n this.release.dispose();\n this.threshold.dispose();\n this.ratio.dispose();\n this.knee.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Compressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Gate.js\n\n\n\n\n\n\n/**\n * Gate only passes a signal through when the incoming\n * signal exceeds a specified threshold. It uses [[Follower]] to follow the ampltiude\n * of the incoming signal and compares it to the [[threshold]] value using [[GreaterThan]].\n *\n * @example\n * const gate = new Tone.Gate(-30, 0.2).toDestination();\n * const mic = new Tone.UserMedia().connect(gate);\n * // the gate will only pass through the incoming\n * // signal when it\'s louder than -30db\n * @category Component\n */\nclass Gate extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"])));\n this.name = "Gate";\n const options = optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"]);\n this._follower = new Follower({\n context: this.context,\n smoothing: options.smoothing,\n });\n this._gt = new GreaterThan({\n context: this.context,\n value: dbToGain(options.threshold),\n });\n this.input = new Gain({ context: this.context });\n this._gate = this.output = new Gain({ context: this.context });\n // connections\n this.input.connect(this._gate);\n // the control signal\n this.input.chain(this._follower, this._gt, this._gate.gain);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n smoothing: 0.1,\n threshold: -40\n });\n }\n /**\n * The threshold of the gate in decibels\n */\n get threshold() {\n return gainToDb(this._gt.value);\n }\n set threshold(thresh) {\n this._gt.value = dbToGain(thresh);\n }\n /**\n * The attack/decay speed of the gate. See [[Follower.smoothing]]\n */\n get smoothing() {\n return this._follower.smoothing;\n }\n set smoothing(smoothingTime) {\n this._follower.smoothing = smoothingTime;\n }\n dispose() {\n super.dispose();\n this.input.dispose();\n this._follower.dispose();\n this._gt.dispose();\n this._gate.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Gate.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/Limiter.js\n\n\n\n\n;\n/**\n * Limiter will limit the loudness of an incoming signal.\n * Under the hood it\'s composed of a [[Compressor]] with a fast attack\n * and release and max compression ratio.\n *\n * @example\n * const limiter = new Tone.Limiter(-20).toDestination();\n * const oscillator = new Tone.Oscillator().connect(limiter);\n * oscillator.start();\n * @category Component\n */\nclass Limiter extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"])));\n this.name = "Limiter";\n const options = optionsFromArguments(Limiter.getDefaults(), arguments, ["threshold"]);\n this._compressor = this.input = this.output = new Compressor({\n context: this.context,\n ratio: 20,\n attack: 0.003,\n release: 0.01,\n threshold: options.threshold\n });\n this.threshold = this._compressor.threshold;\n readOnly(this, "threshold");\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n threshold: -12\n });\n }\n /**\n * A read-only decibel value for metering purposes, representing the current amount of gain\n * reduction that the compressor is applying to the signal.\n */\n get reduction() {\n return this._compressor.reduction;\n }\n dispose() {\n super.dispose();\n this._compressor.dispose();\n this.threshold.dispose();\n return this;\n }\n}\n//# sourceMappingURL=Limiter.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/MidSideCompressor.js\n\n\n\n\n\n\n/**\n * MidSideCompressor applies two different compressors to the [[mid]]\n * and [[side]] signal components of the input. See [[MidSideSplit]] and [[MidSideMerge]].\n * @category Component\n */\nclass MidSideCompressor extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(MidSideCompressor.getDefaults(), arguments)));\n this.name = "MidSideCompressor";\n const options = optionsFromArguments(MidSideCompressor.getDefaults(), arguments);\n this._midSideSplit = this.input = new MidSideSplit({ context: this.context });\n this._midSideMerge = this.output = new MidSideMerge({ context: this.context });\n this.mid = new Compressor(Object.assign(options.mid, { context: this.context }));\n this.side = new Compressor(Object.assign(options.side, { context: this.context }));\n this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid);\n this._midSideSplit.side.chain(this.side, this._midSideMerge.side);\n readOnly(this, ["mid", "side"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n mid: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n side: {\n ratio: 6,\n threshold: -30,\n release: 0.25,\n attack: 0.03,\n knee: 10\n }\n });\n }\n dispose() {\n super.dispose();\n this.mid.dispose();\n this.side.dispose();\n this._midSideSplit.dispose();\n this._midSideMerge.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MidSideCompressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/dynamics/MultibandCompressor.js\n\n\n\n\n\n\n/**\n * A compressor with separate controls over low/mid/high dynamics. See [[Compressor]] and [[MultibandSplit]]\n *\n * @example\n * const multiband = new Tone.MultibandCompressor({\n * \tlowFrequency: 200,\n * \thighFrequency: 1300,\n * \tlow: {\n * \t\tthreshold: -12\n * \t}\n * });\n * @category Component\n */\nclass MultibandCompressor extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(Object.assign(optionsFromArguments(MultibandCompressor.getDefaults(), arguments)));\n this.name = "MultibandCompressor";\n const options = optionsFromArguments(MultibandCompressor.getDefaults(), arguments);\n this._splitter = this.input = new MultibandSplit({\n context: this.context,\n lowFrequency: options.lowFrequency,\n highFrequency: options.highFrequency\n });\n this.lowFrequency = this._splitter.lowFrequency;\n this.highFrequency = this._splitter.highFrequency;\n this.output = new Gain({ context: this.context });\n this.low = new Compressor(Object.assign(options.low, { context: this.context }));\n this.mid = new Compressor(Object.assign(options.mid, { context: this.context }));\n this.high = new Compressor(Object.assign(options.high, { context: this.context }));\n // connect the compressor\n this._splitter.low.chain(this.low, this.output);\n this._splitter.mid.chain(this.mid, this.output);\n this._splitter.high.chain(this.high, this.output);\n readOnly(this, ["high", "mid", "low", "highFrequency", "lowFrequency"]);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n lowFrequency: 250,\n highFrequency: 2000,\n low: {\n ratio: 6,\n threshold: -30,\n release: 0.25,\n attack: 0.03,\n knee: 10\n },\n mid: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n high: {\n ratio: 3,\n threshold: -24,\n release: 0.03,\n attack: 0.02,\n knee: 16\n },\n });\n }\n dispose() {\n super.dispose();\n this._splitter.dispose();\n this.low.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.output.dispose();\n return this;\n }\n}\n//# sourceMappingURL=MultibandCompressor.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/EQ3.js\n\n\n\n\n\n/**\n * EQ3 provides 3 equalizer bins: Low/Mid/High.\n * @category Component\n */\nclass EQ3 extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]));\n this.name = "EQ3";\n /**\n * the output\n */\n this.output = new Gain({ context: this.context });\n this._internalChannels = [];\n const options = optionsFromArguments(EQ3.getDefaults(), arguments, ["low", "mid", "high"]);\n this.input = this._multibandSplit = new MultibandSplit({\n context: this.context,\n highFrequency: options.highFrequency,\n lowFrequency: options.lowFrequency,\n });\n this._lowGain = new Gain({\n context: this.context,\n gain: options.low,\n units: "decibels",\n });\n this._midGain = new Gain({\n context: this.context,\n gain: options.mid,\n units: "decibels",\n });\n this._highGain = new Gain({\n context: this.context,\n gain: options.high,\n units: "decibels",\n });\n this.low = this._lowGain.gain;\n this.mid = this._midGain.gain;\n this.high = this._highGain.gain;\n this.Q = this._multibandSplit.Q;\n this.lowFrequency = this._multibandSplit.lowFrequency;\n this.highFrequency = this._multibandSplit.highFrequency;\n // the frequency bands\n this._multibandSplit.low.chain(this._lowGain, this.output);\n this._multibandSplit.mid.chain(this._midGain, this.output);\n this._multibandSplit.high.chain(this._highGain, this.output);\n readOnly(this, ["low", "mid", "high", "lowFrequency", "highFrequency"]);\n this._internalChannels = [this._multibandSplit];\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n high: 0,\n highFrequency: 2500,\n low: 0,\n lowFrequency: 400,\n mid: 0,\n });\n }\n /**\n * Clean up.\n */\n dispose() {\n super.dispose();\n writable(this, ["low", "mid", "high", "lowFrequency", "highFrequency"]);\n this._multibandSplit.dispose();\n this.lowFrequency.dispose();\n this.highFrequency.dispose();\n this._lowGain.dispose();\n this._midGain.dispose();\n this._highGain.dispose();\n this.low.dispose();\n this.mid.dispose();\n this.high.dispose();\n this.Q.dispose();\n return this;\n }\n}\n//# sourceMappingURL=EQ3.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/filter/Convolver.js\n\n\n\n\n\n\n/**\n * Convolver is a wrapper around the Native Web Audio\n * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface).\n * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on\n * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb).\n *\n * @example\n * // initializing the convolver with an impulse response\n * const convolver = new Tone.Convolver("./path/to/ir.wav").toDestination();\n * @category Component\n */\nclass Convolver extends (/* unused pure expression or super */ null && (ToneAudioNode)) {\n constructor() {\n super(optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]));\n this.name = "Convolver";\n /**\n * The native ConvolverNode\n */\n this._convolver = this.context.createConvolver();\n const options = optionsFromArguments(Convolver.getDefaults(), arguments, ["url", "onload"]);\n this._buffer = new ToneAudioBuffer(options.url, buffer => {\n this.buffer = buffer;\n options.onload();\n });\n this.input = new Gain({ context: this.context });\n this.output = new Gain({ context: this.context });\n // set if it\'s already loaded, set it immediately\n if (this._buffer.loaded) {\n this.buffer = this._buffer;\n }\n // initially set normalization\n this.normalize = options.normalize;\n // connect it up\n this.input.chain(this._convolver, this.output);\n }\n static getDefaults() {\n return Object.assign(ToneAudioNode.getDefaults(), {\n normalize: true,\n onload: noOp,\n });\n }\n /**\n * Load an impulse response url as an audio buffer.\n * Decodes the audio asynchronously and invokes\n * the callback once the audio buffer loads.\n * @param url The url of the buffer to load. filetype support depends on the browser.\n */\n load(url) {\n return __awaiter(this, void 0, void 0, function* () {\n this.buffer = yield this._buffer.load(url);\n });\n }\n /**\n * The convolver\'s buffer\n */\n get buffer() {\n if (this._buffer.length) {\n return this._buffer;\n }\n else {\n return null;\n }\n }\n set buffer(buffer) {\n if (buffer) {\n this._buffer.set(buffer);\n }\n // if it\'s already got a buffer, create a new one\n if (this._convolver.buffer) {\n // disconnect the old one\n this.input.disconnect();\n this._convolver.disconnect();\n // create and connect a new one\n this._convolver = this.context.createConvolver();\n this.input.chain(this._convolver, this.output);\n }\n const buff = this._buffer.get();\n this._convolver.buffer = buff ? buff : null;\n }\n /**\n * The normalize property of the ConvolverNode interface is a boolean that\n * controls whether the impulse response from the buffer will be scaled by\n * an equal-power normalization when the buffer attribute is set, or not.\n */\n get normalize() {\n return this._convolver.normalize;\n }\n set normalize(norm) {\n this._convolver.normalize = norm;\n }\n dispose() {\n super.dispose();\n this._buffer.dispose();\n this._convolver.disconnect();\n return this;\n }\n}\n//# sourceMappingURL=Convolver.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/component/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n//# sourceMappingURL=index.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/classes.js\n\n\n\n\n\n\n\n//# sourceMappingURL=classes.js.map\n;// CONCATENATED MODULE: ./node_modules/tone/build/esm/index.js\n\n\n\n\n\n\n\n/**\n * The current audio context time of the global [[Context]].\n * See [[Context.now]]\n * @category Core\n */\nfunction now() {\n return getContext().now();\n}\n/**\n * The current audio context time of the global [[Context]] without the [[Context.lookAhead]]\n * See [[Context.immediate]]\n * @category Core\n */\nfunction immediate() {\n return getContext().immediate();\n}\n/**\n * The Transport object belonging to the global Tone.js Context.\n * See [[Transport]]\n * @category Core\n */\nconst esm_Transport = Global_getContext().transport;\n/**\n * The Transport object belonging to the global Tone.js Context.\n * See [[Transport]]\n * @category Core\n */\nfunction getTransport() {\n return getContext().transport;\n}\n/**\n * The Destination (output) belonging to the global Tone.js Context.\n * See [[Destination]]\n * @category Core\n */\nconst esm_Destination = Global_getContext().destination;\n/**\n * @deprecated Use [[Destination]]\n */\nconst Master = Global_getContext().destination;\n/**\n * The Destination (output) belonging to the global Tone.js Context.\n * See [[Destination]]\n * @category Core\n */\nfunction getDestination() {\n return getContext().destination;\n}\n/**\n * The [[Listener]] belonging to the global Tone.js Context.\n * @category Core\n */\nconst esm_Listener = Global_getContext().listener;\n/**\n * The [[Listener]] belonging to the global Tone.js Context.\n * @category Core\n */\nfunction getListener() {\n return getContext().listener;\n}\n/**\n * Draw is used to synchronize the draw frame with the Transport\'s callbacks.\n * See [[Draw]]\n * @category Core\n */\nconst esm_Draw = Global_getContext().draw;\n/**\n * Get the singleton attached to the global context.\n * Draw is used to synchronize the draw frame with the Transport\'s callbacks.\n * See [[Draw]]\n * @category Core\n */\nfunction getDraw() {\n return getContext().draw;\n}\n/**\n * A reference to the global context\n * See [[Context]]\n */\nconst context = Global_getContext();\n/**\n * Promise which resolves when all of the loading promises are resolved.\n * Alias for static [[ToneAudioBuffer.loaded]] method.\n * @category Core\n */\nfunction loaded() {\n return ToneAudioBuffer.loaded();\n}\n// this fills in name changes from 13.x to 14.x\n\n\nconst Buffer = (/* unused pure expression or super */ null && (ToneAudioBuffer));\nconst Buffers = (/* unused pure expression or super */ null && (ToneAudioBuffers));\nconst BufferSource = (/* unused pure expression or super */ null && (ToneBufferSource));\n//# sourceMappingURL=index.js.map\n// EXTERNAL MODULE: ./src/lib/startAudioContext.js\nvar startAudioContext = __webpack_require__(631);\nvar startAudioContext_default = /*#__PURE__*/__webpack_require__.n(startAudioContext);\n;// CONCATENATED MODULE: ./src/lib/util.js\n\n\nvar isIphone = navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i);\nvar isIpad = navigator.userAgent.match(/iPad/i);\nvar isAndroid = navigator.userAgent.match(/Android/i);\nvar isMobile = isIphone || isIpad || isAndroid;\nvar isDesktop = !isMobile;\ndocument.body.classList.add(isMobile ? "mobile" : "desktop");\nvar browser = {\n isIphone: isIphone,\n isIpad: isIpad,\n isMobile: isMobile,\n isDesktop: isDesktop\n};\nvar choice = function choice(a) {\n return a[Math.floor(Math.random() * a.length)];\n};\nvar mod = function mod(n, m) {\n return n - m * Math.floor(n / m);\n};\nvar random = function random() {\n return Math.random();\n};\nvar rand = function rand(n) {\n return Math.random() * n;\n};\nvar randint = function randint(n) {\n return rand(n) | 0;\n};\nvar randrange = function randrange(a, b) {\n return a + rand(b - a);\n};\nvar randsign = function randsign() {\n return random() >= 0.5 ? -1 : 1;\n};\nvar randnullsign = function randnullsign() {\n var r = random();\n return r < 0.333 ? -1 : r < 0.666 ? 0 : 1;\n};\nfunction requestAudioContext(fn) {\n var container = document.createElement("div");\n var button = document.createElement("div");\n button.innerHTML = "Tap to start - please unmute your phone";\n Object.assign(container.style, {\n display: "block",\n position: "absolute",\n width: "100%",\n height: "100%",\n zIndex: "10000",\n top: "0px",\n left: "0px",\n backgroundColor: "rgba(0, 0, 0, 0.8)"\n });\n Object.assign(button.style, {\n display: "block",\n position: "absolute",\n left: "50%",\n top: "50%",\n padding: "20px",\n backgroundColor: "#7F33ED",\n color: "white",\n fontFamily: "monospace",\n borderRadius: "3px",\n transform: "translate3D(-50%,-50%,0)",\n textAlign: "center",\n lineHeight: "1.5",\n width: "150px"\n });\n container.appendChild(button);\n document.body.appendChild(container);\n startAudioContext_default().setContext(context);\n startAudioContext_default().on(button);\n startAudioContext_default().onStarted(function (_) {\n container.remove();\n fn();\n });\n}\n;// CONCATENATED MODULE: ./src/lib/output.js\n\nvar compressor = new Compressor_Compressor(-30, 3);\nvar gain = new Gain_Gain(0.3);\ncompressor.connect(gain);\ngain.toDestination();\n/* harmony default export */ const output = (compressor);\n;// CONCATENATED MODULE: ./src/lib/kalimba.js\n\n\n\nvar player_count = 4;\nvar player_index = 0;\nvar samples = [{\n root: 226,\n fn: "samples/380737__cabled-mess__sansula-01-a-raw.mp3"\n}, {\n root: 267,\n fn: "samples/380736__cabled-mess__sansula-02-c-raw.mp3"\n}, {\n root: 340,\n fn: "samples/380735__cabled-mess__sansula-03-e-raw.mp3"\n}, {\n root: 452,\n fn: "samples/380733__cabled-mess__sansula-06-a-02-raw.mp3"\n}\n// { root: 507, fn: \'samples/380734__cabled-mess__sansula-07-b-h-raw.wav\', },\n// { root: 535, fn: \'samples/380731__cabled-mess__sansula-08-c-raw.wav\', },\n// { root: 671, fn: \'samples/380732__cabled-mess__sansula-09-e-raw.wav\', },\n];\n\nsamples.forEach(function (sample) {\n sample.players = [];\n sample.index = -1;\n for (var i = 0; i < player_count; i++) {\n var fn = sample.fn;\n if (window.location.href.match(/asdf.us/)) {\n fn = "//asdf.us/kalimba/" + fn;\n }\n var player = new Player_Player({\n url: fn,\n retrigger: true,\n playbackRate: 1\n });\n player.connect(output);\n sample.players.push(player);\n }\n});\nfunction play(freq, time) {\n var best = choice(samples);\n best.index = (best.index + 1) % player_count;\n var player = best.players[best.index];\n player.playbackRate = freq / best.root;\n player.start(time || 0);\n}\nfunction pause() {\n // no-op\n}\n/* harmony default export */ const kalimba = ({\n play: play,\n pause: pause\n});\n;// CONCATENATED MODULE: ./src/relabi/index.js\nfunction _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }\nfunction _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n\n\n\nvar TWO_PI = 2 * Math.PI;\n\n/**\n * Wave functions\n */\nvar WAVE_FUNCTIONS = {\n sine: Math.cos,\n triangle: function triangle(time) {\n return 4 / TWO_PI * Math.abs(((time - TWO_PI / 4) % TWO_PI + TWO_PI) % TWO_PI - TWO_PI / 2) - 1;\n },\n square: function square(time) {\n return time % TWO_PI < Math.PI ? 1 : -1;\n },\n saw: function saw(time) {\n return (time % TWO_PI - Math.PI) / Math.PI;\n }\n};\nvar Relabi = /*#__PURE__*/function () {\n /**\n * Initialize relabi generator\n */\n function Relabi() {\n _classCallCheck(this, Relabi);\n this.updateTime = 1.0;\n this.steps = 100;\n this.waves = [{\n type: "sine",\n frequency: randrange(0.5, 2)\n }, {\n type: "sine",\n frequency: randrange(0.5, 2)\n }, {\n type: "sine",\n frequency: randrange(1, 10)\n }, {\n type: "sine",\n frequency: randrange(5, 10)\n }];\n this.bounds = [-0.5, 0.5];\n this.frequencies = [220, 220 * 3 / 2, 440, 440 * 3 / 2];\n }\n\n /**\n * Start the generator\n */\n _createClass(Relabi, [{\n key: "start",\n value: function start() {\n var _this = this;\n console.log("Start Relabi");\n this.stop();\n this.clock = new Clock_Clock(function (time) {\n return _this.step(time);\n }, this.updateTime);\n this.clock.start();\n }\n\n /**\n * Stop the generator and reset it\n */\n }, {\n key: "stop",\n value: function stop() {\n if (this.clock) {\n this.clock.stop();\n this.clock.dispose();\n }\n }\n\n /**\n * Generate relabi events\n */\n }, {\n key: "step",\n value: function step(time) {\n var waveCount = this.waves.length;\n var boundsCount = this.bounds.length;\n var previousValue = this.previousValue;\n var index;\n var step;\n var value;\n var noteCount = 0;\n\n // Generate several events per second\n for (step = 0; step < this.steps; step += 1) {\n // Time offset for this event\n var offset = time + step * this.updateTime / this.steps;\n\n // Initialize value\n value = 0;\n\n // Compute the wave functions for this event\n for (index = 0; index < waveCount; index += 1) {\n var wave = this.waves[index];\n value += WAVE_FUNCTIONS[wave.type](offset * wave.frequency);\n }\n\n // Scale to [-1, 1]\n value /= waveCount / Math.PI;\n\n // Compute whether we crossed a boundary, and which direction\n for (index = 0; index < boundsCount; index += 1) {\n var bound = this.bounds[index];\n if (value < bound && bound < previousValue) {\n // Going down\n this.trigger(offset, index * 2);\n noteCount += 1;\n } else if (value > bound && bound > previousValue) {\n // Going up\n this.trigger(offset, index * 2 + 1);\n noteCount += 1;\n }\n }\n\n // Update the previous value\n previousValue = value;\n }\n\n // Store the latest value\n this.previousValue = value;\n console.log("Tick ".concat(Math.floor(time), ", played ").concat(noteCount, " notes"));\n }\n\n /**\n * Trigger an event\n */\n }, {\n key: "trigger",\n value: function trigger(time, index) {\n // console.log("trigger index", index, time);\n kalimba.play(this.frequencies[index], time);\n }\n }]);\n return Relabi;\n}();\n/* harmony default export */ const src_relabi = (Relabi);\n;// CONCATENATED MODULE: ./src/index.jsx\n\n\n\n\ndocument.body.style.backgroundColor = "#111";\ndocument.body.style.color = "#fff";\nrequestAudioContext(function () {\n document.body.innerHTML = \'<div id="app"></div>\';\n var relabi = new src_relabi();\n relabi.start();\n var root = (0,client/* createRoot */.s)(document.getElementById("app"));\n root.render( /*#__PURE__*/react.createElement("h1", null, "Relabi generator"));\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjA5LmpzIiwibWFwcGluZ3MiOiI7Ozs7OztBQUFPO0FBQ1AsbUM7Ozs7QUNETztBQUNQLHVDOztBQ0RPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRTs7QUNMTztBQUNQO0FBQ0E7QUFDQSx3QkFBd0Isb0NBQW9DO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxzRDs7QUNkTztBQUNQO0FBQ0EscURBQXFELHFGQUFxRjtBQUMxSTtBQUNBO0FBQ0EsdUQ7O0FDTE87QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNQO0FBQ087QUFDQTtBQUNQLG1DOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksY0FBYztBQUMxQixZQUFZLGdDQUFnQztBQUM1QztBQUNBLDJCQUEyQixjQUFjO0FBQ3pDLDJCQUEyQixnQ0FBZ0M7QUFDM0Q7QUFDQTtBQUNBLG9GQUFvRixpRkFBaUYsOEdBQThHLElBQUk7QUFDaFI7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBLG1EOztBQzVCcUU7QUFDUDtBQUNhO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsZUFBZTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0EsNENBQTRDLHFCQUFxQjtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBFQUEwRSxxQkFBcUI7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLGtCQUFrQixTQUFTLCtGQUErRixFQUFFO0FBQ3JLLENBQUMsRUFBRTtBQUNIO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0EsOERBQThELDJDQUEyQztBQUN6RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDJDQUEyQztBQUNuRTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEVBQTBFLHFCQUFxQjtBQUMvRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTRELGtCQUFrQixjQUFjLFFBQVEsd0dBQXdHO0FBQzVNO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCLG1FQUFtRSxHQUFHO0FBQ3RFLG9CQUFvQjtBQUNwQix5QkFBeUIsK0JBQStCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0EsNkNBQTZDLGFBQWE7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0EsMkhBQTJIO0FBQzNIO0FBQ0E7QUFDQSwyQ0FBMkMsb0JBQW9CLDJCQUEyQjtBQUMxRix5Q0FBeUMsa0JBQWtCLDZDQUE2QyxFQUFFO0FBQzFHLENBQUMsSUFBSSw2QkFBNkIsNENBQTRDLEVBQUUsaUJBQWlCLGVBQWUsRUFBRSxtQkFBbUIsa0VBQWtFLEdBQUcsMEJBQTBCLGFBQWEsc0NBQXNDLFVBQVUsV0FBVztBQUM1Uyx5REFBeUQsK0JBQStCLGdCQUFnQjtBQUN4RztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnSEFBZ0gsYUFBYSxJQUFJO0FBQ2pJO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLG9EOztBQzVOTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDOztBQ1BPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEOztBQ1pxRDtBQUNRO0FBQ3REO0FBQ1Asb0NBQW9DLGNBQWM7QUFDbEQsK0JBQStCLGtCQUFrQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUU7O0FDVjZDO0FBQ1E7QUFDOUM7QUFDUCxXQUFXLGNBQWMsQ0FBQyxlQUFlO0FBQ3pDO0FBQ0EsNkQ7O0FDTHFEO0FBQzhCO0FBQzVFO0FBQ1AsUUFBUSwyQkFBMkI7QUFDbkM7QUFDQTtBQUNBLElBQUksMkJBQTJCO0FBQy9CLElBQUksNEJBQTRCO0FBQ2hDO0FBQ0Esd0Q7O0FDVE87QUFDUDtBQUNBO0FBQ0EsOEM7O0FDSHFEO0FBQzhCO0FBQzVFO0FBQ1AsU0FBUywyQkFBMkI7QUFDcEM7QUFDQTtBQUNBLElBQUksaUNBQThCO0FBQ2xDLElBQUksNEJBQTRCO0FBQ2hDO0FBQ0EseUQ7O0FDVGtFO0FBQ1U7QUFDNUU7QUFDTztBQUNQLFNBQVMsa0JBQWtCO0FBQzNCLFFBQVEseUJBQXlCO0FBQ2pDO0FBQ0E7QUFDQSx3RTs7QUNSbUg7QUFDaEM7QUFDOEI7QUFDMUc7QUFDUDtBQUNBO0FBQ0EsZ0JBQWdCLDhCQUE4QjtBQUM5QyxnQkFBZ0IsVUFBVTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHVDQUF1QztBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLHdCQUF3QjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHNDQUFzQztBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsc0NBQXNDO0FBQ2xFO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0Q7O0FDNURPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRTs7QUNYTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRDs7QUNqQk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUQ7O0FDeEVPO0FBQ1A7QUFDQTtBQUNBLCtDOztBQ0hrRTtBQUMzRDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsZ0JBQWdCO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEOztBQ25DTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Rjs7QUNUTztBQUNQLDRDOztBQ0RxRTtBQUM5RDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLG9CQUFvQjtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLHFFOztBQ2hCOEk7QUFDbkM7QUFDM0csTUFBTSx3Q0FBZTtBQUNyQjtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsdUNBQXVDLElBQUksR0FBRyx3Q0FBZTtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsc0NBQXNDO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixtQ0FBbUM7QUFDbkQ7QUFDQTtBQUNBLHNDQUFzQyxtREFBbUQsUUFBUSxtREFBbUQ7QUFDcEo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0Q7O0FDbkRPO0FBQ0E7QUFDUCxxQzs7QUNGcUQ7QUFDOUMseUNBQXlDLDJCQUEyQjtBQUMzRSxnRDs7QUNGc0Y7QUFDbEI7QUFDZTtBQUNFO0FBQ3JGLE1BQU0sb0RBQWU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxHQUFHLG9EQUFlO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkdBQTZHLDBCQUEwQixFQUFFLDBCQUEwQjtBQUNuSztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHdCQUF3QjtBQUN4QztBQUNBO0FBQ0Esd0JBQXdCLGlCQUFpQjtBQUN6Qyx3QkFBd0IseUJBQXlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0U7O0FDdEdrRTtBQUMzRDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLGdCQUFnQjtBQUNoRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRTs7QUM5RE87QUFDUDtBQUNBO0FBQ0Esb0Q7O0FDSE87QUFDUDtBQUNBO0FBQ0EsOEM7O0FDSE87QUFDUDtBQUNBO0FBQ0EsZ0Q7O0FDSE87QUFDUDtBQUNBO0FBQ0EscUM7O0FDSE87QUFDUDtBQUNBO0FBQ0EsMkM7O0FDSE87QUFDUDtBQUNBO0FBQ0EsOEM7O0FDSDBEO0FBQ0w7QUFDOUM7QUFDUCxXQUFXLGNBQWMsQ0FBQyw0QkFBNEI7QUFDdEQ7QUFDQSxzRDs7QUNMMkQ7QUFDTjtBQUM5QztBQUNQLFdBQVcsY0FBYyxDQUFDLDZCQUE2QjtBQUN2RDtBQUNBLHVEOztBQ0w2RTtBQUNYO0FBQ0E7QUFDSTtBQUNyQjtBQUNZO0FBQ0s7QUFDSztBQUNFO0FBQ2Q7QUFDaUI7QUFDckU7QUFDUCxZQUFZLGVBQWUsRUFBRSx1QkFBdUI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsd0JBQXdCLHVCQUF1QjtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsa0JBQWtCO0FBQzVCO0FBQ0EsY0FBYyxrQkFBa0I7QUFDaEM7QUFDQSxrQkFBa0Isb0JBQW9CO0FBQ3RDO0FBQ0Esc0JBQXNCLFVBQVU7QUFDaEM7QUFDQSwwQkFBMEIsZ0JBQWdCO0FBQzFDO0FBQ0EsOEJBQThCLGtCQUFrQjtBQUNoRDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0Msd0JBQXdCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxpQkFBaUI7QUFDekIsUUFBUSx5QkFBeUI7QUFDakM7QUFDQTtBQUNBLDBFOztBQzlDNkc7QUFDdEc7QUFDUCxJQUFJLHlDQUF5QztBQUM3QztBQUNBLGtEOztBQ0pPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRDs7QUNMeUU7QUFDSDtBQUMvRDtBQUNQO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQywyREFBMkQsb0JBQW9CO0FBQy9FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixjQUFjO0FBQ2xDLG9CQUFvQixhQUFhO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isb0JBQW9CO0FBQ3BDLGFBQWE7QUFDYjtBQUNBO0FBQ0Esc0VBQXNFLGNBQWM7QUFDcEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRSxhQUFhO0FBQ2xGO0FBQ0E7QUFDQSwwRUFBMEUsa0JBQWtCO0FBQzVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLHFEOztBQ3ZKTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEQ7O0FDekNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1FOztBQ2xCc0Y7QUFDL0U7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0RBQXdELGFBQWE7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUVBQXVFO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRUFBZ0U7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVFQUF1RTtBQUN2RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzREFBc0QsU0FBUyx3Q0FBd0MsMEJBQTBCLEVBQUUsMEJBQTBCO0FBQzdKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLCtFQUErRTtBQUMvRjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRDs7QUNsT087QUFDUDtBQUNBO0FBQ0Esc0M7O0FDSDJDO0FBQ3BDO0FBQ1AsV0FBVyxXQUFXO0FBQ3RCO0FBQ0Esd0Q7O0FDSk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUQ7O0FDWjZEO0FBQ3REO0FBQ1AsSUFBSSxrQkFBa0I7QUFDdEI7QUFDQSxzRTs7QUNKNkQ7QUFDdEQ7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxrQkFBa0I7QUFDMUI7QUFDQTtBQUNBLHVFOztBQ1ZPO0FBQ1A7QUFDQTtBQUNBLG1EOztBQ0gyRTtBQUNwRTtBQUNQLFFBQVEsc0JBQXNCO0FBQzlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEU7O0FDVk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEQ7O0FDVDZEO0FBQ3REO0FBQ1AsV0FBVyxrQkFBa0I7QUFDN0I7QUFDQSx5RTs7QUNKbUY7QUFDNUU7QUFDUCwyQkFBMkIsNEJBQTRCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0U7O0FDUHFEO0FBQ1E7QUFDdEQ7QUFDUCxvQ0FBb0MsY0FBYztBQUNsRCwrQkFBK0Isa0JBQWtCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRTs7QUNWMkU7QUFDcEU7QUFDUCxRQUFRLHNCQUFzQjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRTs7QUNUOEM7QUFDTztBQUM5QztBQUNQLFdBQVcsY0FBYyxDQUFDLGdCQUFnQjtBQUMxQztBQUNBLGlEOztBQ0wrQztBQUNNO0FBQzlDO0FBQ1AsV0FBVyxjQUFjLENBQUMsaUJBQWlCO0FBQzNDO0FBQ0Esa0Q7O0FDTDRDO0FBQ3JDO0FBQ1AsV0FBVyxrQkFBa0I7QUFDN0I7QUFDQSw4Qzs7QUNKcUQ7QUFDOUM7QUFDUCxZQUFZLDJCQUEyQjtBQUN2QztBQUNBLGlEOztBQ0pPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0ZBQWtGO0FBQ2xGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUU7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0Q7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLHFFOztBQ3pDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEOztBQ1ZPO0FBQ1A7QUFDQTtBQUNBLDZDOztBQ0hnRTtBQUN6RDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGlCQUFpQjtBQUNqRDtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsZUFBZTtBQUMvRDtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsZUFBZTtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsaUJBQWlCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDZEOztBQ25FK0Q7QUFDWjtBQUNrQztBQUN3QjtBQUNFO0FBQ0s7QUFDNUI7QUFDMkI7QUFDbEI7QUFDa0I7QUFDRTtBQUNTO0FBQzlDO0FBQ0U7QUFDVTtBQUN0QjtBQUNFO0FBQ0Y7QUFDRjtBQUNMO0FBQ087QUFDYTtBQUM4QjtBQUNMO0FBQzdCO0FBQ2M7QUFDN0Y7QUFDQSxZQUFZLDhCQUE4QixFQUFFLHdCQUF3QjtBQUNwRSxZQUFZLFVBQVUsRUFBRSx1QkFBdUI7QUFDL0MsMkJBQTJCLDRCQUE0QjtBQUN2RDtBQUNBLGdDQUFnQyxrQkFBa0I7QUFDbEQsaUNBQWlDLG1CQUFtQjtBQUNwRDtBQUNBLHNDQUFzQyx3Q0FBd0M7QUFDOUUsWUFBWSxvQ0FBb0M7QUFDaEQsK0JBQStCLGNBQWM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsdUNBQXVDO0FBQzdFLFlBQVkscUNBQXFDO0FBQ2pELCtCQUErQixjQUFjO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxrQkFBa0I7QUFDMUI7QUFDQSxZQUFZLGlCQUFpQjtBQUM3QixZQUFZLG9DQUFvQztBQUNoRDtBQUNBO0FBQ0EsWUFBWSxxQ0FBcUM7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSw4QkFBOEIsRUFBRSx1QkFBdUI7QUFDbkUsa0NBQWtDLDJCQUEyQjtBQUM3RDtBQUNBLHVDQUF1Qyx1Q0FBdUM7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksOEJBQThCLEVBQUUsd0JBQXdCO0FBQ3BFLGtDQUFrQywyQkFBMkI7QUFDN0Q7QUFDQSx1Q0FBdUMsd0NBQXdDO0FBQy9FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSw4QkFBOEI7QUFDdEMsdUNBQXVDLGNBQWM7QUFDckQsWUFBWSw0Q0FBNEMsQ0FBQyxrQkFBa0IsVUFBVSxrQkFBa0I7QUFDdkc7QUFDQTtBQUNBLFFBQVEsaUJBQWlCO0FBQ3pCLGdCQUFnQixlQUFlLEVBQUUsdUJBQXVCO0FBQ3hELFFBQVEsc0NBQXNDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDhCQUE4QjtBQUN0Qyx1Q0FBdUMsY0FBYztBQUNyRCxZQUFZLGtCQUFrQixvQkFBb0IsbUJBQW1CO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLHVCQUF1QjtBQUNoRTtBQUNBO0FBQ0EsWUFBWSwyQkFBMkI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5Qyx1QkFBdUI7QUFDaEU7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLDJCQUEyQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUMsdUJBQXVCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDJCQUEyQjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLG9DQUFvQztBQUN4RSwrQkFBK0Isb0NBQW9DO0FBQ25FLHFCQUFxQjtBQUNyQixnQkFBZ0IsNkJBQTZCO0FBQzdDO0FBQ0EsWUFBWSxvQkFBb0I7QUFDaEMsWUFBWSxtQkFBbUI7QUFDL0I7QUFDQSxnQkFBZ0Isd0JBQXdCO0FBQ3hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsV0FBVztBQUMzQixtREFBbUQsa0JBQWtCO0FBQ3JFO0FBQ0EsdUNBQXVDLHVDQUF1QztBQUM5RSxzQ0FBc0Msa0JBQWtCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBLHlFQUF5RSxrQkFBa0I7QUFDM0Ysd0JBQXdCLHdCQUF3QjtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixzQkFBc0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLG1CQUFtQjtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyxrQkFBa0I7QUFDbkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixzQkFBc0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsV0FBVztBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixzQkFBc0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRDs7QUMxU3dEO0FBQ2pEO0FBQ1A7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLDBCQUFtQjtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxnQ0FBZ0M7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0M7O0FDM0tPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsaUJBQWlCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixpQkFBaUI7QUFDN0M7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLGtDQUFrQztBQUM5RDtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsbUJBQW1CO0FBQy9DO0FBQ0E7QUFDQTtBQUNBLDRCQUE0Qiw4QkFBOEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0Q7O0FDL0JPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUMxQnFFO0FBQ3RCO0FBQy9DLE1BQU0sOENBQWU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRUFBb0UsR0FBRyw4Q0FBZSxjQUFjO0FBQ3BHO0FBQ0E7QUFDQSxzREFBc0QsMkNBQTJDO0FBQ2pHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxtQ0FBbUMsV0FBVztBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixlQUFlO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRDs7QUM1RU87QUFDUCw4REFBOEQ7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkM7O0FDdkJPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDOztBQ2ZPO0FBQ1A7QUFDQSxvQkFBb0IsT0FBTztBQUMzQjtBQUNBO0FBQ0Esd0JBQXdCLFlBQVk7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0Q7O0FDWm9EO0FBQ1M7QUFDUjtBQUM5QztBQUNQLCtCQUErQixjQUFjLENBQUMsc0JBQXNCO0FBQ3BFLG1DQUFtQyxrQkFBa0I7QUFDckQsV0FBVyxjQUFjO0FBQ3pCO0FBQ0EsdUQ7O0FDUitEO0FBQ0o7QUFDVTtBQUNXO0FBQ0U7QUFDaEI7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLHVCQUF1QjtBQUN4RCx3Q0FBd0Msd0JBQXdCO0FBQ2hFLG1CQUFtQixrQkFBa0I7QUFDckMsb0JBQW9CLGtCQUFrQjtBQUN0Qyx1RkFBdUYsMENBQTBDLEtBQUs7QUFDdEksb0JBQW9CLFlBQVk7QUFDaEM7QUFDQSw0QkFBNEIsNEJBQTRCO0FBQ3hELGdDQUFnQywwQkFBMEI7QUFDMUQsb0JBQW9CLGVBQWU7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsTUFBTTtBQUN2RSxnQkFBZ0IsZUFBZTtBQUMvQixhQUFhO0FBQ2I7QUFDQSx3QkFBd0IsNEJBQTRCO0FBQ3BELDRCQUE0QiwyQkFBMkI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxxRUFBcUUsNkJBQTZCO0FBQ2xHLG9DQUFvQywyQkFBMkI7QUFDL0Qsd0JBQXdCLGFBQWE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQsZ0JBQWdCO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxnQ0FBZ0MsMkJBQTJCO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyw0QkFBNEI7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6Qix3Q0FBd0MsNEJBQTRCO0FBQ3BFO0FBQ0EsNENBQTRDLDBCQUEwQjtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFQUFxRSwyQkFBMkI7QUFDaEc7QUFDQSxvQ0FBb0MsMkJBQTJCO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRDs7QUMvT087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELHNDQUFzQztBQUN0RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTRELGdCQUFnQjtBQUM1RTtBQUNBO0FBQ0EsOERBQThELGlCQUFpQjtBQUMvRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9ELGNBQWM7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCx1QkFBdUI7QUFDL0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1REFBdUQsNkJBQTZCO0FBQ3BGLHVEQUF1RCw0QkFBNEI7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsMEQ7O0FDbkZzRjtBQUN0RixNQUFNLDhDQUFlO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLEdBQUcsOENBQWU7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtGQUFrRiwwQkFBMEIsRUFBRSwwQkFBMEI7QUFDeEk7QUFDQSw2R0FBNkcsMEJBQTBCLHFCQUFxQiwwQkFBMEI7QUFDdEw7QUFDQTtBQUNBO0FBQ0Esd0dBQXdHLDBCQUEwQixHQUFHLDBCQUEwQjtBQUMvSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEOztBQ3BFa0U7QUFDM0Q7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELGdCQUFnQjtBQUMzRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtEOztBQ25ETztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkM7O0FDL0JBLE1BQU0sK0NBQWU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLEdBQUcsK0NBQWU7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkQ7O0FDakJrRTtBQUMzRDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsZ0JBQWdCO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFOztBQ2hDQSxNQUFNLGlEQUFlO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBLG1FQUFtRSxHQUFHLGlEQUFlLGNBQWM7QUFDbkc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkQ7O0FDakJrRTtBQUMzRDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvREFBb0QsZ0JBQWdCO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFOztBQ2hDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0M7O0FDTGdFO0FBQ3pEO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQWlCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvRDs7QUNiTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2RTs7QUN2QnNGO0FBQ2xCO0FBQ2U7QUFDRTtBQUNyRixNQUFNLGdEQUFlO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxHQUFHLGdEQUFlO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEZBQThGLDBCQUEwQixFQUFFLDBCQUEwQjtBQUNwSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHdCQUF3QjtBQUN4QztBQUNBO0FBQ0Esd0JBQXdCLGlCQUFpQjtBQUN6Qyx3QkFBd0IseUJBQXlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEQ7O0FDaEVrRTtBQUMzRDtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkRBQTZELGdCQUFnQjtBQUM3RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUU7O0FDdkRPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEOztBQ05BLE1BQU0sMENBQWU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsR0FBRywwQ0FBZTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0Q7O0FDbEQyRTtBQUNUO0FBQzNEO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxnQkFBZ0I7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixzQkFBc0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkQ7O0FDdkNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRDs7QUNqQk87QUFDUCw0Qzs7QUNETztBQUNQLFlBQVksZUFBZTtBQUMzQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsK0M7O0FDckJtRTtBQUN3QztBQUNwRztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixpQkFBaUI7QUFDakM7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixpQkFBaUI7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixtQ0FBbUM7QUFDM0Q7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSw2Qzs7QUMzRXFGO0FBQzlFO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixVQUFVO0FBQ2xDO0FBQ0Esd0JBQXdCLDJCQUEyQjtBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRDs7QUMvQkEsTUFBTSxzQ0FBZTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxHQUFHLHNDQUFlO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEOztBQ3hCa0U7QUFDM0Q7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0RBQW9ELGdCQUFnQjtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEOztBQ3ZDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0U7O0FDTE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFOztBQ0xPO0FBQ1A7QUFDQTtBQUNBLHNDOztBQ0htRDtBQUNBO0FBQzVDO0FBQ1A7QUFDQSwwQkFBMEIsV0FBVztBQUNyQyxZQUFZLFdBQVc7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixVQUFVO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUNwQmdFO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQWlCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1RDs7QUMvQkEsTUFBTSxvREFBZTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxHQUFHLG9EQUFlO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFOztBQzlFa0U7QUFDM0Q7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFLGdCQUFnQjtBQUNqRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRTs7QUNyRE87QUFDUCwwQzs7QUNETztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0ZBQXNGO0FBQ3RGLDhDQUE4QyxnQ0FBZ0M7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsMkM7O0FDaERPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EOztBQzNCTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUU7O0FDM0JPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLHdDOztBQ2RzRjtBQUN0RixNQUFNLHFDQUFlO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxHQUFHLHFDQUFlO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRkFBZ0YsMEJBQTBCLEVBQUUsMEJBQTBCO0FBQ3RJO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEOztBQ3hCa0U7QUFDM0Q7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELGdCQUFnQjtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRDs7QUN0Q087QUFDUDtBQUNBO0FBQ0EsZ0U7O0FDSE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUQ7O0FDVE87QUFDUCw0QkFBNEIsUUFBUTtBQUNwQztBQUNBLG9EOztBQ0hPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EOztBQ1RPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0RDs7QUNMTztBQUNQLCtDOztBQ0RnRTtBQUN6RDtBQUNQO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQix1QkFBdUI7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Qzs7QUNWTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRTs7QUNmTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4RDs7QUNUTztBQUNQLGdEOztBQ0Q2RTtBQUN0RTtBQUNQO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQix3QkFBd0I7QUFDOUM7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsOEU7O0FDWDRIO0FBQzVILE1BQU0sMkNBQWU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLEdBQUcsMkNBQWU7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksMkNBQTJDO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEOztBQzNCQTtBQUNBO0FBQ0EsSUFBSSw4SUFBOEk7QUFDM0k7QUFDUDtBQUNBO0FBQ0Esb0JBQW9CLGlCQUFpQjtBQUNyQztBQUNBLHdCQUF3QixlQUFlO0FBQ3ZDLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsdUJBQXVCO0FBQ3ZELHlFQUF5RTtBQUN6RTtBQUNBLGdDQUFnQyxvQkFBb0I7QUFDcEQsc0VBQXNFO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDOztBQzFCd0Q7QUFDVTtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixvQkFBb0I7QUFDNUM7QUFDQTtBQUNBLHdCQUF3Qix1QkFBdUI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixzQkFBc0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQVk7QUFDcEI7QUFDQTtBQUNBO0FBQ087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RCxnQkFBZ0I7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0RDs7QUM1RnFGO0FBQzlFO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLFVBQVU7QUFDdEM7QUFDQSw0QkFBNEIsMkJBQTJCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRDs7QUM1Qk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0Q7O0FDTk87QUFDUDtBQUNBO0FBQ0EsNkM7O0FDSE87QUFDUDtBQUNBO0FBQ0EsOEM7O0FDSE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0Q7O0FDTk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1EOztBQ0xPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRDs7QUNMTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUQ7O0FDTE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDOztBQ0xPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRDs7QUNMTztBQUNQLDZDOztBQ0RPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1RTs7QUNqQkEsTUFBTSwrREFBZTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsR0FBRywrREFBZTtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyRTs7QUN2Qk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFOztBQ2pCTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0RTs7QUNUeUU7QUFDSDtBQUMvRDtBQUNQO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGtCQUFrQjtBQUNuQywyREFBMkQsb0JBQW9CO0FBQy9FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixjQUFjO0FBQ2xDLG9CQUFvQixhQUFhO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isb0JBQW9CO0FBQ3BDLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSw2RDs7QUMzSTJDO0FBQ3BDO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGlCQUFpQjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRTs7QUN4Q087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEOztBQ3JCeUU7QUFDSjtBQUNyRSxNQUFNLHlEQUFlO0FBQ3JCO0FBQ0E7QUFDTztBQUNQO0FBQ0E7QUFDQSxvQkFBb0IsdUNBQXVDLElBQUksR0FBRyx5REFBZTtBQUNqRjtBQUNBO0FBQ0EsaUNBQWlDLGtCQUFrQixRQUFRLGtCQUFrQjtBQUM3RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLG9CQUFvQjtBQUNwQyxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFFOztBQ3BFTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsK0M7O0FDbEVPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEOztBQ05nRjtBQUN6RTtBQUNQLElBQUksMkJBQTJCO0FBQy9CLElBQUksMkJBQTJCO0FBQy9CLElBQUksMkJBQTJCO0FBQy9CO0FBQ0EsNEQ7O0FDTk87QUFDUDtBQUNBO0FBQ0Esd0Y7O0FDSE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixZQUFZO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRjs7QUNYeUY7QUFDRTtBQUNtRDtBQUNmO0FBQ3hIO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsUUFBUSw0QkFBNEI7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLDJCQUEyQjtBQUNuQyxRQUFRLDJCQUEyQjtBQUNuQyxRQUFRLDJCQUEyQjtBQUNuQyxRQUFRLDJCQUEyQjtBQUNuQztBQUNBLDZCQUE2QixtREFBbUQsUUFBUSxtREFBbUQ7QUFDM0ksWUFBWSw0Q0FBNEM7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3RDs7QUN4Qk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkQ7O0FDVE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0U7O0FDTjJFO0FBQ3BFO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsdUJBQXVCO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0Esd0Y7O0FDYk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsNkY7O0FDWE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLDRGOztBQ1Y2RztBQUNwQjtBQUNFO0FBQ29EO0FBQ1U7QUFDRjtBQUNoSjtBQUNQO0FBQ0E7QUFDQSxRQUFRLDRCQUE0QjtBQUNwQyxRQUFRLG9DQUFvQztBQUM1QyxRQUFRLDJCQUEyQjtBQUNuQztBQUNBLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DO0FBQ0E7QUFDQSxZQUFZLG9EQUFvRDtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSx5REFBeUQ7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHdEQUF3RDtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRTs7QUM3Q087QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEQ7O0FDVE87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUQ7O0FDekRPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlFOztBQ05PO0FBQ1AsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRTs7QUNWcUg7QUFDOUc7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdEQUF3RDtBQUN4RCw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0EsNkZBQTZGLFVBQVU7QUFDdkc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsd0NBQXdDO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBLDZEOztBQzNITztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQzs7QUNOTztBQUNQO0FBQ0EsZ0JBQWdCLGVBQWU7QUFDL0IsNkJBQTZCLE1BQU07QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsTUFBTTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSw0RDs7QUNqQmtGO0FBQzNFO0FBQ1AsZ0RBQWdELDRCQUE0QjtBQUM1RTtBQUNBO0FBQ0Esa0U7O0FDTG9EO0FBQzBDO0FBQ3ZGO0FBQ1AsNkJBQTZCLDBCQUEwQjtBQUN2RDtBQUNBO0FBQ0EsUUFBUSwwQkFBMEI7QUFDbEM7QUFDQSx5Q0FBeUMsa0NBQWtDO0FBQzNFO0FBQ0E7QUFDQTtBQUNBLDBEOztBQ1pzRjtBQUNuQjtBQUNKO0FBQ0o7QUFDNkI7QUFDbkI7QUFDdEI7QUFDeEM7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3Qiw0QkFBNEI7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLHlCQUF5Qix5Q0FBeUM7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLDZEQUE2RCwwQkFBMEI7QUFDdkYscUJBQXFCO0FBQ3JCO0FBQ0EsNkRBQTZELDBCQUEwQjtBQUN2RjtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULDJCQUEyQixpQkFBaUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLHdCQUF3Qiw2QkFBNkI7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBLHdCQUF3Qiw0QkFBNEI7QUFDcEQ7QUFDQSw0QkFBNEIsMEJBQTBCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyxXQUFXO0FBQzVDO0FBQ0EsK0RBQStELE1BQU07QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsNkNBQTZDLDJCQUEyQjtBQUN4RTtBQUNBLHVCQUF1QixrQkFBa0I7QUFDekMsd0JBQXdCLGtCQUFrQjtBQUMxQztBQUNBO0FBQ0EsMEVBQTBFLE1BQU0sUUFBUSwwQ0FBMEMsS0FBSztBQUN2STtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUVBQWlFLDZCQUE2QjtBQUM5RjtBQUNBLGdDQUFnQywyQkFBMkI7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsMkJBQTJCO0FBQzNFO0FBQ0E7QUFDQSxnQ0FBZ0MsZ0JBQWdCO0FBQ2hELG9DQUFvQyw0QkFBNEI7QUFDaEUsd0NBQXdDLDBCQUEwQjtBQUNsRSw0QkFBNEIsZUFBZTtBQUMzQztBQUNBO0FBQ0E7QUFDQSw2RUFBNkUsTUFBTTtBQUNuRiw0QkFBNEIsZUFBZTtBQUMzQyx5QkFBeUI7QUFDekI7QUFDQSxvQ0FBb0MsNEJBQTRCO0FBQ2hFLHdDQUF3QywyQkFBMkI7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0EsNkVBQTZFLDZCQUE2QjtBQUMxRyw0Q0FBNEMsMkJBQTJCO0FBQ3ZFLGdDQUFnQyxhQUFhO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBLHdDQUF3Qyw0QkFBNEI7QUFDcEU7QUFDQSw0Q0FBNEMsMEJBQTBCO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0Q0FBNEMsWUFBWTtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRUFBbUU7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxRUFBcUUsNkJBQTZCO0FBQ2xHO0FBQ0Esb0NBQW9DLDJCQUEyQjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRTs7QUMxWTZHO0FBQ3BCO0FBQ0U7QUFDcEY7QUFDUDtBQUNBLElBQUksNEJBQTRCO0FBQ2hDLElBQUksb0NBQW9DO0FBQ3hDLElBQUksb0NBQW9DO0FBQ3hDLElBQUksb0NBQW9DO0FBQ3hDLElBQUksb0NBQW9DO0FBQ3hDLElBQUksMkJBQTJCO0FBQy9CO0FBQ0E7QUFDQSxxRDs7QUNiMkY7QUFDcEY7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsNEJBQTRCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBLDhEOztBQ2hCMkU7QUFDcEU7QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsdUJBQXVCO0FBQzdDO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQix1QkFBdUI7QUFDN0M7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLHVCQUF1QjtBQUM3QztBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0Esc0Q7O0FDL0IyRjtBQUNYO0FBQ3pFO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLDRCQUE0QjtBQUNoQztBQUNBLElBQUksdUJBQXVCO0FBQzNCO0FBQ0E7QUFDQSx3RDs7QUNaNkc7QUFDbEI7QUFDOEQ7QUFDRjtBQUNoSjtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsNEJBQTRCO0FBQ3BDLFFBQVEsb0NBQW9DO0FBQzVDO0FBQ0E7QUFDQSxZQUFZLHlEQUF5RDtBQUNyRTtBQUNBO0FBQ0E7QUFDQSxZQUFZLHdEQUF3RDtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRDs7QUMxQk87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEOztBQ0x3RTtBQUNqRTtBQUNQLDZCQUE2Qiw2QkFBNkI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsK0RBQStELG1DQUFtQztBQUNsRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxvQkFBb0I7QUFDdEQ7QUFDQTtBQUNBLHFFOztBQ3hGeUY7QUFDRTtBQUNwRjtBQUNQO0FBQ0E7QUFDQSxRQUFRLDRCQUE0QjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsMkJBQTJCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EseUQ7O0FDbEM2RztBQUNsQjtBQUNwRjtBQUNQO0FBQ0EsSUFBSSw0QkFBNEI7QUFDaEMsSUFBSSxvQ0FBb0M7QUFDeEM7QUFDQTtBQUNBLDZDOztBQ1I2RztBQUNsQjtBQUNwRjtBQUNQO0FBQ0E7QUFDQSxRQUFRLDRCQUE0QjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxvQ0FBb0M7QUFDNUMsUUFBUSxvQ0FBb0M7QUFDNUMsUUFBUSxvQ0FBb0M7QUFDNUMsUUFBUSxvQ0FBb0M7QUFDNUMsUUFBUSxvQ0FBb0M7QUFDNUM7QUFDQTtBQUNBO0FBQ0EsbUU7O0FDdEI2RztBQUNsQjtBQUNwRjtBQUNQO0FBQ0EsSUFBSSw0QkFBNEI7QUFDaEMsSUFBSSxvQ0FBb0M7QUFDeEM7QUFDQTtBQUNBLDRDOztBQ1IyRjtBQUNwRjtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSw0QkFBNEI7QUFDcEM7QUFDQTtBQUNBO0FBQ0EsMEQ7O0FDYm1FO0FBQ1g7QUFDZ0I7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLFFBQVE7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPO0FBQ1AsMENBQTBDLDhFQUE4RTtBQUN4SCwyQkFBMkIsaUJBQWlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0Qix1QkFBdUI7QUFDbkQ7QUFDQTtBQUNBLDRCQUE0QixvQkFBb0I7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixrQkFBa0I7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsc0JBQXNCO0FBQ2xEO0FBQ0E7QUFDQSxtQ0FBbUMsWUFBWTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFlBQVk7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsb0JBQW9CO0FBQ25DO0FBQ0E7QUFDQSxnRTs7QUMxSU87QUFDUDtBQUNBO0FBQ0Esa0U7O0FDSDJGO0FBQ3BGO0FBQ1A7QUFDQSxJQUFJLDRCQUE0QjtBQUNoQztBQUNBO0FBQ0EsMEZBQTBGLGNBQWM7QUFDeEc7QUFDQTtBQUNBO0FBQ0Esc0U7O0FDVk8sc0VBQXNFLGFBQWE7QUFDMUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkVBQTZFLG9CQUFvQjtBQUNqRztBQUNBO0FBQ0EsaUU7O0FDaEJPO0FBQ1Asa0NBQWtDLGtCQUFrQjtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0U7O0FDbkJPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9FOztBQ1Q2RztBQUNwQjtBQUNFO0FBQzhEO0FBQ0Y7QUFDaEo7QUFDUDtBQUNBO0FBQ0EsUUFBUSw0QkFBNEI7QUFDcEMsUUFBUSxvQ0FBb0M7QUFDNUMsUUFBUSxvQ0FBb0M7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDJCQUEyQjtBQUN2QztBQUNBO0FBQ0E7QUFDQSxZQUFZLHlEQUF5RDtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksd0RBQXdEO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEOztBQ2xDNkc7QUFDcEI7QUFDRTtBQUNwRjtBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsNEJBQTRCO0FBQ3BDLFFBQVEsb0NBQW9DO0FBQzVDLFFBQVEsb0NBQW9DO0FBQzVDLFFBQVEsb0NBQW9DO0FBQzVDLFFBQVEsb0NBQW9DO0FBQzVDLFFBQVEsb0NBQW9DO0FBQzVDLFFBQVEsb0NBQW9DO0FBQzVDLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DLFFBQVEsMkJBQTJCO0FBQ25DO0FBQ0E7QUFDQTtBQUNBLHNEOztBQzVCMkY7QUFDbkI7QUFDakU7QUFDUCw2QkFBNkIscU5BQXFOO0FBQ2xQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsNEJBQTRCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxvRUFBb0UsOEJBQThCO0FBQ2xHLDJFQUEyRSxvQ0FBb0M7QUFDL0csMkVBQTJFLG9DQUFvQztBQUMvRywyRUFBMkUsb0NBQW9DO0FBQy9HLHdFQUF3RSxvQ0FBb0M7QUFDNUcsd0VBQXdFLG9DQUFvQztBQUM1Ryx3RUFBd0Usb0NBQW9DO0FBQzVHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsYUFBYTtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQ7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQSwyRUFBMkUsY0FBYztBQUN6RiwyRUFBMkUsY0FBYztBQUN6Rix3RUFBd0UsY0FBYztBQUN0Rix3RUFBd0UsY0FBYztBQUN0Rix3RUFBd0UsY0FBYztBQUN0RjtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUFDQTtBQUNBLFFBQVEsWUFBTSxDQUFDLGNBQWM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQU07QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVEsWUFBTTtBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSxzQkFBc0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCLFlBQVksWUFBTSxDQUFDLG1CQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGlCQUFTO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLHlCQUF5QjtBQUNuRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxrQkFBUTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsaUJBQVM7QUFDeEIsZ0JBQWdCLGNBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLFlBQVk7QUFDNUI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixnQkFBZ0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsb0JBQVE7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLDZGQUE2RixzQkFBc0IsSUFBSSxxQkFBcUI7QUFDMUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxZQUFNLHNHQUFzRyxzQkFBc0IsSUFBSSx3QkFBd0I7QUFDdEs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixFQUFFO0FBQ3pCO0FBQ0E7QUFDQSxRQUFRLFlBQU0sMkdBQTJHLHNCQUFzQixJQUFJLHdCQUF3QjtBQUMzSztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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QUFLO0FBQ2xEO0FBQ0EsK0JBQStCLFVBQVU7QUFDekM7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QiwyQ0FBMkI7QUFDeEQsc0JBQXNCLGNBQUk7QUFDMUI7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLG9CQUFvQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxvQkFBb0I7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsZ0JBQVU7QUFDbkM7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLG1CQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksaUJBQU87QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixTQUFTO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsU0FBUztBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLGdCQUFVO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUIsZ0JBQVU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFNBQUk7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELFFBQVE7QUFDN0Q7QUFD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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELGtCQUFRO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlELGtCQUFRO0FBQ2pFO0FBQ0E7QUFD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c0NBQXNDLHVCQUF1QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0I7O0FDeE9zQztBQUN0QztBQUNBO0FBQ0E7QUFD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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Qzs7QUMxT3dCO0FBQ0k7QUFDWTtBQUNFO0FBQ0E7QUFDRztBQUNGO0FBQ0E7QUFDQztBQUNJO0FBQ2Y7QUFDUztBQUNWO0FBQ0M7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QUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCx3QkFBd0IseUJBQXlCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDck1tQztBQUNxQjtBQUNnQjtBQUN0QjtBQUNSO0FBQ1Y7QUFDMEI7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELGdCQUFnQjtBQUNyRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBGQUEwRixRQUFRO0FBQ2xHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNVN3QztBQUMwQjtBQUNMO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLCtEQUFlO0FBQ3pDO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQSw2Q0FBNkMsU0FBSTtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNuS2dEO0FBQ2dCO0FBQ1M7QUFDZDtBQUNvQjtBQUN2QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sb0NBQW9DO0FBQzlDLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLHlEQUFTO0FBQ25DO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFNBQUk7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0Qiw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxTQUFJO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ2haNEM7QUFDRjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxVQUFVLGlDQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDcEs4QjtBQUN3QjtBQUNPO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyxzQkFBc0Isb0RBQUk7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xFZ0Q7QUFDNkI7QUFDbEI7QUFDN0I7QUFDVTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLHlEQUFTO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUN0UHVCO0FBQ0E7QUFDRztBQUNDO0FBQ0M7QUFDNUIsaUM7O0FDTCtDO0FBQzJCO0FBQ1Y7QUFDWDtBQUNFO0FBQ1Y7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyw2REFBYTtBQUM1QztBQUNBLGlEQUFpRCxtQkFBUztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDaExrQztBQUMrQjtBQUNsQjtBQUNBO0FBQ2E7QUFDSTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNPLHVCQUF1Qiw2REFBYTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtB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QUFDM0gsUUFBUSxDQUFDNkgsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0VBQ3ZEL0QsSUFBSSxDQUFDZ0UsTUFBTSxlQUFDSixtQkFBQSxhQUFJLGtCQUFvQixDQUFDLENBQUM7QUFDeEMsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3ZlcnNpb24uanM/MzM4MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hYm9ydC1lcnJvci5qcz83MzgyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzPzc4N2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMuanM/ZjBmZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanM/YWQzZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2dsb2JhbHMuanM/NzRmNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtY29uc3RydWN0aWJsZS5qcz81MjgwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zcGxpdC1pbXBvcnQtc3RhdGVtZW50cy5qcz83ODkyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1hdWRpby13b3JrbGV0LW1vZHVsZS5qcz83NDg3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtdmFsdWUtZm9yLWtleS5qcz81ZDc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9waWNrLWVsZW1lbnQtZnJvbS1zZXQuanM/NTYwZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzP2E1MmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcz8wMjdjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlLmpzPzJmOTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYXVkaW8td29ya2xldC1ub2RlLmpzPzFiOGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLmpzP2FlNWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5LmpzPzdhNTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz8zMzllIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcz8xMGM5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1zaWxlbnQtY29ubmVjdGlvbi5qcz9jOWM5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcz9kYTZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtY29uc3RydWN0b3IuanM/MDg1NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dC5qcz80OTY1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz83MzFhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQuanM/MzdmZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pbmRleC1zaXplLWVycm9yLmpzP2JjY2UiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kLmpzPzIzYjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzPzUyN2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9jb25zdGFudHMuanM/NjJmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUuanM/MTFkNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3IuanM/NzU2OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz82NGRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS5qcz9mMmZmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2JpcXVhZC1maWx0ZXItbm9kZS5qcz9hMjIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2NvbnN0YW50LXNvdXJjZS1ub2RlLmpzPzI0MWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvZ2Fpbi1ub2RlLmpzP2FlMTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvb3NjaWxsYXRvci1ub2RlLmpzPzQwOWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvc3RlcmVvLXBhbm5lci1ub2RlLmpzP2ZkNzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzPzJhNzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucy5qcz80ZGFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zLmpzP2M5MzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGguanM/OWU5YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtdmFsaWQtbGF0ZW5jeS1oaW50LmpzPzgwMDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz85NWI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanM/MDUzNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/ODJiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1saXN0ZW5lci1mYWN0b3J5LmpzP2QwNzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYXVkaW8tbm9kZS5qcz9iNDVlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24uanM/ZThjMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaW5zZXJ0LWVsZW1lbnQtaW4tc2V0LmpzPzBlMjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2FkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcz8zZTIwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzPzE2YjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXIuanM/MTM2NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS10by1uYXRpdmUtYXVkaW8tbm9kZS5qcz8yZmU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24uanM/M2M1NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzP2U4NjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlbGV0ZS1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcz85YjE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzPzIxOTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZS5qcz9mNzI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUuanM/MzA0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1wYXJhbS5qcz85NGQ5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1wYXJ0LW9mLWEtY3ljbGUuanM/M2NjYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtcGFzc2l2ZS1hdWRpby1ub2RlLmpzP2FhMzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC1zdXBwb3J0LmpzP2UzNDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Zpc2l0LWVhY2gtYXVkaW8tbm9kZS1vbmNlLmpzPzAyYmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUuanM/OTIxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLmpzP2RlZjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tbm9kZS1jb25zdHJ1Y3Rvci5qcz85ZmU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLWZhY3RvcnkuanM/OTJkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1wYXJhbS1yZW5kZXJlci5qcz8wOTA4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvcmVhZC1vbmx5LW1hcC5qcz85Yzg1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcz81MTJiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jb3B5LWZyb20tY2hhbm5lbC5qcz9kMDBlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jb3B5LXRvLWNoYW5uZWwuanM/Y2ZlZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMuanM/ZjAxOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzP2UxMmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/M2YxNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/YjEzNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanM/MjU2MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz84MjdiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NhY2hlLXRlc3QtcmVzdWx0LmpzP2ZjNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz9lZDAyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz9lMDg3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz81NGJhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzP2ViMDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29ubmVjdC1hdWRpby1wYXJhbS5qcz81NzI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcz8xMjQyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Nvbm5lY3RlZC1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanM/NjQ2NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb25zdGFudC1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz80YmQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MzE0NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nLmpzPzA5YmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29udm9sdmVyLW5vZGUtY29uc3RydWN0b3IuanM/MDVlOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzVhOTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/NTMyYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kYXRhLWNsb25lLWVycm9yLmpzPzE5NWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RldGFjaC1hcnJheS1idWZmZXIuanM/OWY3ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWNvZGUtYXVkaW8tZGF0YS5qcz8yNjlkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlY3JlbWVudC1jeWNsZS1jb3VudGVyLmpzPzFmNGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVsYXktbm9kZS1jb25zdHJ1Y3Rvci5qcz8xMTNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8xZTc1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzP2UyMTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVsZXRlLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlLmpzPzFkNDQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvZGVsYXktbm9kZS5qcz82ZTk2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RldGVjdC1jeWNsZXMuanM/N2FiMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kaXNjb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanM/M2Q0MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3IuanM/ODJmMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz9iYTkwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2VuY29kaW5nLWVycm9yLmpzP2I2N2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZXZhbHVhdGUtc291cmNlLmpzPzM1ZjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yLmpzPzQyMjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZXhwb3NlLWN1cnJlbnQtZnJhbWUtYW5kLWN1cnJlbnQtdGltZS5qcz82M2Y3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2ZldGNoLXNvdXJjZS5qcz9lOWRjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dhaW4tbm9kZS1jb25zdHJ1Y3Rvci5qcz9jN2RlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dhaW4tbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzc3ZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzLmpzPzYwNGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtcmVuZGVyZXIuanM/ZGE1MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUuanM/MDM2MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYXVkaW8tcGFyYW0tcmVuZGVyZXIuanM/MGZlNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz85MjMyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3IuanM/ZTA5NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtbmF0aXZlLWNvbnRleHQuanM/NGVhYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/ZGE5ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGVzLmpzP2RjZTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaW52YWxpZC1hY2Nlc3MtZXJyb3IuanM/MzYxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QuanM/ODc0NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanM/MDU2ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZmlsdGVyLWJ1ZmZlci5qcz9lNDFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzM3MzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeS5qcz9lMzI1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLWFueS1hdWRpby1jb250ZXh0LmpzPzVhMjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLW5vZGUuanM/MDc4OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tcGFyYW0uanM/N2U3NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzP2RmMjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLWNvbnRleHQuanM/MjI2YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tbm9kZS5qcz82M2I5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1wYXJhbS5qcz8xNTFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1jb250ZXh0LmpzPzVjZTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz81YWQ2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLXNlY3VyZS1jb250ZXh0LmpzPzg2ZjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz83MzcwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzPzMwNzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzP2FhNGIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzP2JhNTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWluaW1hbC1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzP2VkZDMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/ZGU2MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQuanM/ZTUzOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9taW5pbWFsLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz81MDM2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21vbml0b3ItY29ubmVjdGlvbnMuanM/ZmM3NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbi5qcz84ZWY3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucy5qcz9jZTc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLXN1cHBvcnQuanM/MTAxZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC5qcz9mNTc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hbmFseXNlci1ub2RlLWZhY3RvcnkuanM/YjM0MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzPzg4ZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZS5qcz82M2YwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanM/ZjgwMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMuanM/MjUxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcz85MjRmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeS5qcz8zZjkwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzPzI3ZTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanM/ZGVkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yLmpzP2UxNmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtY2xvbmFiaWxpdHktb2YtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanM/NmMyZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZhY3RvcnkuanM/MjhkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvY29tcHV0ZS1idWZmZXItc2l6ZS5qcz9kMTE2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jbG9uZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcz84YjUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcHJvbWlzZS5qcz8xMmQ1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanM/M2E5ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZha2VyLWZhY3RvcnkuanM/MGMwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYmlxdWFkLWZpbHRlci1ub2RlLmpzP2E5ZGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWNoYW5uZWwtbWVyZ2VyLW5vZGUtZmFjdG9yeS5qcz8yNTZkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWNoYW5uZWwtc3BsaXR0ZXItbm9kZS5qcz8zYmFmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanM/ODliYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFjdG9yeS5qcz81YTAzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMuanM/NTAxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeS5qcz9lMGNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5LmpzP2ExNGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWRlbGF5LW5vZGUuanM/MDUxOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnkuanM/NDg5NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtZ2Fpbi1ub2RlLmpzP2Y3ZjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5LmpzP2YzZTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzP2Y4YWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUuanM/MDcwOSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanM/ZDFjYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLmpzP2VjYzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzPzM2MzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz83MmY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1vc2NpbGxhdG9yLW5vZGUtZmFjdG9yeS5qcz85N2VmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1wYW5uZXItbm9kZS1mYWN0b3J5LmpzP2VjZmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanM/MGRhZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5LmpzPzliYjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXNjcmlwdC1wcm9jZXNzb3Itbm9kZS5qcz9iMTUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFjdG9yeS5qcz81OGY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcz8wZGUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZhY3RvcnkuanM/ODU5NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzPzMzNDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbm90LXN1cHBvcnRlZC1lcnJvci5qcz8xMzYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL29mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz8zMGQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL29zY2lsbGF0b3Itbm9kZS1jb25zdHJ1Y3Rvci5qcz85YzViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL29zY2lsbGF0b3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzczMmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcGFubmVyLW5vZGUtY29uc3RydWN0b3IuanM/Njg0ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzE4MjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcGVyaW9kaWMtd2F2ZS1jb25zdHJ1Y3Rvci5qcz9jMTAwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3JlbmRlci1hdXRvbWF0aW9uLmpzPzE4ZWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlLmpzPzNiODUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1wYXJhbS5qcz83NGY4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3JlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzPzEzYTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzLmpzP2YyODAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzP2UzMDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc3RhcnQtcmVuZGVyaW5nLmpzPzcxMzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzPzhlYzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/N2I0MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci1zdXBwb3J0LmpzPzRiYjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydC5qcz9mYmNhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Rlc3Qtb2ZmbGluZS1hdWRpby1jb250ZXh0LWN1cnJlbnQtdGltZS1zdXBwb3J0LmpzP2NlYTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvdW5rbm93bi1lcnJvci5qcz9jMWQwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dhdmUtc2hhcGVyLW5vZGUtY29uc3RydWN0b3IuanM/MTQyZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MjgzYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93aW5kb3cuanM/YWIzYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy5qcz8zZTNkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMuanM/MWFkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLmpzPzcwZDUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd3JhcC1jaGFubmVsLW1lcmdlci1ub2RlLmpzPzg3NTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1maXJzdC1zYW1wbGUuanM/ODk1YSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvaXMtZGMtY3VydmUuanM/ZDRlMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvb3ZlcndyaXRlLWFjY2Vzc29ycy5qcz8xYjI3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zYW5pdGl6ZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcz84MDU4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMuanM/NDkwNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2FuaXRpemUtcGVyaW9kaWMtd2F2ZS1vcHRpb25zLmpzP2Y2ZGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC12YWx1ZS1hdC10aW1lLXVudGlsLXBvc3NpYmxlLmpzP2E5YzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzPzY3MmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmctc3VwcG9ydC5qcz84ZGRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLXN1cHBvcnQuanM/ZjYxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcz9lMTZlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzP2U1NmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcz83NGY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLWNsb25hYmlsaXR5LmpzPzY3YzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcuanM/MWYxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanM/ZWQyMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1ldmVudC1saXN0ZW5lci5qcz9lNDllIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvbW9kdWxlLmpzPzc4ZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9EZWJ1Zy5qcz9hMzc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvVHlwZUNoZWNrLmpzPzg2NzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9BdWRpb0NvbnRleHQuanM/OTFhYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdHNsaWIvdHNsaWIuZXM2LmpzPzlhYjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVGlja2VyLmpzP2E0NTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9BZHZhbmNlZFR5cGVDaGVjay5qcz9iZjZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRGVmYXVsdHMuanM/NWI3OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9Ub25lLmpzP2FmYWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9NYXRoLmpzP2Y0Y2YiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9UaW1lbGluZS5qcz9lNTI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvQ29udGV4dEluaXRpYWxpemF0aW9uLmpzPzAxMzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9FbWl0dGVyLmpzPzE1ZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9CYXNlQ29udGV4dC5qcz8xZDIzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvQ29udGV4dC5qcz9hMjgyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvRHVtbXlDb250ZXh0LmpzPzRjOWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9JbnRlcmZhY2UuanM/MDZlMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlci5qcz8xNDliIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHQuanM/YWIxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9HbG9iYWwuanM/NTgzYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL0NvbnZlcnNpb25zLmpzPzQ2ZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UaW1lQmFzZS5qcz9iNjc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvVGltZS5qcz80MTQyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvRnJlcXVlbmN5LmpzPzQ1YzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UcmFuc3BvcnRUaW1lLmpzP2Q1MGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lV2l0aENvbnRleHQuanM/ZDY4MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL1N0YXRlVGltZWxpbmUuanM/ZjFiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1BhcmFtLmpzPzFmNzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlLmpzP2I2NGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9HYWluLmpzP2IyMzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9PbmVTaG90U291cmNlLmpzPzQ3NzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9Ub25lQ29uc3RhbnRTb3VyY2UuanM/ZjRiZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NpZ25hbC5qcz9kZGVhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RpY2tQYXJhbS5qcz81Y2UzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RpY2tTaWduYWwuanM/NzIxNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UaWNrU291cmNlLmpzPzgyYzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svQ2xvY2suanM/MTBhMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0RlbGF5LmpzP2JiM2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9PZmZsaW5lLmpzP2U5NDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzLmpzPzQ5ZDUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9NaWRpLmpzP2M4ZmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UaWNrcy5qcz9lNmNlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRHJhdy5qcz81NDNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvSW50ZXJ2YWxUaW1lbGluZS5qcz8wODljIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2luZGV4LmpzP2NkMzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZS5qcz9hMDk4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvRGVzdGluYXRpb24uanM/MWJjZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL1RpbWVsaW5lVmFsdWUuanM/YjAzMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UcmFuc3BvcnRFdmVudC5qcz8zZjE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RyYW5zcG9ydFJlcGVhdEV2ZW50LmpzPzk4ZGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVHJhbnNwb3J0LmpzPzRjNGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9Tb3VyY2UuanM/NTA5YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlLmpzPzJiM2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9Ob2lzZS5qcz9kMzA2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvVXNlck1lZGlhLmpzP2M3M2YiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL09zY2lsbGF0b3JJbnRlcmZhY2UuanM/ZDlkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlLmpzP2ZiYmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL09zY2lsbGF0b3IuanM/NGRkMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NpZ25hbE9wZXJhdG9yLmpzPzllODgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9XYXZlU2hhcGVyLmpzP2EzY2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9BdWRpb1RvR2Fpbi5qcz9hZGFkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvTXVsdGlwbHkuanM/NTA3OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvQU1Pc2NpbGxhdG9yLmpzPzU4MjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL0ZNT3NjaWxsYXRvci5qcz81YTE4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9QdWxzZU9zY2lsbGF0b3IuanM/NDI5NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvRmF0T3NjaWxsYXRvci5qcz9iOGRkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9QV01Pc2NpbGxhdG9yLmpzP2VmZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yLmpzPzdkNzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9BZGQuanM/NDI4MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NjYWxlLmpzP2VkNmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9aZXJvLmpzP2VkYjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL0xGTy5qcz9mMzNhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvRGVjb3JhdG9yLmpzPzk2ZmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9idWZmZXIvUGxheWVyLmpzPzc3ODAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9idWZmZXIvUGxheWVycy5qcz80NzQ5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvYnVmZmVyL0dyYWluUGxheWVyLmpzPzBhMWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9pbmRleC5qcz9mNDIzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvQWJzLmpzP2JiOTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9HYWluVG9BdWRpby5qcz8yMjZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvTmVnYXRlLmpzPzBhMjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TdWJ0cmFjdC5qcz9iNjdkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvR3JlYXRlclRoYW5aZXJvLmpzPzYyMjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9HcmVhdGVyVGhhbi5qcz9iZDMzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvUG93LmpzP2E4NDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TY2FsZUV4cC5qcz80Njc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU3luY2VkU2lnbmFsLmpzPzk1NzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9pbmRleC5qcz8wMzU2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGUuanM/MjNmOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9JbnN0cnVtZW50LmpzP2U5MzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTW9ub3Bob25pYy5qcz83NGVlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGUuanM/ZjIxMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9TeW50aC5qcz9lNWU1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01vZHVsYXRpb25TeW50aC5qcz8zYzI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L0FNU3ludGguanM/YmEwNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9CaXF1YWRGaWx0ZXIuanM/NjQ2ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXIuanM/MTMxNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2VudmVsb3BlL0ZyZXF1ZW5jeUVudmVsb3BlLmpzPzg3MDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTW9ub1N5bnRoLmpzPzJkZWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvRHVvU3ludGguanM/Nzg3ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9GTVN5bnRoLmpzP2I5YzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTWV0YWxTeW50aC5qcz85MzJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L01lbWJyYW5lU3ludGguanM/OTU0MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Ob2lzZVN5bnRoLmpzPzNjOGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGUuanM/OGE2NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXQuanM/ZTA4ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Iud29ya2xldC5qcz81MWYxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldC5qcz81NjhjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvRGVsYXlMaW5lLndvcmtsZXQuanM/ZDUwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9GZWVkYmFja0NvbWJGaWx0ZXIud29ya2xldC5qcz8wODhjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlci5qcz9hNTFmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL09uZVBvbGVGaWx0ZXIuanM/YTc4ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlci5qcz8yOGUwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L1BsdWNrU3ludGguanM/MDZjYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Qb2x5U3ludGguanM/NTg4MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9TYW1wbGVyLmpzPzMxOTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvaW5kZXguanM/YzYxMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvVG9uZUV2ZW50LmpzP2U1MzEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L0xvb3AuanM/ZGJkYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvUGFydC5qcz84ZDM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9QYXR0ZXJuR2VuZXJhdG9yLmpzPzljZGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L1BhdHRlcm4uanM/YzQ2NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvU2VxdWVuY2UuanM/OGY5MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvaW5kZXguanM/NDA0YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvQ3Jvc3NGYWRlLmpzPzJjODYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9FZmZlY3QuanM/ZDEyNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0xGT0VmZmVjdC5qcz80YjM5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQXV0b0ZpbHRlci5qcz8wOTc0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9QYW5uZXIuanM/YjFlYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0F1dG9QYW5uZXIuanM/MmE0NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0ZvbGxvd2VyLmpzPzQ2YjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9BdXRvV2FoLmpzP2M5Y2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9CaXRDcnVzaGVyLndvcmtsZXQuanM/ZGI4NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0JpdENydXNoZXIuanM/YTQ5YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0NoZWJ5c2hldi5qcz9iMTg3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9TcGxpdC5qcz85OWI4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9NZXJnZS5qcz9kMDViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvU3RlcmVvRWZmZWN0LmpzP2YwNmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9TdGVyZW9GZWVkYmFja0VmZmVjdC5qcz8xMWUwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQ2hvcnVzLmpzPzc0MWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9EaXN0b3J0aW9uLmpzPzgwNDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GZWVkYmFja0VmZmVjdC5qcz9hNzE5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvRmVlZGJhY2tEZWxheS5qcz84YmYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL1BoYXNlU2hpZnRBbGxwYXNzLmpzPzhkNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GcmVxdWVuY3lTaGlmdGVyLmpzPzhhNjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GcmVldmVyYi5qcz9lODk3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvSkNSZXZlcmIuanM/MTVkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1N0ZXJlb1hGZWVkYmFja0VmZmVjdC5qcz84OTg2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUGluZ1BvbmdEZWxheS5qcz9kZTI0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUGl0Y2hTaGlmdC5qcz84NmE2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvUGhhc2VyLmpzPzZiNzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9SZXZlcmIuanM/MGQ4MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZVNwbGl0LmpzP2ZlM2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL01pZFNpZGVNZXJnZS5qcz82ZmIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvTWlkU2lkZUVmZmVjdC5qcz9lZmY3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvU3RlcmVvV2lkZW5lci5qcz8wZGIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvVHJlbW9sby5qcz8wZTFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvVmlicmF0by5qcz8wYzFlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvaW5kZXguanM/ZWM0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0FuYWx5c2VyLmpzP2VkYWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9NZXRlckJhc2UuanM/NDc2YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL01ldGVyLmpzP2RmNDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9hbmFseXNpcy9GRlQuanM/NjVlZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0RDTWV0ZXIuanM/N2I5MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL1dhdmVmb3JtLmpzPzk5ZDMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1NvbG8uanM/MWJiZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUGFuVm9sLmpzPzFhZjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL0NoYW5uZWwuanM/ZDM3MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTW9uby5qcz85ZmE4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9NdWx0aWJhbmRTcGxpdC5qcz8zNDUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvTGlzdGVuZXIuanM/MjAzOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUGFubmVyM0QuanM/YzlkZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvUmVjb3JkZXIuanM/YWQ3YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL0NvbXByZXNzb3IuanM/NmRiNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL0dhdGUuanM/OGJmNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL0xpbWl0ZXIuanM/MTVjNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL01pZFNpZGVDb21wcmVzc29yLmpzP2RiNTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9NdWx0aWJhbmRDb21wcmVzc29yLmpzP2ZkYmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvRVEzLmpzPzJmNzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvQ29udm9sdmVyLmpzP2VhMTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9pbmRleC5qcz8xZDc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jbGFzc2VzLmpzP2QzYzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luZGV4LmpzPzVlNTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi91dGlsLmpzP2YxZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi9vdXRwdXQuanM/M2ZlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL2thbGltYmEuanM/OTlkYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvcmVsYWJpL2luZGV4LmpzPzAyZmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2luZGV4LmpzeD9lZDEyIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBjb25zdCB2ZXJzaW9uID0gXCIxNC43Ljc3XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD12ZXJzaW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBYm9ydEVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0Fib3J0RXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFib3J0LWVycm9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChpbnNlcnRFbGVtZW50SW5TZXQpID0+IHtcbiAgICByZXR1cm4gKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGFjdGl2ZUlucHV0c1tpbnB1dF0sIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyA9IChhdWRpb05vZGVDb25uZWN0aW9uc1N0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGF1ZGlvTm9kZVJlbmRlcmVyLCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYWN0aXZlSW5wdXRzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGFjdGl2ZUlucHV0cy5wdXNoKG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNTdG9yZS5zZXQoYXVkaW9Ob2RlLCB7XG4gICAgICAgICAgICBhY3RpdmVJbnB1dHMsXG4gICAgICAgICAgICBvdXRwdXRzOiBuZXcgU2V0KCksXG4gICAgICAgICAgICBwYXNzaXZlSW5wdXRzOiBuZXcgV2Vha01hcCgpLFxuICAgICAgICAgICAgcmVuZGVyZXI6IGF1ZGlvTm9kZVJlbmRlcmVyXG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IChhdWRpb1BhcmFtQ29ubmVjdGlvbnNTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9QYXJhbSwgYXVkaW9QYXJhbVJlbmRlcmVyKSA9PiB7XG4gICAgICAgIGF1ZGlvUGFyYW1Db25uZWN0aW9uc1N0b3JlLnNldChhdWRpb1BhcmFtLCB7IGFjdGl2ZUlucHV0czogbmV3IFNldCgpLCBwYXNzaXZlSW5wdXRzOiBuZXcgV2Vha01hcCgpLCByZW5kZXJlcjogYXVkaW9QYXJhbVJlbmRlcmVyIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSA9IG5ldyBXZWFrU2V0KCk7XG5leHBvcnQgY29uc3QgQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fTk9ERV9TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEFVRElPX1BBUkFNX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBDT05URVhUX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBFVkVOVF9MSVNURU5FUlMgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IENZQ0xFX0NPVU5URVJTID0gbmV3IFdlYWtNYXAoKTtcbi8vIFRoaXMgY2x1bmt5IG5hbWUgaXMgYm9ycm93ZWQgZnJvbSB0aGUgc3BlYy4gOi0pXG5leHBvcnQgY29uc3QgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBOT0RFX1RPX1BST0NFU1NPUl9NQVBTID0gbmV3IFdlYWtNYXAoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdsb2JhbHMuanMubWFwIiwiY29uc3QgaGFuZGxlciA9IHtcbiAgICBjb25zdHJ1Y3QoKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVyO1xuICAgIH1cbn07XG5leHBvcnQgY29uc3QgaXNDb25zdHJ1Y3RpYmxlID0gKGNvbnN0cnVjdGlibGUpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBwcm94eSA9IG5ldyBQcm94eShjb25zdHJ1Y3RpYmxlLCBoYW5kbGVyKTtcbiAgICAgICAgbmV3IHByb3h5KCk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tdW51c2VkLWV4cHJlc3Npb25cbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWNvbnN0cnVjdGlibGUuanMubWFwIiwiLypcbiAqIFRoaXMgbWFzc2l2ZSByZWdleCB0cmllcyB0byBjb3ZlciBhbGwgdGhlIGZvbGxvd2luZyBjYXNlcy5cbiAqXG4gKiBpbXBvcnQgJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IHsgbmFtZWRJbXBvcnQgfSBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IHsgbmFtZWRJbXBvcnQgYXMgcmVuYW1lbmRJbXBvcnQgfSBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0ICogYXMgbmFtZXNwYWNlSW1wb3J0IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCwgeyBuYW1lZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCwgeyBuYW1lZEltcG9ydCBhcyByZW5hbWVuZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgZGVmYXVsdEltcG9ydCwgKiBhcyBuYW1lc3BhY2VJbXBvcnQgZnJvbSAnLi9wYXRoJztcbiAqL1xuY29uc3QgSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCA9IC9eaW1wb3J0KD86KD86W1xcc10rW1xcd10rfCg/OltcXHNdK1tcXHddK1tcXHNdKiwpP1tcXHNdKlxce1tcXHNdKltcXHddKyg/OltcXHNdK2FzW1xcc10rW1xcd10rKT8oPzpbXFxzXSosW1xcc10qW1xcd10rKD86W1xcc10rYXNbXFxzXStbXFx3XSspPykqW1xcc10qfXwoPzpbXFxzXStbXFx3XStbXFxzXSosKT9bXFxzXSpcXCpbXFxzXSthc1tcXHNdK1tcXHddKylbXFxzXStmcm9tKT8oPzpbXFxzXSopKFwiKFteXCJcXFxcXXxcXFxcLikrXCJ8JyhbXidcXFxcXXxcXFxcLikrJykoPzpbXFxzXSopOz8vOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm1heC1saW5lLWxlbmd0aFxuZXhwb3J0IGNvbnN0IHNwbGl0SW1wb3J0U3RhdGVtZW50cyA9IChzb3VyY2UsIHVybCkgPT4ge1xuICAgIGNvbnN0IGltcG9ydFN0YXRlbWVudHMgPSBbXTtcbiAgICBsZXQgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMgPSBzb3VyY2UucmVwbGFjZSgvXltcXHNdKy8sICcnKTtcbiAgICBsZXQgcmVzdWx0ID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMubWF0Y2goSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCk7XG4gICAgd2hpbGUgKHJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCB1bnJlc29sdmVkVXJsID0gcmVzdWx0WzFdLnNsaWNlKDEsIC0xKTtcbiAgICAgICAgY29uc3QgaW1wb3J0U3RhdGVtZW50V2l0aFJlc29sdmVkVXJsID0gcmVzdWx0WzBdXG4gICAgICAgICAgICAucmVwbGFjZSgvKFtcXHNdKyk/Oz8kLywgJycpXG4gICAgICAgICAgICAucmVwbGFjZSh1bnJlc29sdmVkVXJsLCBuZXcgVVJMKHVucmVzb2x2ZWRVcmwsIHVybCkudG9TdHJpbmcoKSk7XG4gICAgICAgIGltcG9ydFN0YXRlbWVudHMucHVzaChpbXBvcnRTdGF0ZW1lbnRXaXRoUmVzb2x2ZWRVcmwpO1xuICAgICAgICBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyA9IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzLnNsaWNlKHJlc3VsdFswXS5sZW5ndGgpLnJlcGxhY2UoL15bXFxzXSsvLCAnJyk7XG4gICAgICAgIHJlc3VsdCA9IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzLm1hdGNoKElNUE9SVF9TVEFURU1FTlRfUkVHRVgpO1xuICAgIH1cbiAgICByZXR1cm4gW2ltcG9ydFN0YXRlbWVudHMuam9pbignOycpLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c107XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3BsaXQtaW1wb3J0LXN0YXRlbWVudHMuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBpc0NvbnN0cnVjdGlibGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWNvbnN0cnVjdGlibGUnO1xuaW1wb3J0IHsgc3BsaXRJbXBvcnRTdGF0ZW1lbnRzIH0gZnJvbSAnLi4vaGVscGVycy9zcGxpdC1pbXBvcnQtc3RhdGVtZW50cyc7XG5jb25zdCB2ZXJpZnlQYXJhbWV0ZXJEZXNjcmlwdG9ycyA9IChwYXJhbWV0ZXJEZXNjcmlwdG9ycykgPT4ge1xuICAgIGlmIChwYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkICYmICFBcnJheS5pc0FycmF5KHBhcmFtZXRlckRlc2NyaXB0b3JzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgcGFyYW1ldGVyRGVzY3JpcHRvcnMgcHJvcGVydHkgb2YgZ2l2ZW4gdmFsdWUgZm9yIHByb2Nlc3NvckN0b3IgaXMgbm90IGFuIGFycmF5LicpO1xuICAgIH1cbn07XG5jb25zdCB2ZXJpZnlQcm9jZXNzb3JDdG9yID0gKHByb2Nlc3NvckN0b3IpID0+IHtcbiAgICBpZiAoIWlzQ29uc3RydWN0aWJsZShwcm9jZXNzb3JDdG9yKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgZ2l2ZW4gdmFsdWUgZm9yIHByb2Nlc3NvckN0b3Igc2hvdWxkIGJlIGEgY29uc3RydWN0b3IuJyk7XG4gICAgfVxuICAgIGlmIChwcm9jZXNzb3JDdG9yLnByb3RvdHlwZSA9PT0gbnVsbCB8fCB0eXBlb2YgcHJvY2Vzc29yQ3Rvci5wcm90b3R5cGUgIT09ICdvYmplY3QnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBzaG91bGQgaGF2ZSBhIHByb3RvdHlwZS4nKTtcbiAgICB9XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvV29ya2xldE1vZHVsZSA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBldmFsdWF0ZVNvdXJjZSwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGZldGNoU291cmNlLCBnZXROYXRpdmVDb250ZXh0LCBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBvbmdvaW5nUmVxdWVzdHMsIHJlc29sdmVkUmVxdWVzdHMsIHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQsIHdpbmRvdykgPT4ge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgcmV0dXJuIChjb250ZXh0LCBtb2R1bGVVUkwsIG9wdGlvbnMgPSB7IGNyZWRlbnRpYWxzOiAnb21pdCcgfSkgPT4ge1xuICAgICAgICBjb25zdCByZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ID0gcmVzb2x2ZWRSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgIGlmIChyZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ICE9PSB1bmRlZmluZWQgJiYgcmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dC5oYXMobW9kdWxlVVJMKSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCA9IG9uZ29pbmdSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgIGlmIChvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgcHJvbWlzZU9mT25nb2luZ1JlcXVlc3QgPSBvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQuZ2V0KG1vZHVsZVVSTCk7XG4gICAgICAgICAgICBpZiAocHJvbWlzZU9mT25nb2luZ1JlcXVlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgLy8gQnVnICM1OTogU2FmYXJpIGRvZXMgbm90IGltcGxlbWVudCB0aGUgYXVkaW9Xb3JrbGV0IHByb3BlcnR5LlxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmF0aXZlQ29udGV4dC5hdWRpb1dvcmtsZXQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBmZXRjaFNvdXJjZShtb2R1bGVVUkwpXG4gICAgICAgICAgICAgICAgLnRoZW4oKFtzb3VyY2UsIGFic29sdXRlVXJsXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtpbXBvcnRTdGF0ZW1lbnRzLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c10gPSBzcGxpdEltcG9ydFN0YXRlbWVudHMoc291cmNlLCBhYnNvbHV0ZVVybCk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSB1bm1pbmlmaWVkIHZlcnNpb24gb2YgdGhlIGNvZGUgdXNlZCBiZWxvdzpcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIGBgYGpzXG4gICAgICAgICAgICAgICAgICogJHsgaW1wb3J0U3RhdGVtZW50cyB9O1xuICAgICAgICAgICAgICAgICAqICgoYSwgYikgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAoYVtiXSA9IGFbYl0gfHwgWyBdKS5wdXNoKFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgKEF1ZGlvV29ya2xldFByb2Nlc3NvciwgZ2xvYmFsLCByZWdpc3RlclByb2Nlc3Nvciwgc2FtcGxlUmF0ZSwgc2VsZiwgd2luZG93KSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgJHsgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMgfVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAqICAgICApO1xuICAgICAgICAgICAgICAgICAqIH0pKHdpbmRvdywgJ19BV0dTJyk7XG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRTb3VyY2UgPSBgJHtpbXBvcnRTdGF0ZW1lbnRzfTsoKGEsYik9PnsoYVtiXT1hW2JdfHxbXSkucHVzaCgoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLGdsb2JhbCxyZWdpc3RlclByb2Nlc3NvcixzYW1wbGVSYXRlLHNlbGYsd2luZG93KT0+eyR7c291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHN9XG59KX0pKHdpbmRvdywnX0FXR1MnKWA7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRXZhbHVhdGluZyB0aGUgZ2l2ZW4gc291cmNlIGNvZGUgaXMgYSBwb3NzaWJsZSBzZWN1cml0eSBwcm9ibGVtLlxuICAgICAgICAgICAgICAgIHJldHVybiBldmFsdWF0ZVNvdXJjZSh3cmFwcGVkU291cmNlKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUgPSB3aW5kb3cuX0FXR1MucG9wKCk7XG4gICAgICAgICAgICAgICAgaWYgKGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBldmFsdWF0ZUF1ZGlvV29ya2xldEdsb2JhbFNjb3BlKGNsYXNzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG4gICAgICAgICAgICAgICAgfSwgdW5kZWZpbmVkLCAobmFtZSwgcHJvY2Vzc29yQ3RvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmFtZS50cmltKCkgPT09ICcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCA9IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUy5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcC5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UHJvY2Vzc29yQ3Rvcihwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzKHByb2Nlc3NvckN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLnNldChuYW1lLCBwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVByb2Nlc3NvckN0b3IocHJvY2Vzc29yQ3Rvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQYXJhbWV0ZXJEZXNjcmlwdG9ycyhwcm9jZXNzb3JDdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUy5zZXQobmF0aXZlQ29udGV4dCwgbmV3IE1hcChbW25hbWUsIHByb2Nlc3NvckN0b3JdXSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCB1bmRlZmluZWQsIHVuZGVmaW5lZCkpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIDogUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgIGZldGNoU291cmNlKG1vZHVsZVVSTCksXG4gICAgICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKGNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0LCB0ZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0KSlcbiAgICAgICAgICAgIF0pLnRoZW4oKFtbc291cmNlLCBhYnNvbHV0ZVVybF0sIGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgICAgICAgICBpbmRleCA9IGN1cnJlbnRJbmRleDtcbiAgICAgICAgICAgICAgICBjb25zdCBbaW1wb3J0U3RhdGVtZW50cywgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHNdID0gc3BsaXRJbXBvcnRTdGF0ZW1lbnRzKHNvdXJjZSwgYWJzb2x1dGVVcmwpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICMxNzk6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdG8gdHJhbnNmZXIgYW55IGJ1ZmZlciB3aGljaCBoYXMgYmVlbiBwYXNzZWQgdG8gdGhlIHByb2Nlc3MoKSBtZXRob2QgYXMgYW4gYXJndW1lbnQuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSB1bm1pbmlmaWVkIHZlcnNpb24gb2YgdGhlIGNvZGUgdXNlZCBiZWxvdy5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIGBgYGpzXG4gICAgICAgICAgICAgICAgICogY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgIF9fYnVmZmVycyA9IG5ldyBXZWFrU2V0KCk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgdGhpcy5wb3J0LnBvc3RNZXNzYWdlID0gKChwb3N0TWVzc2FnZSkgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIHJldHVybiAobWVzc2FnZSwgdHJhbnNmZXJhYmxlcykgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZFRyYW5zZmVyYWJsZXMgPSAodHJhbnNmZXJhYmxlcylcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgID8gdHJhbnNmZXJhYmxlcy5maWx0ZXIoKHRyYW5zZmVyYWJsZSkgPT4gIXRoaXMuX19idWZmZXJzLmhhcyh0cmFuc2ZlcmFibGUpKVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgOiB0cmFuc2ZlcmFibGVzO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIHJldHVybiBwb3N0TWVzc2FnZS5jYWxsKHRoaXMucG9ydCwgbWVzc2FnZSwgZmlsdGVyZWRUcmFuc2ZlcmFibGVzKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH0pKHRoaXMucG9ydC5wb3N0TWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICogICAgIH1cbiAgICAgICAgICAgICAgICAgKiB9XG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEF1ZGlvV29ya2xldFByb2Nlc3NvciA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgID8gJ0F1ZGlvV29ya2xldFByb2Nlc3NvcidcbiAgICAgICAgICAgICAgICAgICAgOiAnY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige19fYj1uZXcgV2Vha1NldCgpO2NvbnN0cnVjdG9yKCl7c3VwZXIoKTsocD0+cC5wb3N0TWVzc2FnZT0ocT0+KG0sdCk9PnEuY2FsbChwLG0sdD90LmZpbHRlcih1PT4hdGhpcy5fX2IuaGFzKHUpKTp0KSkocC5wb3N0TWVzc2FnZSkpKHRoaXMucG9ydCl9fSc7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3MDogQ2hyb21lIGFuZCBFZGdlIGRvIGNhbGwgcHJvY2VzcygpIHdpdGggYW4gYXJyYXkgd2l0aCBlbXB0eSBjaGFubmVsRGF0YSBmb3IgZWFjaCBpbnB1dCBpZiBubyBpbnB1dCBpcyBjb25uZWN0ZWQuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTkwOiBTYWZhcmkgZG9lc24ndCB0aHJvdyBhbiBlcnJvciB3aGVuIGxvYWRpbmcgYW4gdW5wYXJzYWJsZSBtb2R1bGUuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIHRoZSB1bm1pbmlmaWVkIHZlcnNpb24gb2YgdGhlIGNvZGUgdXNlZCBiZWxvdzpcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIGBgYGpzXG4gICAgICAgICAgICAgICAgICogYCR7IGltcG9ydFN0YXRlbWVudHMgfTtcbiAgICAgICAgICAgICAgICAgKiAoKEF1ZGlvV29ya2xldFByb2Nlc3NvciwgcmVnaXN0ZXJQcm9jZXNzb3IpID0+IHskeyBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyB9XG4gICAgICAgICAgICAgICAgICogfSkoXG4gICAgICAgICAgICAgICAgICogICAgICR7wqBwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIH0sXG4gICAgICAgICAgICAgICAgICogICAgIChuYW1lLCBwcm9jZXNzb3JDdG9yKSA9PiByZWdpc3RlclByb2Nlc3NvcihuYW1lLCBjbGFzcyBleHRlbmRzIHByb2Nlc3NvckN0b3Ige1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICBfX2NvbGxlY3RCdWZmZXJzID0gKGFycmF5KSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgYXJyYXkuZm9yRWFjaCgoZWxlbWVudCkgPT4gdGhpcy5fX2J1ZmZlcnMuYWRkKGVsZW1lbnQuYnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICBwcm9jZXNzIChpbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpIHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICBpbnB1dHMuZm9yRWFjaCh0aGlzLl9fY29sbGVjdEJ1ZmZlcnMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIG91dHB1dHMuZm9yRWFjaCh0aGlzLl9fY29sbGVjdEJ1ZmZlcnMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIHRoaXMuX19jb2xsZWN0QnVmZmVycyhPYmplY3QudmFsdWVzKHBhcmFtZXRlcnMpKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIHJldHVybiBzdXBlci5wcm9jZXNzKFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAoaW5wdXRzLm1hcCgoaW5wdXQpID0+IGlucHV0LnNvbWUoKGNoYW5uZWxEYXRhKSA9PiBjaGFubmVsRGF0YS5sZW5ndGggPT09IDApKSA/IFsgXSA6IGlucHV0KSxcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgb3V0cHV0cyxcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgcGFyYW1ldGVyc1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgfSlcbiAgICAgICAgICAgICAgICAgKiApO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogcmVnaXN0ZXJQcm9jZXNzb3IoYF9fc2FjJHtjdXJyZW50SW5kZXh9YCwgY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgcHJvY2VzcyAoKSB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICogICAgIH1cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIH0pYFxuICAgICAgICAgICAgICAgICAqIGBgYFxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lbWJlckRlZmluaXRpb24gPSBpc1N1cHBvcnRpbmdQb3N0TWVzc2FnZSA/ICcnIDogJ19fYyA9IChhKSA9PiBhLmZvckVhY2goZT0+dGhpcy5fX2IuYWRkKGUuYnVmZmVyKSk7JztcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJSZWdpc3RyYXRpb24gPSBpc1N1cHBvcnRpbmdQb3N0TWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICA/ICcnXG4gICAgICAgICAgICAgICAgICAgIDogJ2kuZm9yRWFjaCh0aGlzLl9fYyk7by5mb3JFYWNoKHRoaXMuX19jKTt0aGlzLl9fYyhPYmplY3QudmFsdWVzKHApKTsnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRTb3VyY2UgPSBgJHtpbXBvcnRTdGF0ZW1lbnRzfTsoKEF1ZGlvV29ya2xldFByb2Nlc3NvcixyZWdpc3RlclByb2Nlc3Nvcik9Pnske3NvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzfVxufSkoJHtwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yfSwobixwKT0+cmVnaXN0ZXJQcm9jZXNzb3IobixjbGFzcyBleHRlbmRzIHB7JHttZW1iZXJEZWZpbml0aW9ufXByb2Nlc3MoaSxvLHApeyR7YnVmZmVyUmVnaXN0cmF0aW9ufXJldHVybiBzdXBlci5wcm9jZXNzKGkubWFwKGo9Pmouc29tZShrPT5rLmxlbmd0aD09PTApP1tdOmopLG8scCl9fSkpO3JlZ2lzdGVyUHJvY2Vzc29yKCdfX3NhYyR7Y3VycmVudEluZGV4fScsY2xhc3MgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7cHJvY2Vzcygpe3JldHVybiAhMX19KWA7XG4gICAgICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFt3cmFwcGVkU291cmNlXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCcgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5hdWRpb1dvcmtsZXRcbiAgICAgICAgICAgICAgICAgICAgLmFkZE1vZHVsZSh1cmwsIG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgYWxsb3cgdG8gY3JlYXRlIGFuIEF1ZGlvV29ya2xldE5vZGUgb24gYSBjbG9zZWQgQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCwgb3B0aW9ucykudGhlbigoKSA9PiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAudGhlbigobmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxOTA6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIHdoZW4gbG9hZGluZyBhbiB1bnBhcnNhYmxlIG1vZHVsZS5cbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgYF9fc2FjJHtjdXJyZW50SW5kZXh9YCk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tdW51c2VkLWV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IFVSTC5yZXZva2VPYmplY3RVUkwodXJsKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgaWYgKG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBvbmdvaW5nUmVxdWVzdHMuc2V0KGNvbnRleHQsIG5ldyBNYXAoW1ttb2R1bGVVUkwsIHByb21pc2VdXSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgb25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0LnNldChtb2R1bGVVUkwsIHByb21pc2UpO1xuICAgICAgICB9XG4gICAgICAgIHByb21pc2VcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRSZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ID0gcmVzb2x2ZWRSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgICAgICBpZiAodXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkUmVxdWVzdHMuc2V0KGNvbnRleHQsIG5ldyBTZXQoW21vZHVsZVVSTF0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHVwZGF0ZWRSZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0LmFkZChtb2R1bGVVUkwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZE9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCA9IG9uZ29pbmdSZXF1ZXN0cy5nZXQoY29udGV4dCk7XG4gICAgICAgICAgICBpZiAodXBkYXRlZE9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlZE9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dC5kZWxldGUobW9kdWxlVVJMKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWF1ZGlvLXdvcmtsZXQtbW9kdWxlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBnZXRWYWx1ZUZvcktleSA9IChtYXAsIGtleSkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gbWFwLmdldChrZXkpO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQSB2YWx1ZSB3aXRoIHRoZSBnaXZlbiBrZXkgY291bGQgbm90IGJlIGZvdW5kLicpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXZhbHVlLWZvci1rZXkuanMubWFwIiwiZXhwb3J0IGNvbnN0IHBpY2tFbGVtZW50RnJvbVNldCA9IChzZXQsIHByZWRpY2F0ZSkgPT4ge1xuICAgIGNvbnN0IG1hdGNoaW5nRWxlbWVudHMgPSBBcnJheS5mcm9tKHNldCkuZmlsdGVyKHByZWRpY2F0ZSk7XG4gICAgaWYgKG1hdGNoaW5nRWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICB0aHJvdyBFcnJvcignTW9yZSB0aGFuIG9uZSBlbGVtZW50IHdhcyBmb3VuZC4nKTtcbiAgICB9XG4gICAgaWYgKG1hdGNoaW5nRWxlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdObyBlbGVtZW50IHdhcyBmb3VuZC4nKTtcbiAgICB9XG4gICAgY29uc3QgW21hdGNoaW5nRWxlbWVudF0gPSBtYXRjaGluZ0VsZW1lbnRzO1xuICAgIHNldC5kZWxldGUobWF0Y2hpbmdFbGVtZW50KTtcbiAgICByZXR1cm4gbWF0Y2hpbmdFbGVtZW50O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBpY2stZWxlbWVudC1mcm9tLXNldC5qcy5tYXAiLCJpbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IGdldFZhbHVlRm9yS2V5KHBhc3NpdmVJbnB1dHMsIHNvdXJjZSk7XG4gICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9uID0gcGlja0VsZW1lbnRGcm9tU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0ICYmIHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IGlucHV0KTtcbiAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBwYXNzaXZlSW5wdXRzLmRlbGV0ZShzb3VyY2UpO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9uO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBFVkVOVF9MSVNURU5FUlMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoRVZFTlRfTElTVEVORVJTLCBhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgaWYgKEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIEF1ZGlvTm9kZSBpcyBhbHJlYWR5IHN0b3JlZC4nKTtcbiAgICB9XG4gICAgQUNUSVZFX0FVRElPX05PREVfU1RPUkUuYWRkKGF1ZGlvTm9kZSk7XG4gICAgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShhdWRpb05vZGUpLmZvckVhY2goKGV2ZW50TGlzdGVuZXIpID0+IGV2ZW50TGlzdGVuZXIodHJ1ZSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQXVkaW9Xb3JrbGV0Tm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BvcnQnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3Qgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICBpZiAoIUFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIEF1ZGlvTm9kZSBpcyBub3Qgc3RvcmVkLicpO1xuICAgIH1cbiAgICBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5kZWxldGUoYXVkaW9Ob2RlKTtcbiAgICBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSkuZm9yRWFjaCgoZXZlbnRMaXN0ZW5lcikgPT4gZXZlbnRMaXN0ZW5lcihmYWxzZSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4vc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuLy8gU2V0IHRoZSBpbnRlcm5hbFN0YXRlIG9mIHRoZSBhdWRpb05vZGUgdG8gJ3Bhc3NpdmUnIGlmIGl0IGlzIG5vdCBhbiBBdWRpb1dvcmtsZXROb2RlIGFuZCBpZiBpdCBoYXMgbm8gJ2FjdGl2ZScgaW5wdXQgY29ubmVjdGlvbnMuXG5leHBvcnQgY29uc3Qgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgPSAoYXVkaW9Ob2RlLCBhY3RpdmVJbnB1dHMpID0+IHtcbiAgICBpZiAoIWlzQXVkaW9Xb3JrbGV0Tm9kZShhdWRpb05vZGUpICYmIGFjdGl2ZUlucHV0cy5ldmVyeSgoY29ubmVjdGlvbnMpID0+IGNvbm5lY3Rpb25zLnNpemUgPT09IDApKSB7XG4gICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUoYXVkaW9Ob2RlKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUtd2hlbi1uZWNlc3NhcnkuanMubWFwIiwiaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5IH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeSc7XG5leHBvcnQgY29uc3QgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlVGFpbFRpbWUsIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgaW5zZXJ0RWxlbWVudEluU2V0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNQYXJ0T2ZBQ3ljbGUsIGlzUGFzc2l2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIGNvbnN0IHRhaWxUaW1lVGltZW91dElkcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcmV0dXJuIChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0LCBpc09mZmxpbmUpID0+IHtcbiAgICAgICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgICAgICBjb25zdCBldmVudExpc3RlbmVycyA9IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgY29uc3QgZXZlbnRMaXN0ZW5lciA9IChpc0FjdGl2ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlU291cmNlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBwYXJ0aWFsQ29ubmVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGlzUGFzc2l2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUocGFzc2l2ZUlucHV0cywgaW5wdXQsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHRhaWxUaW1lID0gZ2V0QXVkaW9Ob2RlVGFpbFRpbWUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIGlmICh0YWlsVGltZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFpbFRpbWVUaW1lb3V0SWQgPSB0YWlsVGltZVRpbWVvdXRJZHMuZ2V0KGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhaWxUaW1lVGltZW91dElkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0YWlsVGltZVRpbWVvdXRJZCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGFpbFRpbWVUaW1lb3V0SWRzLnNldChkZXN0aW5hdGlvbiwgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkoZGVzdGluYXRpb24sIGFjdGl2ZUlucHV0cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sIHRhaWxUaW1lICogMTAwMCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGluc2VydEVsZW1lbnRJblNldChvdXRwdXRzLCBbZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXRdLCAob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgb3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0ICYmIG91dHB1dENvbm5lY3Rpb25bMl0gPT09IGlucHV0LCB0cnVlKSkge1xuICAgICAgICAgICAgZXZlbnRMaXN0ZW5lcnMuYWRkKGV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBpbnB1dCwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAoaW5zZXJ0RWxlbWVudEluU2V0KSA9PiB7XG4gICAgcmV0dXJuIChwYXNzaXZlSW5wdXRzLCBpbnB1dCwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IHBhc3NpdmVJbnB1dHMuZ2V0KHNvdXJjZSk7XG4gICAgICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwYXNzaXZlSW5wdXRzLnNldChzb3VyY2UsIG5ldyBTZXQoW1tvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXV0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluc2VydEVsZW1lbnRJblNldChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucywgW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0ICYmIHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IGlucHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRTaWxlbnRDb25uZWN0aW9uID0gKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICB9KTtcbiAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIGNvbnN0IGRpc2Nvbm5lY3QgPSAoKSA9PiB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0KTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfTtcbiAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtc2lsZW50LWNvbm5lY3Rpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYXVkaW9Xb3JrbGV0Tm9kZSkgPT4ge1xuICAgICAgICBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMobmF0aXZlQ29udGV4dCkuYWRkKGF1ZGlvV29ya2xldE5vZGUpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGZmdFNpemU6IDIwNDgsXG4gICAgbWF4RGVjaWJlbHM6IC0zMCxcbiAgICBtaW5EZWNpYmVsczogLTEwMCxcbiAgICBzbW9vdGhpbmdUaW1lQ29uc3RhbnQ6IDAuOFxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBbmFseXNlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb25Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQW5hbHlzZXJOb2RlIGV4dGVuZHMgYXVkaW9uTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUFuYWx5c2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGFuYWx5c2VyTm9kZVJlbmRlcmVyID0gKChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgPyBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUFuYWx5c2VyTm9kZSwgYW5hbHlzZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlID0gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmZnRTaXplKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplO1xuICAgICAgICB9XG4gICAgICAgIHNldCBmZnRTaXplKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3lCaW5Db3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1heERlY2liZWxzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscztcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWF4RGVjaWJlbHModmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgICAgIGNvbnN0IG1heERlY2liZWxzID0gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAoISh2YWx1ZSA+IHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPSBtYXhEZWNpYmVscztcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBtaW5EZWNpYmVscygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHM7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG1pbkRlY2liZWxzKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzExODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIG1heERlY2liZWxzIGlzIG5vdCBtb3JlIHRoYW4gbWluRGVjaWJlbHMuXG4gICAgICAgICAgICBjb25zdCBtaW5EZWNpYmVscyA9IHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscztcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscyA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKCEodGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzID4gdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzID0gbWluRGVjaWJlbHM7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgc21vb3RoaW5nVGltZUNvbnN0YW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHNtb290aGluZ1RpbWVDb25zdGFudCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldEJ5dGVGcmVxdWVuY3lEYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZUZyZXF1ZW5jeURhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGdldEJ5dGVUaW1lRG9tYWluRGF0YShhcnJheSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmdldEJ5dGVUaW1lRG9tYWluRGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGbG9hdFRpbWVEb21haW5EYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFuYWx5c2VyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzT3duZWRCeUNvbnRleHQgPSAobmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZS5jb250ZXh0ID09PSBuYXRpdmVDb250ZXh0O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW93bmVkLWJ5LWNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUFuYWx5c2VyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQW5hbHlzZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQW5hbHlzZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQW5hbHlzZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQW5hbHlzZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQW5hbHlzZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQW5hbHlzZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZmZ0U2l6ZTogbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemUsXG4gICAgICAgICAgICAgICAgICAgIG1heERlY2liZWxzOiBuYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMsXG4gICAgICAgICAgICAgICAgICAgIG1pbkRlY2liZWxzOiBuYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMsXG4gICAgICAgICAgICAgICAgICAgIHNtb290aGluZ1RpbWVDb25zdGFudDogbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBbmFseXNlck5vZGUpO1xuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGUgPSByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQW5hbHlzZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFuYWx5c2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbChuZXcgRmxvYXQzMkFycmF5KDEpLCAwLCAtMSk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUluZGV4U2l6ZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0luZGV4U2l6ZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC1zaXplLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUluZGV4U2l6ZUVycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2luZGV4LXNpemUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kID0gKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEgPSAoKGdldENoYW5uZWxEYXRhKSA9PiB7XG4gICAgICAgIHJldHVybiAoY2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0Q2hhbm5lbERhdGEuY2FsbChhdWRpb0J1ZmZlciwgY2hhbm5lbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkoYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbnVtYmVyT2ZDaGFubmVsczogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgdGVzdE5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgbGV0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBudWxsO1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0J1ZmZlciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzk5OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgTm90U3VwcG9ydGVkRXJyb3Igd2hlbiB0aGUgbnVtYmVyT2ZDaGFubmVscyBpcyB6ZXJvLiBCdXQgaXQgb25seSBkb2VzIGl0IHdoZW4gdXNpbmcgdGhlXG4gICAgICAgICAgICAgKiBmYWN0b3J5IGZ1bmN0aW9uLiBCdXQgc2luY2UgRmlyZWZveCBhbHNvIHN1cHBvcnRzIHRoZSBjb25zdHJ1Y3RvciBldmVyeXRoaW5nIHNob3VsZCBiZSBmaW5lLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICBjYWNoZVRlc3RSZXN1bHQodGVzdE5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0LCB0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQpXG4gICAgICAgICAgICAgICAgPyBuZXcgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3Rvcih7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9KVxuICAgICAgICAgICAgICAgIDogbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjOTk6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIHRoZSBudW1iZXJPZkNoYW5uZWxzIGlzIHplcm8uXG4gICAgICAgICAgICBpZiAoYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscyA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgICAgICAgICAvLyBCdWcgIzEwMDogU2FmYXJpIGRvZXMgdGhyb3cgYSB3cm9uZyBlcnJvciB3aGVuIGNhbGxpbmcgZ2V0Q2hhbm5lbERhdGEoKSB3aXRoIGFuIG91dC1vZi1ib3VuZHMgdmFsdWUuXG4gICAgICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQoYXVkaW9CdWZmZXIpKSkge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBUaGlzIGRvZXMgdmlvbGF0ZSBhbGwgZ29vZCBwcmF0aWNlcyBidXQgaXQgaXMgbmVjZXNzYXJ5IHRvIGFsbG93IHRoaXMgQXVkaW9CdWZmZXIgdG8gYmUgdXNlZCB3aXRoIG5hdGl2ZVxuICAgICAgICAgICAgICogKE9mZmxpbmUpQXVkaW9Db250ZXh0cy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShpbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuICgoaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlID09PSAnb2JqZWN0JyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpID09PSBBdWRpb0J1ZmZlci5wcm90b3R5cGUpIHx8XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5oYXMoaW5zdGFuY2UpKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCA9IC0zLjQwMjgyMzQ2NjM4NTI4ODZlMzg7XG5leHBvcnQgY29uc3QgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgPSAtTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudHMuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmV4cG9ydCBjb25zdCBpc0FjdGl2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYWN0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGJ1ZmZlcjogbnVsbCxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgIGxvb3A6IGZhbHNlLFxuICAgIGxvb3BFbmQ6IDAsXG4gICAgbG9vcFN0YXJ0OiAwLFxuICAgIHBsYXliYWNrUmF0ZTogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9IGF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyU2V0ID0gbWVyZ2VkT3B0aW9ucy5idWZmZXIgIT09IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbnVsbDtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzM6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnBsYXliYWNrUmF0ZSwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgYnVmZmVyKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gdmFsdWU7XG4gICAgICAgICAgICAvLyBCdWcgIzcyOiBPbmx5IENocm9tZSAmIEVkZ2UgZG8gbm90IGFsbG93IHRvIHJlYXNzaWduIHRoZSBidWZmZXIgeWV0LlxuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2lzQnVmZmVyU2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyU2V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcEVuZCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BFbmQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wU3RhcnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGxvb3BTdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZCA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uRW5kZWQgPSB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBuYXRpdmVPbkVuZGVkICE9PSBudWxsICYmIG5hdGl2ZU9uRW5kZWQgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25FbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCh3aGVuLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLnN0YXJ0ID0gZHVyYXRpb24gPT09IHVuZGVmaW5lZCA/IFt3aGVuLCBvZmZzZXRdIDogW3doZW4sIG9mZnNldCwgZHVyYXRpb25dO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUodGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3Aod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gbnVsbDtcbiAgICAgICAgbGV0IHN0b3AgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgICAgICAgICBsb29wOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BFbmQsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BTdGFydDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydCxcbiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCguLi5zdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGxheWJhY2tSYXRlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBsYXliYWNrUmF0ZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnBsYXliYWNrUmF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdwbGF5YmFja1JhdGUnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQmlxdWFkRmlsdGVyTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ2ZyZXF1ZW5jeScgaW4gYXVkaW9Ob2RlICYmICdnYWluJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmlxdWFkLWZpbHRlci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0NvbnN0YW50U291cmNlTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ29mZnNldCcgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LXNvdXJjZS1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0dhaW5Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAhKCdmcmVxdWVuY3knIGluIGF1ZGlvTm9kZSkgJiYgJ2dhaW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzT3NjaWxsYXRvck5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdkZXR1bmUnIGluIGF1ZGlvTm9kZSAmJiAnZnJlcXVlbmN5JyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc1N0ZXJlb1Bhbm5lck5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdwYW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSwgYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSAoYXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSwgYXVkaW9QYXJhbSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9CdWZmZXJTb3VyY2VOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBpc0F1ZGlvV29ya2xldE5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IGlzQmlxdWFkRmlsdGVyTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9iaXF1YWQtZmlsdGVyLW5vZGUnO1xuaW1wb3J0IHsgaXNDb25zdGFudFNvdXJjZU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvY29uc3RhbnQtc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgaXNHYWluTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9nYWluLW5vZGUnO1xuaW1wb3J0IHsgaXNPc2NpbGxhdG9yTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9vc2NpbGxhdG9yLW5vZGUnO1xuaW1wb3J0IHsgaXNTdGVyZW9QYW5uZXJOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL3N0ZXJlby1wYW5uZXItbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmV4cG9ydCBjb25zdCBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyA9IChhdWRpb05vZGUsIHRyYWNlKSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgYWN0aXZlSW5wdXRzLmZvckVhY2goKGNvbm5lY3Rpb25zKSA9PiBjb25uZWN0aW9ucy5mb3JFYWNoKChbc291cmNlXSkgPT4ge1xuICAgICAgICBpZiAoIXRyYWNlLmluY2x1ZGVzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zKHNvdXJjZSwgWy4uLnRyYWNlLCBhdWRpb05vZGVdKTtcbiAgICAgICAgfVxuICAgIH0pKTtcbiAgICBjb25zdCBhdWRpb1BhcmFtcyA9IGlzQXVkaW9CdWZmZXJTb3VyY2VOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgPyBbXG4gICAgICAgICAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICAgICAgICAgIGF1ZGlvTm9kZS5wbGF5YmFja1JhdGVcbiAgICAgICAgXVxuICAgICAgICA6IGlzQXVkaW9Xb3JrbGV0Tm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICA/IEFycmF5LmZyb20oYXVkaW9Ob2RlLnBhcmFtZXRlcnMudmFsdWVzKCkpXG4gICAgICAgICAgICA6IGlzQmlxdWFkRmlsdGVyTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLlEsIGF1ZGlvTm9kZS5kZXR1bmUsIGF1ZGlvTm9kZS5mcmVxdWVuY3ksIGF1ZGlvTm9kZS5nYWluXVxuICAgICAgICAgICAgICAgIDogaXNDb25zdGFudFNvdXJjZU5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUub2Zmc2V0XVxuICAgICAgICAgICAgICAgICAgICA6IGlzR2Fpbk5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLmdhaW5dXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGlzT3NjaWxsYXRvck5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5kZXR1bmUsIGF1ZGlvTm9kZS5mcmVxdWVuY3ldXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBpc1N0ZXJlb1Bhbm5lck5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUucGFuXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFtdO1xuICAgIGZvciAoY29uc3QgYXVkaW9QYXJhbSBvZiBhdWRpb1BhcmFtcykge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSk7XG4gICAgICAgIGlmIChhdWRpb1BhcmFtQ29ubmVjdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgYXVkaW9QYXJhbUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0cy5mb3JFYWNoKChbc291cmNlXSkgPT4gZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoc291cmNlLCB0cmFjZSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUoYXVkaW9Ob2RlKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVhY3RpdmF0ZS1hY3RpdmUtYXVkaW8tbm9kZS1pbnB1dC1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyB9IGZyb20gJy4vZGVhY3RpdmF0ZS1hY3RpdmUtYXVkaW8tbm9kZS1pbnB1dC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggPSAoY29udGV4dCkgPT4ge1xuICAgIGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zKGNvbnRleHQuZGVzdGluYXRpb24sIFtdKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc1ZhbGlkTGF0ZW5jeUhpbnQgPSAobGF0ZW5jeUhpbnQpID0+IHtcbiAgICByZXR1cm4gKGxhdGVuY3lIaW50ID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgdHlwZW9mIGxhdGVuY3lIaW50ID09PSAnbnVtYmVyJyB8fFxuICAgICAgICAodHlwZW9mIGxhdGVuY3lIaW50ID09PSAnc3RyaW5nJyAmJiAobGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCcgfHwgbGF0ZW5jeUhpbnQgPT09ICdpbnRlcmFjdGl2ZScgfHwgbGF0ZW5jeUhpbnQgPT09ICdwbGF5YmFjaycpKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtdmFsaWQtbGF0ZW5jeS1oaW50LmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IGlzVmFsaWRMYXRlbmN5SGludCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtdmFsaWQtbGF0ZW5jeS1oaW50JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvQ29udGV4dCBleHRlbmRzIGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTkyIFNhZmFyaSBkb2VzIHRocm93IGEgU3ludGF4RXJyb3IgaWYgdGhlIHNhbXBsZVJhdGUgaXMgbm90IHN1cHBvcnRlZC5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyICYmIGVyci5tZXNzYWdlID09PSAnc2FtcGxlUmF0ZSBpcyBub3QgaW4gcmFuZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTMxIFNhZmFyaSByZXR1cm5zIG51bGwgd2hlbiB0aGVyZSBhcmUgZm91ciBvdGhlciBBdWRpb0NvbnRleHRzIHJ1bm5pbmcgYWxyZWFkeS5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVVbmtub3duRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTEgT25seSBDaHJvbWUgYW5kIEVkZ2UgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGdpdmVuIGxhdGVuY3lIaW50IGlzIGludmFsaWQuXG4gICAgICAgICAgICBpZiAoIWlzVmFsaWRMYXRlbmN5SGludChvcHRpb25zLmxhdGVuY3lIaW50KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFRoZSBwcm92aWRlZCB2YWx1ZSAnJHtvcHRpb25zLmxhdGVuY3lIaW50fScgaXMgbm90IGEgdmFsaWQgZW51bSB2YWx1ZSBvZiB0eXBlIEF1ZGlvQ29udGV4dExhdGVuY3lDYXRlZ29yeS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTUwIFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHNldHRpbmcgdGhlIHNhbXBsZVJhdGUuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zYW1wbGVSYXRlICE9PSB1bmRlZmluZWQgJiYgbmF0aXZlQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUgIT09IG9wdGlvbnMuc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVBdWRpb0NvbnRleHQsIDIpO1xuICAgICAgICAgICAgY29uc3QgeyBsYXRlbmN5SGludCB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGNvbnN0IHsgc2FtcGxlUmF0ZSB9ID0gbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgLy8gQHRvZG8gVGhlIHZhbHVlcyBmb3IgJ2JhbGFuY2VkJywgJ2ludGVyYWN0aXZlJyBhbmQgJ3BsYXliYWNrJyBhcmUganVzdCBjb3BpZWQgZnJvbSBDaHJvbWUncyBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICAgIHRoaXMuX2Jhc2VMYXRlbmN5ID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5ID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgICAgICA/IG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeVxuICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnYmFsYW5jZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IDUxMiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdpbnRlcmFjdGl2ZScgfHwgbGF0ZW5jeUhpbnQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMjU2IC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdwbGF5YmFjaydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAxMDI0IC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IC8qXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQHRvZG8gVGhlIG1pbiAoMjU2KSBhbmQgbWF4ICgxNjM4NCkgdmFsdWVzIGFyZSB0YWtlbiBmcm9tIHRoZSBhbGxvd2VkIGJ1ZmZlclNpemUgdmFsdWVzIG9mIGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBTY3JpcHRQcm9jZXNzb3JOb2RlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1hdGgubWF4KDIsIE1hdGgubWluKDEyOCwgTWF0aC5yb3VuZCgobGF0ZW5jeUhpbnQgKiBzYW1wbGVSYXRlKSAvIDEyOCkpKSAqIDEyOCkgLyBzYW1wbGVSYXRlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0ID0gbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgLy8gQnVnICMxODg6IFNhZmFyaSB3aWxsIHNldCB0aGUgY29udGV4dCdzIHN0YXRlIHRvICdpbnRlcnJ1cHRlZCcgaW4gY2FzZSB0aGUgdXNlciBzd2l0Y2hlcyB0YWJzLlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5nYWluLnZhbHVlID0gMWUtMzc7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuY29ubmVjdCh0aGlzLl9uYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0YXJ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjMzQ6IENocm9tZSBhbmQgRWRnZSBwcmV0ZW5kIHRvIGJlIHJ1bm5pbmcgcmlnaHQgYXdheSwgYnV0IGZpcmUgYW4gb25zdGF0ZWNoYW5nZSBldmVudCB3aGVuIHRoZSBzdGF0ZSBhY3R1YWxseSBjaGFuZ2VzXG4gICAgICAgICAgICAgKiB0byAncnVubmluZycuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3N1c3BlbmRlZCc7XG4gICAgICAgICAgICAgICAgY29uc3QgcmV2b2tlU3RhdGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXZva2VTdGF0ZSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXZva2VTdGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJhc2VMYXRlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VMYXRlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZSAhPT0gbnVsbCA/IHRoaXMuX3N0YXRlIDogdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGNsb3NlKCkge1xuICAgICAgICAgICAgLy8gQnVnICMzNTogRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgQXVkaW9Db250ZXh0IHdhcyBjbG9zZWQgYmVmb3JlLlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5jbG9zZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMzNDogSWYgdGhlIHN0YXRlIHdhcyBzZXQgdG8gc3VzcGVuZGVkIGJlZm9yZSBpdCBzaG91bGQgYmUgcmV2b2tlZCBub3cuXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5jbG9zZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVHYWluTm9kZSAhPT0gbnVsbCAmJiB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShtZWRpYUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYUVsZW1lbnQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKG1lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYVN0cmVhbSB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrU291cmNlKG1lZGlhU3RyZWFtVHJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWVkaWFTdHJlYW1UcmFjayB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bWUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZVByb21pc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VtZSgpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZXN1bWUoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NTogQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciBpbnN0ZWFkIG9mIGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCB8fCBlcnIuY29kZSA9PT0gMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3VzcGVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3VzcGVuZCgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9EZXN0aW5hdGlvbk5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaXNPZmZsaW5lKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIocmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBhdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2lzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGlzT2ZmbGluZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICM1MjogQ2hyb21lLCBFZGdlICYgU2FmYXJpIGRvIG5vdCB0aHJvdyBhbiBleGNlcHRpb24gYXQgYWxsLlxuICAgICAgICAgICAgLy8gQnVnICM1NDogRmlyZWZveCBkb2VzIHRocm93IGFuIEluZGV4U2l6ZUVycm9yLlxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGRvZXMgbm90IGluaXRpYWxpemUgdGhlIG1heENoYW5uZWxDb3VudCBwcm9wZXJ0eSBjb3JyZWN0bHkuXG4gICAgICAgICAgICBpZiAodmFsdWUgPiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICM1MzogTm8gYnJvd3NlciBkb2VzIHRocm93IGFuIGV4Y2VwdGlvbiB5ZXQuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4Q2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciA9IChyZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICBjb25zdCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb247XG4gICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbiAgICB9O1xuICAgIHJldHVybiB7XG4gICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tZGVzdGluYXRpb24tbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkgPSAoY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldEZpcnN0U2FtcGxlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAoY29udGV4dCwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVMaXN0ZW5lciA9IG5hdGl2ZUNvbnRleHQubGlzdGVuZXI7XG4gICAgICAgIC8vIEJ1ZyAjMTE3OiBPbmx5IENocm9tZSAmIEVkZ2Ugc3VwcG9ydCB0aGUgbmV3IGludGVyZmFjZSBhbHJlYWR5LlxuICAgICAgICBjb25zdCBjcmVhdGVGYWtlQXVkaW9QYXJhbXMgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGxldCBpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgbGFzdE9yaWVudGF0aW9uID0gWzAsIDAsIC0xLCAwLCAxLCAwXTtcbiAgICAgICAgICAgIGxldCBsYXN0UG9zaXRpb24gPSBbMCwgMCwgMF07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaXNTY3JpcHRQcm9jZXNzb3JOb2RlQ3JlYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgMjU2LCA5LCAwKTtcbiAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKHsgaW5wdXRCdWZmZXIgfSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbiA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDApLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNCksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA1KVxuICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3JpZW50YXRpb24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldE9yaWVudGF0aW9uKC4uLm9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdE9yaWVudGF0aW9uID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRvbiA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDYpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNyksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA4KVxuICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9zaXRvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0UG9zaXRpb24oLi4ucG9zaXRvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbiA9IHBvc2l0b247XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlU2V0T3JpZW50YXRpb24gPSAoaW5kZXgpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb25baW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldE9yaWVudGF0aW9uKC4uLmxhc3RPcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlU2V0UG9zaXRpb24gPSAoaW5kZXgpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkge1xuICAgICAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb25baW5kZXhdID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldFBvc2l0aW9uKC4uLmxhc3RQb3NpdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlRmFrZUF1ZGlvUGFyYW0gPSAoaW5wdXQsIGluaXRpYWxWYWx1ZSwgc2V0VmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBpbml0aWFsVmFsdWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoaXMgc2hvdWxkIGJlIHN0b3BwZWQgd2hlbiB0aGUgY29udGV4dCBpcyBjbG9zZWQuXG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQsICdkZWZhdWx0VmFsdWUnLCB7XG4gICAgICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbml0aWFsVmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjNjIgJiAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IENvbnN0YW50U291cmNlTm9kZXMgYW5kIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZFxuICAgICAgICAgICAgICAgICAqIG1pblZhbHVlIGZvciBHYWluTm9kZXMuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgYXVkaW9QYXJhbSA9IGNyZWF0ZUF1ZGlvUGFyYW0oeyBjb250ZXh0IH0sIGlzT2ZmbGluZSwgY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoYXVkaW9QYXJhbSwgJ3ZhbHVlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoYXVkaW9QYXJhbSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0LmNhbGwoYXVkaW9QYXJhbSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSAhPT0gOSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTE3OiBVc2luZyBzZXRPcmllbnRhdGlvbigpIGFuZCBzZXRQb3NpdGlvbigpIGRvZXNuJ3Qgd29yayB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRWYWx1ZSh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUgPSAoKGNhbmNlbEFuZEhvbGRBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2FuY2VsQW5kSG9sZEF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzID0gKChjYW5jZWxTY2hlZHVsZWRWYWx1ZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2FuY2VsU2NoZWR1bGVkVmFsdWVzLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUgPSAoKGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUgPSAoKGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lID0gKChzZXRUYXJnZXRBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2V0VGFyZ2V0QXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lID0gKChzZXRWYWx1ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRWYWx1ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUgPSAoKHNldFZhbHVlQ3VydmVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2V0VmFsdWVDdXJ2ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZm9yd2FyZFg6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDAsIDAsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDApKSxcbiAgICAgICAgICAgICAgICBmb3J3YXJkWTogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMSwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMSkpLFxuICAgICAgICAgICAgICAgIGZvcndhcmRaOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgyLCAtMSwgY3JlYXRlU2V0T3JpZW50YXRpb24oMikpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNiwgMCwgY3JlYXRlU2V0UG9zaXRpb24oMCkpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNywgMCwgY3JlYXRlU2V0UG9zaXRpb24oMSkpLFxuICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oOCwgMCwgY3JlYXRlU2V0UG9zaXRpb24oMikpLFxuICAgICAgICAgICAgICAgIHVwWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMywgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMykpLFxuICAgICAgICAgICAgICAgIHVwWTogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNCwgMSwgY3JlYXRlU2V0T3JpZW50YXRpb24oNCkpLFxuICAgICAgICAgICAgICAgIHVwWjogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oNSwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oNSkpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB7IGZvcndhcmRYLCBmb3J3YXJkWSwgZm9yd2FyZFosIHBvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblosIHVwWCwgdXBZLCB1cFogfSA9IG5hdGl2ZUxpc3RlbmVyLmZvcndhcmRYID09PSB1bmRlZmluZWQgPyBjcmVhdGVGYWtlQXVkaW9QYXJhbXMoKSA6IG5hdGl2ZUxpc3RlbmVyO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZ2V0IGZvcndhcmRYKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3J3YXJkWDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgZm9yd2FyZFkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcndhcmRZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBmb3J3YXJkWigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZFo7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25YO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25aKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblo7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHVwWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBYO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB1cFkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVwWTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdXBaKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1cFo7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1saXN0ZW5lci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0F1ZGlvTm9kZSA9IChhdWRpb05vZGVPckF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gJ2NvbnRleHQnIGluIGF1ZGlvTm9kZU9yQXVkaW9QYXJhbTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi9hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gPSAob3V0cHV0Q29ubmVjdGlvbikgPT4ge1xuICAgIHJldHVybiBpc0F1ZGlvTm9kZShvdXRwdXRDb25uZWN0aW9uWzBdKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpbnNlcnRFbGVtZW50SW5TZXQgPSAoc2V0LCBlbGVtZW50LCBwcmVkaWNhdGUsIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICBmb3IgKGNvbnN0IGxtbnQgb2Ygc2V0KSB7XG4gICAgICAgIGlmIChwcmVkaWNhdGUobG1udCkpIHtcbiAgICAgICAgICAgIGlmIChpZ25vcmVEdXBsaWNhdGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1RoZSBzZXQgY29udGFpbnMgYXQgbGVhc3Qgb25lIHNpbWlsYXIgZWxlbWVudC4nKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQuYWRkKGVsZW1lbnQpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluc2VydC1lbGVtZW50LWluLXNldC5qcy5tYXAiLCJpbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5leHBvcnQgY29uc3QgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGluc2VydEVsZW1lbnRJblNldChhY3RpdmVJbnB1dHMsIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuZXhwb3J0IGNvbnN0IGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAocGFzc2l2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gcGFzc2l2ZUlucHV0cy5nZXQoc291cmNlKTtcbiAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwYXNzaXZlSW5wdXRzLnNldChzb3VyY2UsIG5ldyBTZXQoW1tvdXRwdXQsIGV2ZW50TGlzdGVuZXJdXSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCBbb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb24pID0+IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IG91dHB1dCwgaWdub3JlRHVwbGljYXRlcyk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgPSAobmF0aXZlQXVkaW9Ob2RlT3JOYXRpdmVBdWRpb05vZGVGYWtlcikgPT4ge1xuICAgIHJldHVybiAnaW5wdXRzJyBpbiBuYXRpdmVBdWRpb05vZGVPck5hdGl2ZUF1ZGlvTm9kZUZha2VyO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1ub2RlLWZha2VyLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuZXhwb3J0IGNvbnN0IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUpKSB7XG4gICAgICAgIGNvbnN0IGZha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLmlucHV0c1tpbnB1dF07XG4gICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5jb25uZWN0KGZha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCAwKTtcbiAgICAgICAgcmV0dXJuIFtmYWtlTmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgMF07XG4gICAgfVxuICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICByZXR1cm4gW25hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0XTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24gPSAoYWN0aXZlSW5wdXRDb25uZWN0aW9ucywgc291cmNlLCBvdXRwdXQpID0+IHtcbiAgICBmb3IgKGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiBvZiBhY3RpdmVJbnB1dENvbm5lY3Rpb25zKSB7XG4gICAgICAgIGlmIChhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkge1xuICAgICAgICAgICAgYWN0aXZlSW5wdXRDb25uZWN0aW9ucy5kZWxldGUoYWN0aXZlSW5wdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIHJldHVybiBhY3RpdmVJbnB1dENvbm5lY3Rpb247XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLmpzLm1hcCIsImltcG9ydCB7IHBpY2tFbGVtZW50RnJvbVNldCB9IGZyb20gJy4vcGljay1lbGVtZW50LWZyb20tc2V0JztcbmV4cG9ydCBjb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIHJldHVybiBwaWNrRWxlbWVudEZyb21TZXQoYWN0aXZlSW5wdXRzLCAoYWN0aXZlSW5wdXRDb25uZWN0aW9uKSA9PiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3QgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSwgZXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShhdWRpb05vZGUpO1xuICAgIGlmICghZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TGlzdGVuZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgZXhwZWN0ZWQgZXZlbnQgbGlzdGVuZXIuJyk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IGdldFZhbHVlRm9yS2V5KHBhc3NpdmVJbnB1dHMsIHNvdXJjZSk7XG4gICAgY29uc3QgbWF0Y2hpbmdDb25uZWN0aW9uID0gcGlja0VsZW1lbnRGcm9tU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0KTtcbiAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICBwYXNzaXZlSW5wdXRzLmRlbGV0ZShzb3VyY2UpO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hpbmdDb25uZWN0aW9uO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5leHBvcnQgY29uc3QgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUgPSAobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlKSkge1xuICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZS5pbnB1dHNbaW5wdXRdLCBvdXRwdXQsIDApO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kaXNjb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLWZyb20tbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXROYXRpdmVBdWRpb05vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX05PREVfU1RPUkUsIGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX1BBUkFNX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldE5hdGl2ZUF1ZGlvUGFyYW0gPSAoYXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19QQVJBTV9TVE9SRSwgYXVkaW9QYXJhbSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW5hdGl2ZS1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBDWUNMRV9DT1VOVEVSUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzUGFydE9mQUN5Y2xlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBDWUNMRV9DT1VOVEVSUy5oYXMoYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wYXJ0LW9mLWEtY3ljbGUuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmV4cG9ydCBjb25zdCBpc1Bhc3NpdmVBdWRpb05vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICFBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5oYXMoYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1wYXNzaXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCA9IChuYXRpdmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAvKlxuICAgICAgICAgKiBUaGlzIGJ1ZyBleGlzdGVkIGluIFNhZmFyaSB1cCB1bnRpbCB2MTQuMC4yLiBTaW5jZSBBdWRpb1dvcmtsZXRzIHdlcmUgbm90IHN1cHBvcnRlZCBpbiBTYWZhcmkgdW50aWwgdjE0LjEgdGhlIHByZXNlbmNlIG9mIHRoZVxuICAgICAgICAgKiBjb25zdHJ1Y3RvciBmb3IgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBjYW4gYmUgdXNlZCBoZXJlIHRvIHNraXAgdGhlIHRlc3QuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYW5hbHl6ZXIgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlU2NyaXB0UHJvY2Vzc29yKDI1NiwgMSwgMSk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmUgZGVwcmVjYXRpb25cbiAgICAgICAgICAgIGNvbnN0IGR1bW15ID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjOTU6IFNhZmFyaSBkb2VzIG5vdCBwbGF5IG9uZSBzYW1wbGUgYnVmZmVycy5cbiAgICAgICAgICAgIGNvbnN0IG9uZXMgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDIsIDQ0MTAwKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gb25lcy5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgICAgIGNoYW5uZWxEYXRhWzBdID0gMTtcbiAgICAgICAgICAgIGNoYW5uZWxEYXRhWzFdID0gMTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgICAgIHNvdXJjZS5idWZmZXIgPSBvbmVzO1xuICAgICAgICAgICAgc291cmNlLmxvb3AgPSB0cnVlO1xuICAgICAgICAgICAgc291cmNlLmNvbm5lY3QoYW5hbHl6ZXIpLmNvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIHNvdXJjZS5jb25uZWN0KGR1bW15KTtcbiAgICAgICAgICAgIHNvdXJjZS5kaXNjb25uZWN0KGR1bW15KTtcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgYW5hbHl6ZXIub25hdWRpb3Byb2Nlc3MgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaG5ubER0ID0gZXZlbnQuaW5wdXRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmUgZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkucHJvdG90eXBlLnNvbWUuY2FsbChjaG5ubER0LCAoc2FtcGxlKSA9PiBzYW1wbGUgPT09IDEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc291cmNlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICBhbmFseXplci5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBzb3VyY2UuZGlzY29ubmVjdChhbmFseXplcik7XG4gICAgICAgICAgICAgICAgYW5hbHl6ZXIuZGlzY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydCgpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UgPSAoY3ljbGVzLCB2aXNpdG9yKSA9PiB7XG4gICAgY29uc3QgY291bnRzID0gbmV3IE1hcCgpO1xuICAgIGZvciAoY29uc3QgY3ljbGUgb2YgY3ljbGVzKSB7XG4gICAgICAgIGZvciAoY29uc3QgYXVkaW9Ob2RlIG9mIGN5Y2xlKSB7XG4gICAgICAgICAgICBjb25zdCBjb3VudCA9IGNvdW50cy5nZXQoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGNvdW50cy5zZXQoYXVkaW9Ob2RlLCBjb3VudCA9PT0gdW5kZWZpbmVkID8gMSA6IGNvdW50ICsgMSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY291bnRzLmZvckVhY2goKGNvdW50LCBhdWRpb05vZGUpID0+IHZpc2l0b3IoYXVkaW9Ob2RlLCBjb3VudCkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZpc2l0LWVhY2gtYXVkaW8tbm9kZS1vbmNlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc05hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVBdWRpb05vZGVPckF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gJ2NvbnRleHQnIGluIG5hdGl2ZUF1ZGlvTm9kZU9yQXVkaW9QYXJhbTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2QgPSAobmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QgPSAoKGNvbm5lY3QpID0+IHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZCBuby1pbmZlcnJhYmxlLXR5cGVzXG4gICAgICAgIHJldHVybiAoZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSBpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikgPyBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA6IGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgICAgICAgICAvLyBTYXZlIHRoZSBuZXcgY29ubmVjdGlvbiBvbmx5IGlmIHRoZSBjYWxscyB0byBjb25uZWN0IGFib3ZlIGRpZG4ndCB0aHJvdyBhbiBlcnJvci5cbiAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiA9IGNvbm5lY3Rpb25zLmdldChkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb24sIFt7IGlucHV0LCBvdXRwdXQgfV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5ldmVyeSgoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5pbnB1dCAhPT0gaW5wdXQgfHwgY29ubmVjdGlvbi5vdXRwdXQgIT09IG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLnB1c2goeyBpbnB1dCwgb3V0cHV0IH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb05vZGUuY29ubmVjdC5iaW5kKG5hdGl2ZUF1ZGlvTm9kZSkpO1xuICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0ID0gKChkaXNjb25uZWN0KSA9PiB7XG4gICAgICAgIHJldHVybiAoZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgICAgICAgICAgZGlzY29ubmVjdC5hcHBseShuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmNsZWFyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtkZXN0aW5hdGlvbiwgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uXSBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZENvbm5lY3Rpb25zID0gY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmZpbHRlcigoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5vdXRwdXQgIT09IGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRDb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb24sIGZpbHRlcmVkQ29ubmVjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29ubmVjdGlvbnMuaGFzKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiA9IGNvbm5lY3Rpb25zLmdldChkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZENvbm5lY3Rpb25zID0gY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmZpbHRlcigoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvbi5vdXRwdXQgIT09IG91dHB1dCAmJiAoY29ubmVjdGlvbi5pbnB1dCAhPT0gaW5wdXQgfHwgaW5wdXQgPT09IHVuZGVmaW5lZCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkQ29ubmVjdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuc2V0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIGZpbHRlcmVkQ29ubmVjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBbZGVzdGluYXRpb24sIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbl0gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZm9yRWFjaCgoY29ubmVjdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgY29ubmVjdGlvbi5vdXRwdXQsIGNvbm5lY3Rpb24uaW5wdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIGNvbm5lY3Rpb24ub3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fTk9ERV9TVE9SRSwgRVZFTlRfTElTVEVORVJTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBpc0F1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uJztcbmltcG9ydCB7IGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2FkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uJztcbmltcG9ydCB7IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGRlbGV0ZUV2ZW50TGlzdGVuZXJPZkF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi4vaGVscGVycy9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzUGFydE9mQUN5Y2xlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1wYXJ0LW9mLWEtY3ljbGUnO1xuaW1wb3J0IHsgaXNQYXNzaXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1wYXNzaXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5IH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeSc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UgfSBmcm9tICcuLi9oZWxwZXJzL3Zpc2l0LWVhY2gtYXVkaW8tbm9kZS1vbmNlJztcbmltcG9ydCB7IHdyYXBBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2QnO1xuY29uc3QgYWRkQ29ubmVjdGlvblRvQXVkaW9QYXJhbU9mQXVkaW9Db250ZXh0ID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaXNPZmZsaW5lKSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhkZXN0aW5hdGlvbik7XG4gICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShzb3VyY2UpO1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXIgPSAoaXNBY3RpdmUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvUGFyYW0gPSBnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpO1xuICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKGFjdGl2ZUlucHV0cywgc291cmNlLCBwYXJ0aWFsQ29ubmVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFydGlhbENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgICAgICBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIGlmIChpbnNlcnRFbGVtZW50SW5TZXQob3V0cHV0cywgW2Rlc3RpbmF0aW9uLCBvdXRwdXRdLCAob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgb3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCB0cnVlKSkge1xuICAgICAgICBldmVudExpc3RlbmVycy5hZGQoZXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShzb3VyY2UpKSB7XG4gICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5jb25zdCBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvTm9kZSA9IChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCBhY3RpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24oYWN0aXZlSW5wdXRzW2lucHV0XSwgc291cmNlLCBvdXRwdXQpO1xuICAgIGlmIChhY3RpdmVJbnB1dENvbm5lY3Rpb24gPT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICByZXR1cm4gW3Bhc3NpdmVJbnB1dENvbm5lY3Rpb25bMl0sIGZhbHNlXTtcbiAgICB9XG4gICAgcmV0dXJuIFthY3RpdmVJbnB1dENvbm5lY3Rpb25bMl0sIHRydWVdO1xufTtcbmNvbnN0IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9QYXJhbSA9IChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCBhY3RpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgIHJldHVybiBbcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSwgZmFsc2VdO1xuICAgIH1cbiAgICByZXR1cm4gW2FjdGl2ZUlucHV0Q29ubmVjdGlvblsyXSwgdHJ1ZV07XG59O1xuY29uc3QgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUgPSAoc291cmNlLCBpc09mZmxpbmUsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgY29uc3QgW2xpc3RlbmVyLCBpc0FjdGl2ZV0gPSBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvTm9kZShzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KTtcbiAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlKHNvdXJjZSwgbGlzdGVuZXIpO1xuICAgICAgICBpZiAoaXNBY3RpdmUgJiYgIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUoZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSksIGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbiksIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgY29uc3QgeyBhY3RpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkoZGVzdGluYXRpb24sIGFjdGl2ZUlucHV0cyk7XG4gICAgfVxufTtcbmNvbnN0IGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbSA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IFtsaXN0ZW5lciwgaXNBY3RpdmVdID0gZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb1BhcmFtKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgaWYgKGxpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZUV2ZW50TGlzdGVuZXJPZkF1ZGlvTm9kZShzb3VyY2UsIGxpc3RlbmVyKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlICYmICFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGdldE5hdGl2ZUF1ZGlvTm9kZShzb3VyY2UpLmRpc2Nvbm5lY3QoZ2V0TmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbiksIG91dHB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuY29uc3QgZGVsZXRlQW55Q29ubmVjdGlvbiA9IChzb3VyY2UsIGlzT2ZmbGluZSkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9ucyA9IFtdO1xuICAgIGZvciAoY29uc3Qgb3V0cHV0Q29ubmVjdGlvbiBvZiBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMpIHtcbiAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXRDb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUoc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBkZXN0aW5hdGlvbnMucHVzaChvdXRwdXRDb25uZWN0aW9uWzBdKTtcbiAgICB9XG4gICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmNsZWFyKCk7XG4gICAgcmV0dXJuIGRlc3RpbmF0aW9ucztcbn07XG5jb25zdCBkZWxldGVDb25uZWN0aW9uQXRPdXRwdXQgPSAoc291cmNlLCBpc09mZmxpbmUsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIGNvbnN0IGRlc3RpbmF0aW9ucyA9IFtdO1xuICAgIGZvciAoY29uc3Qgb3V0cHV0Q29ubmVjdGlvbiBvZiBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMpIHtcbiAgICAgICAgaWYgKG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkge1xuICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXRDb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZXN0aW5hdGlvbnMucHVzaChvdXRwdXRDb25uZWN0aW9uWzBdKTtcbiAgICAgICAgICAgIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cy5kZWxldGUob3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlc3RpbmF0aW9ucztcbn07XG5jb25zdCBkZWxldGVDb25uZWN0aW9uVG9EZXN0aW5hdGlvbiA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoc291cmNlKTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMpXG4gICAgICAgIC5maWx0ZXIoKG91dHB1dENvbm5lY3Rpb24pID0+IG91dHB1dENvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmXG4gICAgICAgIChvdXRwdXQgPT09IHVuZGVmaW5lZCB8fCBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQpICYmXG4gICAgICAgIChpbnB1dCA9PT0gdW5kZWZpbmVkIHx8IG91dHB1dENvbm5lY3Rpb25bMl0gPT09IGlucHV0KSlcbiAgICAgICAgLm1hcCgob3V0cHV0Q29ubmVjdGlvbikgPT4ge1xuICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0oc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cy5kZWxldGUob3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIHJldHVybiBvdXRwdXRDb25uZWN0aW9uWzBdO1xuICAgIH0pO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvciA9IChhZGRBdWRpb05vZGVDb25uZWN0aW9ucywgYWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRlY3JlbWVudEN5Y2xlQ291bnRlciwgZGV0ZWN0Q3ljbGVzLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVBdWRpb05vZGUsIGlzTmF0aXZlQXVkaW9QYXJhbSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9Ob2RlIGV4dGVuZHMgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIGlzQWN0aXZlLCBuYXRpdmVBdWRpb05vZGUsIGF1ZGlvTm9kZVJlbmRlcmVyKSB7XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUgPSBuYXRpdmVBdWRpb05vZGU7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTI6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHRvIGRpc2Nvbm5lY3QgYSBzcGVjaWZpYyBkZXN0aW5hdGlvbi5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSAmJlxuICAgICAgICAgICAgICAgIHRydWUgIT09XG4gICAgICAgICAgICAgICAgICAgIGNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSkpIHtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZChuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQVVESU9fTk9ERV9TVE9SRS5zZXQodGhpcywgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIEVWRU5UX0xJU1RFTkVSUy5zZXQodGhpcywgbmV3IFNldCgpKTtcbiAgICAgICAgICAgIGlmIChjb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJyAmJiBpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHRoaXMsIGF1ZGlvTm9kZVJlbmRlcmVyLCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTppbnZhbGlkLXZvaWRcbiAgICAgICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE3NDogU2FmYXJpIGRvZXMgZXhwb3NlIGEgd3JvbmcgbnVtYmVyT2ZPdXRwdXRzIGZvciBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2Rlcy5cbiAgICAgICAgICAgIGlmIChvdXRwdXQgPCAwIHx8IG91dHB1dCA+PSB0aGlzLl9uYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KHRoaXMuX2NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSB8fCBpc05hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUodGhpcy5fbmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlzUGFzc2l2ZSA9IGlzUGFzc2l2ZUF1ZGlvTm9kZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSB8fCBpc1Bhc3NpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KC4uLmNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnICYmICFpc1Bhc3NpdmUgJiYgaXNQYXNzaXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDE6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyB0aGUgY29ycmVjdCBleGNlcHRpb24gc28gZmFyLlxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlzTmV3Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gYWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY0OiBPbmx5IEZpcmVmb3ggZGV0ZWN0cyBjeWNsZXMgc28gZmFyLlxuICAgICAgICAgICAgICAgIGlmIChpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvTm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjeWNsZXMgPSBkZXRlY3RDeWNsZXMoW3RoaXNdLCBkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXIoaXNPZmZsaW5lKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvUGFyYW0gPSBnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzczLCAjMTQ3ICYgIzE1MzogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgdG8gY29ubmVjdCBhbiBpbnB1dCBzaWduYWwgdG8gdGhlIHBsYXliYWNrUmF0ZSBBdWRpb1BhcmFtIG9mIGFuXG4gICAgICAgICAgICAgKiBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuIFRoaXMgY2FuJ3QgYmUgZWFzaWx5IGRldGVjdGVkIGFuZCB0aGF0J3Mgd2h5IHRoZSBvdXRkYXRlZCBuYW1lIHByb3BlcnR5IGlzIHVzZWQgaGVyZSB0byBpZGVudGlmeVxuICAgICAgICAgICAgICogU2FmYXJpLiBJbiBhZGRpdGlvbiB0byB0aGF0IHRoZSBtYXhWYWx1ZSBwcm9wZXJ0eSBpcyB1c2VkIHRvIG9ubHkgZGV0ZWN0IHRoZSBhZmZlY3RlZCB2ZXJzaW9ucyBiZWxvdyB2MTQuMC4yLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9QYXJhbS5uYW1lID09PSAncGxheWJhY2tSYXRlJyAmJiBuYXRpdmVBdWRpb1BhcmFtLm1heFZhbHVlID09PSAxMDI0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lIHx8IGlzUGFzc2l2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU4OiBTYWZhcmkgZG9lc24ndCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGlzTmV3Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IGFkZENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW1PZkF1ZGlvQ29udGV4dCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICBpZiAoaXNOZXdDb25uZWN0aW9uVG9BdWRpb1BhcmFtKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3ljbGVzID0gZGV0ZWN0Q3ljbGVzKFt0aGlzXSwgZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXIoaXNPZmZsaW5lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSB7XG4gICAgICAgICAgICBsZXQgZGVzdGluYXRpb25zO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQodGhpcy5fY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQW55Q29ubmVjdGlvbih0aGlzLCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPCAwIHx8IGRlc3RpbmF0aW9uT3JPdXRwdXQgPj0gdGhpcy5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQ29ubmVjdGlvbkF0T3V0cHV0KHRoaXMsIGlzT2ZmbGluZSwgZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0ICE9PSB1bmRlZmluZWQgJiYgKG91dHB1dCA8IDAgfHwgb3V0cHV0ID49IHRoaXMubnVtYmVyT2ZPdXRwdXRzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGUoZGVzdGluYXRpb25Pck91dHB1dCkgJiYgaW5wdXQgIT09IHVuZGVmaW5lZCAmJiAoaW5wdXQgPCAwIHx8IGlucHV0ID49IGRlc3RpbmF0aW9uT3JPdXRwdXQubnVtYmVyT2ZJbnB1dHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9ucyA9IGRlbGV0ZUNvbm5lY3Rpb25Ub0Rlc3RpbmF0aW9uKHRoaXMsIGlzT2ZmbGluZSwgZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGRlc3RpbmF0aW9uIG9mIGRlc3RpbmF0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN5Y2xlcyA9IGRldGVjdEN5Y2xlcyhbdGhpc10sIGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB2aXNpdEVhY2hBdWRpb05vZGVPbmNlKGN5Y2xlcywgZGVjcmVtZW50Q3ljbGVDb3VudGVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBBdXRvbWF0aW9uRXZlbnRMaXN0IH0gZnJvbSAnYXV0b21hdGlvbi1ldmVudHMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvUGFyYW1GYWN0b3J5ID0gKGFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBhdWRpb1BhcmFtU3RvcmUsIGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlciwgY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudCwgY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudCwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCBpc0F1ZGlvUGFyYW1PZk9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0sIG1heFZhbHVlID0gbnVsbCwgbWluVmFsdWUgPSBudWxsKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTk2IE9ubHkgU2FmYXJpIHNldHMgdGhlIGRlZmF1bHRWYWx1ZSB0byB0aGUgaW5pdGlhbCB2YWx1ZS5cbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gbmF0aXZlQXVkaW9QYXJhbS52YWx1ZTtcbiAgICAgICAgY29uc3QgYXV0b21hdGlvbkV2ZW50TGlzdCA9IG5ldyBBdXRvbWF0aW9uRXZlbnRMaXN0KGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1SZW5kZXJlciA9IGlzQXVkaW9QYXJhbU9mT2ZmbGluZUF1ZGlvQ29udGV4dCA/IGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlcihhdXRvbWF0aW9uRXZlbnRMaXN0KSA6IG51bGw7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW0gPSB7XG4gICAgICAgICAgICBnZXQgZGVmYXVsdFZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtYXhWYWx1ZSA9PT0gbnVsbCA/IG5hdGl2ZUF1ZGlvUGFyYW0ubWF4VmFsdWUgOiBtYXhWYWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pblZhbHVlID09PSBudWxsID8gbmF0aXZlQXVkaW9QYXJhbS5taW5WYWx1ZSA6IG1pblZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9QYXJhbS52YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM5ODogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgeWV0IHRyZWF0IHRoZSB2YWx1ZSBzZXR0ZXIgbGlrZSBhIGNhbGwgdG8gc2V0VmFsdWVBdFRpbWUoKS5cbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FuY2VsQW5kSG9sZEF0VGltZShjYW5jZWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMyODogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgeWV0IGltcGxlbWVudCBjYW5jZWxBbmRIb2xkQXRUaW1lKCkuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBuYXRpdmVBdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZShjYW5jZWxUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzTGFzdEV2ZW50ID0gQXJyYXkuZnJvbShhdXRvbWF0aW9uRXZlbnRMaXN0KS5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRMYXN0RXZlbnQgPSBBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhjYW5jZWxUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzTGFzdEV2ZW50ICE9PSBjdXJyZW50TGFzdEV2ZW50ICYmIGN1cnJlbnRMYXN0RXZlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWUsIGN1cnJlbnRMYXN0RXZlbnQuZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50TGFzdEV2ZW50LnR5cGUgPT09ICdsaW5lYXJSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWUsIGN1cnJlbnRMYXN0RXZlbnQuZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50TGFzdEV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWUsIGN1cnJlbnRMYXN0RXZlbnQuc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlQ3VydmUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKGN1cnJlbnRMYXN0RXZlbnQudmFsdWVzLCBjdXJyZW50TGFzdEV2ZW50LnN0YXJ0VGltZSwgY3VycmVudExhc3RFdmVudC5kdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQoY2FuY2VsVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzQ1OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE4NzogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShlbmRUaW1lKSB8fCBlbmRUaW1lIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTk0OiBGaXJlZm94IGRvZXMgbm90IGltcGxpY2l0bHkgY2FsbCBzZXRWYWx1ZUF0VGltZSgpIGlmIHRoZXJlIGlzIG5vIHByZXZpb3VzIGV2ZW50LlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5NTogRmlyZWZveCBkb2VzIG5vdCBpbXBsaWNpdGx5IGNhbGwgc2V0VmFsdWVBdFRpbWUoKSBpZiB0aGVyZSBpcyBubyBwcmV2aW91cyBldmVudC5cbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuZnJvbShhdXRvbWF0aW9uRXZlbnRMaXN0KS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSkpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZW5kVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFRhcmdldEF0VGltZSh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50KHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFRhcmdldEF0VGltZSh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIHN0YXJ0VGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgMTgzOiBTYWZhcmkgb25seSBhY2NlcHRzIGEgRmxvYXQzMkFycmF5LlxuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlZFZhbHVlcyA9IHZhbHVlcyBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IHZhbHVlcyA6IG5ldyBGbG9hdDMyQXJyYXkodmFsdWVzKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTUyOiBTYWZhcmkgZG9lcyBub3QgY29ycmVjdGx5IGludGVycG9sYXRlIHRoZSB2YWx1ZXMgb2YgdGhlIGN1cnZlLlxuICAgICAgICAgICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGVcbiAgICAgICAgICAgICAgICAgKiBleGlzdGVuY2Ugb2YgdGhlIHdlYmtpdEF1ZGlvQ29udGV4dCBpcyB1c2VkIGFzIGEgd29ya2Fyb3VuZCBoZXJlLlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmRUaW1lID0gc3RhcnRUaW1lICsgZHVyYXRpb247XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNhbXBsZVJhdGUgPSBhdWRpb05vZGUuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXJzdFNhbXBsZSA9IE1hdGguY2VpbChzdGFydFRpbWUgKiBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFzdFNhbXBsZSA9IE1hdGguZmxvb3IoZW5kVGltZSAqIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkludGVycG9sYXRlZFZhbHVlcyA9IGxhc3RTYW1wbGUgLSBmaXJzdFNhbXBsZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZXJwb2xhdGVkVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShudW1iZXJPZkludGVycG9sYXRlZFZhbHVlcyk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZJbnRlcnBvbGF0ZWRWYWx1ZXM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGhlb3JldGljSW5kZXggPSAoKGNvbnZlcnRlZFZhbHVlcy5sZW5ndGggLSAxKSAvIGR1cmF0aW9uKSAqICgoZmlyc3RTYW1wbGUgKyBpKSAvIHNhbXBsZVJhdGUgLSBzdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG93ZXJJbmRleCA9IE1hdGguZmxvb3IodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBwZXJJbmRleCA9IE1hdGguY2VpbCh0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcnBvbGF0ZWRWYWx1ZXNbaV0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VySW5kZXggPT09IHVwcGVySW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBjb252ZXJ0ZWRWYWx1ZXNbbG93ZXJJbmRleF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoMSAtICh0aGVvcmV0aWNJbmRleCAtIGxvd2VySW5kZXgpKSAqIGNvbnZlcnRlZFZhbHVlc1tsb3dlckluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIGNvbnZlcnRlZFZhbHVlc1t1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGludGVycG9sYXRlZFZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoaW50ZXJwb2xhdGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZU9mTGFzdFNhbXBsZSA9IGxhc3RTYW1wbGUgLyBzYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGltZU9mTGFzdFNhbXBsZSA8IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZShhdWRpb1BhcmFtLCBpbnRlcnBvbGF0ZWRWYWx1ZXNbaW50ZXJwb2xhdGVkVmFsdWVzLmxlbmd0aCAtIDFdLCB0aW1lT2ZMYXN0U2FtcGxlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUoYXVkaW9QYXJhbSwgY29udmVydGVkVmFsdWVzW2NvbnZlcnRlZFZhbHVlcy5sZW5ndGggLSAxXSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50KGNvbnZlcnRlZFZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoY29udmVydGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGF1ZGlvUGFyYW1TdG9yZS5zZXQoYXVkaW9QYXJhbSwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgIGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZS5zZXQoYXVkaW9QYXJhbSwgYXVkaW9Ob2RlKTtcbiAgICAgICAgYWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0sIGF1ZGlvUGFyYW1SZW5kZXJlcik7XG4gICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tcGFyYW0tZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyID0gKGF1dG9tYXRpb25FdmVudExpc3QpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgICByZXBsYXkoYXVkaW9QYXJhbSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBhdXRvbWF0aW9uRXZlbnQgb2YgYXV0b21hdGlvbkV2ZW50TGlzdCkge1xuICAgICAgICAgICAgICAgIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2V4cG9uZW50aWFsUmFtcFRvVmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZW5kVGltZSwgdmFsdWUgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdsaW5lYXJSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBlbmRUaW1lLCB2YWx1ZSB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRUYXJnZXQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgc3RhcnRUaW1lLCB0YXJnZXQsIHRpbWVDb25zdGFudCB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFRhcmdldEF0VGltZSh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBzdGFydFRpbWUsIHZhbHVlIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnc2V0VmFsdWVDdXJ2ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBkdXJhdGlvbiwgc3RhcnRUaW1lLCB2YWx1ZXMgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBhcHBseSBhbiB1bmtub3duIGF1dG9tYXRpb24uXCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tcGFyYW0tcmVuZGVyZXIuanMubWFwIiwiZXhwb3J0IGNsYXNzIFJlYWRPbmx5TWFwIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJhbWV0ZXJzKSB7XG4gICAgICAgIHRoaXMuX21hcCA9IG5ldyBNYXAocGFyYW1ldGVycyk7XG4gICAgfVxuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLnNpemU7XG4gICAgfVxuICAgIGVudHJpZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZW50cmllcygpO1xuICAgIH1cbiAgICBmb3JFYWNoKGNhbGxiYWNrLCB0aGlzQXJnID0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IGNhbGxiYWNrLmNhbGwodGhpc0FyZywgdmFsdWUsIGtleSwgdGhpcykpO1xuICAgIH1cbiAgICBnZXQobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmdldChuYW1lKTtcbiAgICB9XG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5oYXMobmFtZSk7XG4gICAgfVxuICAgIGtleXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAua2V5cygpO1xuICAgIH1cbiAgICB2YWx1ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAudmFsdWVzKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVhZC1vbmx5LW1hcC5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IFJlYWRPbmx5TWFwIH0gZnJvbSAnLi4vcmVhZC1vbmx5LW1hcCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIC8vIEJ1ZyAjNjE6IFRoZSBjaGFubmVsQ291bnRNb2RlIHNob3VsZCBiZSAnbWF4JyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgYnV0IGlzIHNldCB0byAnZXhwbGljaXQnIHRvIGFjaGlldmUgY29uc2lzdGVudCBiZWhhdmlvci5cbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBudW1iZXJPZklucHV0czogMSxcbiAgICBudW1iZXJPZk91dHB1dHM6IDEsXG4gICAgcGFyYW1ldGVyRGF0YToge30sXG4gICAgcHJvY2Vzc29yT3B0aW9uczoge31cbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID0gKGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMsIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb1dvcmtsZXROb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgICAgICB2YXIgX2E7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zKHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH0pO1xuICAgICAgICAgICAgLy8gQnVnICMxOTE6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIGlmIHRoZSBvcHRpb25zIGFyZW4ndCBjbG9uYWJsZS5cbiAgICAgICAgICAgIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5KG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID0gTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHByb2Nlc3NvckNvbnN0cnVjdG9yID0gbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID09PSBudWxsIHx8IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCA9PT0gdm9pZCAwID8gdm9pZCAwIDogbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLmdldChuYW1lKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg2OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGFsbG93IHRvIGNyZWF0ZSBhbiBBdWRpb1dvcmtsZXROb2RlIG9uIGEgY2xvc2VkIEF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBpc09mZmxpbmUgfHwgbmF0aXZlQ29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCdcbiAgICAgICAgICAgICAgICA/IG5hdGl2ZUNvbnRleHRcbiAgICAgICAgICAgICAgICA6IChfYSA9IGdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IG5hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZShuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBpc09mZmxpbmUgPyBudWxsIDogY29udGV4dC5iYXNlTGF0ZW5jeSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYW1lLCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlcihuYW1lLCBtZXJnZWRPcHRpb25zLCBwcm9jZXNzb3JDb25zdHJ1Y3RvcikgOiBudWxsKSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQHRvZG8gQWRkIGEgbWVjaGFuaXNtIHRvIHN3aXRjaCBhbiBBdWRpb1dvcmtsZXROb2RlIHRvIHBhc3NpdmUgb25jZSB0aGUgcHJvY2VzcygpIGZ1bmN0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXRQcm9jZXNzb3JcbiAgICAgICAgICAgICAqIHJldHVybnMgZmFsc2UuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvV29ya2xldE5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gW107XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnMuZm9yRWFjaCgobmF0aXZlQXVkaW9QYXJhbSwgbm0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnMucHVzaChbbm0sIGF1ZGlvUGFyYW1dKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGU7XG4gICAgICAgICAgICB0aGlzLl9vbnByb2Nlc3NvcmVycm9yID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtZXRlcnMgPSBuZXcgUmVhZE9ubHlNYXAocGFyYW1ldGVycyk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM4NiAmICM4NzogSW52b2tpbmcgdGhlIHJlbmRlcmVyIG9mIGFuIEF1ZGlvV29ya2xldE5vZGUgbWlnaHQgYmUgbmVjZXNzYXJ5IGlmIGl0IGhhcyBubyBkaXJlY3Qgb3IgaW5kaXJlY3QgY29ubmVjdGlvbiB0b1xuICAgICAgICAgICAgICogdGhlIGRlc3RpbmF0aW9uLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUobmF0aXZlQ29udGV4dCwgdGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnModGhpcyk7XG4gICAgICAgICAgICBzZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFjdGl2ZUlucHV0cyk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9ucHJvY2Vzc29yZXJyb3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25wcm9jZXNzb3JlcnJvcih2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgPSB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlLm9ucHJvY2Vzc29yZXJyb3I7XG4gICAgICAgICAgICB0aGlzLl9vbnByb2Nlc3NvcmVycm9yID1cbiAgICAgICAgICAgICAgICBuYXRpdmVPblByb2Nlc3NvckVycm9yICE9PSBudWxsICYmIG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgPT09IHdyYXBwZWRMaXN0ZW5lclxuICAgICAgICAgICAgICAgICAgICA/IHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIDogbmF0aXZlT25Qcm9jZXNzb3JFcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFyYW1ldGVycygpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9wYXJhbWV0ZXJzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhlIGRlZmluaXRpb24gdGhhdCBUeXBlU2NyaXB0IHVzZXMgb2YgdGhlIEF1ZGlvUGFyYW1NYXAgaXMgbGFja2luZyBtYW55IG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbWV0ZXJzO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3J0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUucG9ydDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBmdW5jdGlvbiBjb3B5RnJvbUNoYW5uZWwoYXVkaW9CdWZmZXIsIFxuLy8gQHRvZG8gVGhlcmUgaXMgY3VycmVudGx5IG5vIHdheSB0byBkZWZpbmUgc29tZXRoaW5nIGxpa2UgeyBbIGtleTogbnVtYmVyIHwgc3RyaW5nIF06IEZsb2F0MzJBcnJheSB9XG5wYXJlbnQsIGtleSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KSB7XG4gICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHBhcmVudFtrZXldID0gbmV3IEZsb2F0MzJBcnJheSgxMjgpO1xuICAgICAgICB9XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbChwYXJlbnRba2V5XSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKS5cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcik7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBwYXJlbnRba2V5XSA9IGNoYW5uZWxEYXRhLnNsaWNlKGJ1ZmZlck9mZnNldCwgYnVmZmVyT2Zmc2V0ICsgMTI4KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNsaWNlZElucHV0ID0gbmV3IEZsb2F0MzJBcnJheShjaGFubmVsRGF0YS5idWZmZXIsIGJ1ZmZlck9mZnNldCAqIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCwgMTI4KTtcbiAgICAgICAgICAgIHBhcmVudFtrZXldLnNldChzbGljZWRJbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb3B5LWZyb20tY2hhbm5lbC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY29weVRvQ2hhbm5lbCA9IChhdWRpb0J1ZmZlciwgcGFyZW50LCBrZXksIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCkgPT4ge1xuICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbChwYXJlbnRba2V5XSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlUb0NoYW5uZWwoKS5cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKS5zZXQocGFyZW50W2tleV0sIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29weS10by1jaGFubmVsLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOZXN0ZWRBcnJheXMgPSAoeCwgeSkgPT4ge1xuICAgIGNvbnN0IGFycmF5cyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeDsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IGFycmF5ID0gW107XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IHR5cGVvZiB5ID09PSAnbnVtYmVyJyA/IHkgOiB5W2ldO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICBhcnJheS5wdXNoKG5ldyBGbG9hdDMyQXJyYXkoMTI4KSk7XG4gICAgICAgIH1cbiAgICAgICAgYXJyYXlzLnB1c2goYXJyYXkpO1xuICAgIH1cbiAgICByZXR1cm4gYXJyYXlzO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1uZXN0ZWQtYXJyYXlzLmpzLm1hcCIsImltcG9ydCB7IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KSA9PiB7XG4gICAgY29uc3Qgbm9kZVRvUHJvY2Vzc29yTWFwID0gZ2V0VmFsdWVGb3JLZXkoTk9ERV9UT19QUk9DRVNTT1JfTUFQUywgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KG5vZGVUb1Byb2Nlc3Nvck1hcCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzLm1hcCIsImltcG9ydCB7IGNvcHlGcm9tQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS1mcm9tLWNoYW5uZWwnO1xuaW1wb3J0IHsgY29weVRvQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS10by1jaGFubmVsJztcbmltcG9ydCB7IGNyZWF0ZU5lc3RlZEFycmF5cyB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEF1ZGlvV29ya2xldFByb2Nlc3NvciB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuY29uc3QgcHJvY2Vzc0J1ZmZlciA9IGFzeW5jIChwcm94eSwgcmVuZGVyZWRCdWZmZXIsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMsIG91dHB1dENoYW5uZWxDb3VudCwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKSA9PiB7XG4gICAgLy8gQ2VpbCB0aGUgbGVuZ3RoIHRvIHRoZSBuZXh0IGZ1bGwgcmVuZGVyIHF1YW50dW0uXG4gICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICBjb25zdCBsZW5ndGggPSByZW5kZXJlZEJ1ZmZlciA9PT0gbnVsbCA/IE1hdGguY2VpbChwcm94eS5jb250ZXh0Lmxlbmd0aCAvIDEyOCkgKiAxMjggOiByZW5kZXJlZEJ1ZmZlci5sZW5ndGg7XG4gICAgY29uc3QgbnVtYmVyT2ZJbnB1dENoYW5uZWxzID0gb3B0aW9ucy5jaGFubmVsQ291bnQgKiBvcHRpb25zLm51bWJlck9mSW5wdXRzO1xuICAgIGNvbnN0IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPSBvdXRwdXRDaGFubmVsQ291bnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCk7XG4gICAgY29uc3QgcHJvY2Vzc2VkQnVmZmVyID0gbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9PT0gMFxuICAgICAgICA/IG51bGxcbiAgICAgICAgOiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZk91dHB1dENoYW5uZWxzLCBsZW5ndGgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBwcm9jZXNzb3IgY29uc3RydWN0b3IuJyk7XG4gICAgfVxuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMocHJveHkpO1xuICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IGF3YWl0IGdldEF1ZGlvV29ya2xldFByb2Nlc3NvcihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eSk7XG4gICAgY29uc3QgaW5wdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMsIG9wdGlvbnMuY2hhbm5lbENvdW50KTtcbiAgICBjb25zdCBvdXRwdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzLCBvdXRwdXRDaGFubmVsQ291bnQpO1xuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBBcnJheS5mcm9tKHByb3h5LnBhcmFtZXRlcnMua2V5cygpKS5yZWR1Y2UoKHBybXRycywgbmFtZSkgPT4gKHsgLi4ucHJtdHJzLCBbbmFtZV06IG5ldyBGbG9hdDMyQXJyYXkoMTI4KSB9KSwge30pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEyOCkge1xuICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZklucHV0cyA+IDAgJiYgcmVuZGVyZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChyZW5kZXJlZEJ1ZmZlciwgaW5wdXRzW2pdLCBrLCBrLCBpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQgJiYgcmVuZGVyZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmZvckVhY2goKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChyZW5kZXJlZEJ1ZmZlciwgcGFyYW1ldGVycywgbmFtZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgsIGkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgIGlmIChvdXRwdXRzW2pdW2tdLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0c1tqXVtrXSA9IG5ldyBGbG9hdDMyQXJyYXkoMTI4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHBvdGVudGlhbGx5RW1wdHlJbnB1dHMgPSBpbnB1dHMubWFwKChpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9Ob2RlQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzW2luZGV4XS5zaXplID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVTb3VyY2VGbGFnID0gZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUoaSAvIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBhdWRpb1dvcmtsZXRQcm9jZXNzb3IucHJvY2Vzcyhwb3RlbnRpYWxseUVtcHR5SW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSk7XG4gICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG91dHB1dENoYW5uZWxDb3VudFtqXTsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3B5VG9DaGFubmVsKHByb2Nlc3NlZEJ1ZmZlciwgb3V0cHV0c1tqXSwgaywgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2pdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghYWN0aXZlU291cmNlRmxhZykge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgcHJveHkuZGlzcGF0Y2hFdmVudChuZXcgRXJyb3JFdmVudCgncHJvY2Vzc29yZXJyb3InLCB7XG4gICAgICAgICAgICAgICAgY29sbm86IGVycm9yLmNvbG5vLFxuICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBlcnJvci5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICBsaW5lbm86IGVycm9yLmxpbmVubyxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcHJvY2Vzc2VkQnVmZmVyO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBkZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChuYW1lLCBvcHRpb25zLCBwcm9jZXNzb3JDb25zdHJ1Y3RvcikgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgcHJvY2Vzc2VkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgbGV0IG5hdGl2ZU91dHB1dE5vZGVzID0gbnVsbDtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxDb3VudCA9IEFycmF5LmlzQXJyYXkob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpXG4gICAgICAgICAgICAgICAgPyBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudFxuICAgICAgICAgICAgICAgIDogQXJyYXkuZnJvbShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgICAgICAvLyBCdWcgIzYxOiBPbmx5IENocm9tZSwgRWRnZSAmIEZpcmVmb3ggaGF2ZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB5ZXQuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9IG91dHB1dENoYW5uZWxDb3VudC5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSArIHZhbHVlLCAwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyksXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJveHkubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBvdXRwdXRDaGFubmVsQ291bnRbaV1cbiAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBnYWluOiAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY29ubmVjdCA9IGNvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMpO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QgPSBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLmJpbmQobnVsbCwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVPdXRwdXROb2RlcyA9IFtvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMsIG91dHB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFuYXRpdmVBdWRpb1dvcmtsZXROb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBuZXcgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVPdXRwdXROb2RlcyA9PT0gbnVsbCA/IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgOiBuYXRpdmVPdXRwdXROb2Rlc1syXSk7XG4gICAgICAgICAgICBpZiAobmF0aXZlT3V0cHV0Tm9kZXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyUHJvbWlzZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBwcm9jZXNzb3IgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGdldHMgbm90IGluaXRpYWxpemVkIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZJbnB1dENoYW5uZWxzID0gcHJveHkuY2hhbm5lbENvdW50ICogcHJveHkubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mUGFyYW1ldGVycyA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWQgPyAwIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJCdWZmZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IobnVtYmVyT2ZDaGFubmVscywgXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDZWlsIHRoZSBsZW5ndGggdG8gdGhlIG5leHQgZnVsbCByZW5kZXIgcXVhbnR1bS5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICAgICAgICAgICAgICBNYXRoLmNlaWwocHJveHkuY29udGV4dC5sZW5ndGggLyAxMjgpICogMTI4LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2Fpbk5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW5Ob2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGVzID0gYXdhaXQgUHJvbWlzZS5hbGwoQXJyYXkuZnJvbShwcm94eS5wYXJhbWV0ZXJzLnZhbHVlcygpKS5tYXAoYXN5bmMgKGF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDogYXVkaW9QYXJhbS52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24ocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycylcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGosIGkgKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGopO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBjb25zdGFudFNvdXJjZU5vZGVdIG9mIGNvbnN0YW50U291cmNlTm9kZXMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChnYWluTm9kZXMubWFwKChnYWluTm9kZSkgPT4gcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBnYWluTm9kZSkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkQnVmZmVyUHJvbWlzZSA9IHByb2Nlc3NCdWZmZXIocHJveHksIG51bWJlck9mQ2hhbm5lbHMgPT09IDAgPyBudWxsIDogYXdhaXQgcmVuZGVyQnVmZmVyKCksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMsIG91dHB1dENoYW5uZWxDb3VudCwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvY2Vzc2VkQnVmZmVyID0gYXdhaXQgcHJvY2Vzc2VkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgW291dHB1dENoYW5uZWxTcGxpdHRlck5vZGUsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcywgb3V0cHV0R2Fpbk5vZGVdID0gbmF0aXZlT3V0cHV0Tm9kZXM7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gcHJvY2Vzc2VkQnVmZmVyO1xuICAgICAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IHByb3h5Lm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlID0gb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG91dHB1dENoYW5uZWxDb3VudFtpXTsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBqLCBqKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dEdhaW5Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb1dvcmtsZXROb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW25tLCBhdWRpb1BhcmFtXSBvZiBwcm94eS5wYXJhbWV0ZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIFxuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzLmdldChubSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW25tLCBhdWRpb1BhcmFtXSBvZiBwcm94eS5wYXJhbWV0ZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhlIGRlZmluaXRpb24gdGhhdCBUeXBlU2NyaXB0IHVzZXMgb2YgdGhlIEF1ZGlvUGFyYW1NYXAgaXMgbGFja2luZyBtYW55IG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycy5nZXQobm0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KTtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb1dvcmtsZXROb2RlT3JHYWluTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb1dvcmtsZXROb2RlT3JHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8td29ya2xldC1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChhZGRBdWRpb1dvcmtsZXRNb2R1bGUsIGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciwgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IsIGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yLCBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IsIGRlY29kZUF1ZGlvRGF0YSwgZGVsYXlOb2RlQ29uc3RydWN0b3IsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciwgZ2Fpbk5vZGVDb25zdHJ1Y3RvciwgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yLCBwYW5uZXJOb2RlQ29uc3RydWN0b3IsIHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yLCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IsIHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQmFzZUF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgc3VwZXIoX25hdGl2ZUNvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udGV4dCA9IF9uYXRpdmVDb250ZXh0O1xuICAgICAgICAgICAgdGhpcy5fYXVkaW9Xb3JrbGV0ID1cbiAgICAgICAgICAgICAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZE1vZHVsZTogKG1vZHVsZVVSTCwgb3B0aW9ucykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRBdWRpb1dvcmtsZXRNb2R1bGUodGhpcywgbW9kdWxlVVJMLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgYXVkaW9Xb3JrbGV0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F1ZGlvV29ya2xldDtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVBbmFseXNlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQmlxdWFkRmlsdGVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ2hhbm5lbE1lcmdlcihudW1iZXJPZklucHV0cyA9IDYpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG51bWJlck9mSW5wdXRzIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMgPSA2KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG51bWJlck9mT3V0cHV0cyB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDb25zdGFudFNvdXJjZSgpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ29udm9sdmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lID0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBkZWxheU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1heERlbGF5VGltZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVHYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBnYWluTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUlJUkZpbHRlcihmZWVkZm9yd2FyZCwgZmVlZGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgZmVlZGJhY2ssIGZlZWRmb3J3YXJkIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU9zY2lsbGF0b3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlUGFubmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBwYW5uZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlUGVyaW9kaWNXYXZlKHJlYWwsIGltYWcsIGNvbnN0cmFpbnRzID0geyBkaXNhYmxlTm9ybWFsaXphdGlvbjogZmFsc2UgfSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBwZXJpb2RpY1dhdmVDb25zdHJ1Y3Rvcih0aGlzLCB7IC4uLmNvbnN0cmFpbnRzLCBpbWFnLCByZWFsIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZVN0ZXJlb1Bhbm5lcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZVdhdmVTaGFwZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSwgc3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVjb2RlQXVkaW9EYXRhKHRoaXMuX25hdGl2ZUNvbnRleHQsIGF1ZGlvRGF0YSkudGhlbigoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHN1Y2Nlc3NDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBlcnJvckNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yQ2FsbGJhY2soZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIFE6IDEsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBkZXR1bmU6IDAsXG4gICAgZnJlcXVlbmN5OiAzNTAsXG4gICAgZ2FpbjogMCxcbiAgICB0eXBlOiAnbG93cGFzcydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBCaXF1YWRGaWx0ZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBiaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBiaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM4MDogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX1EgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgLy8gQnVnICM3ODogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZGV0dW5lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lLCAxMjAwICogTWF0aC5sb2cyKE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUKSwgLTEyMDAgKiBNYXRoLmxvZzIoTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQpKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzc6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZSBmb3IgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3ksIGNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsIDApO1xuICAgICAgICAgICAgLy8gQnVnICM3OTogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZ2FpbiA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4sIDQwICogTWF0aC5sb2cxMChNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCksIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlO1xuICAgICAgICAgICAgLy8gQHRvZG8gRGV0ZXJtaW5lIGEgbWVhbmluZ2Z1bCB0YWlsLXRpbWUgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIG9uZSBzZWNvbmQuXG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGV0dW5lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldHVuZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZnJlcXVlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZ2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nYWluO1xuICAgICAgICB9XG4gICAgICAgIGdldCBRKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX1E7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS50eXBlO1xuICAgICAgICB9XG4gICAgICAgIHNldCB0eXBlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLnR5cGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg5OiBTYWZhcmkgZG9lcyB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvci5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNjg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgcGFyYW1ldGVycyBkaWZmZXIgaW4gdGhlaXIgbGVuZ3RoLlxuICAgICAgICAgICAgaWYgKGZyZXF1ZW5jeUh6Lmxlbmd0aCAhPT0gbWFnUmVzcG9uc2UubGVuZ3RoIHx8IG1hZ1Jlc3BvbnNlLmxlbmd0aCAhPT0gcGhhc2VSZXNwb25zZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmlxdWFkLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIFE6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZXR1bmU6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3k6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBnYWluOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUudHlwZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQmlxdWFkRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LlEsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmZyZXF1ZW5jeSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LlEsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gcmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUJpcXVhZEZpbHRlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmlxdWFkLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNhY2hlVGVzdFJlc3VsdCA9IChvbmdvaW5nVGVzdHMsIHRlc3RSZXN1bHRzKSA9PiB7XG4gICAgcmV0dXJuICh0ZXN0ZXIsIHRlc3QpID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVkVGVzdFJlc3VsdCA9IHRlc3RSZXN1bHRzLmdldCh0ZXN0ZXIpO1xuICAgICAgICBpZiAoY2FjaGVkVGVzdFJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FjaGVkVGVzdFJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvbmdvaW5nVGVzdCA9IG9uZ29pbmdUZXN0cy5nZXQodGVzdGVyKTtcbiAgICAgICAgaWYgKG9uZ29pbmdUZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBvbmdvaW5nVGVzdDtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3luY2hyb25vdXNUZXN0UmVzdWx0ID0gdGVzdCgpO1xuICAgICAgICAgICAgaWYgKHN5bmNocm9ub3VzVGVzdFJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgICAgICAgICAgICBvbmdvaW5nVGVzdHMuc2V0KHRlc3Rlciwgc3luY2hyb25vdXNUZXN0UmVzdWx0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gc3luY2hyb25vdXNUZXN0UmVzdWx0XG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKGZpbmFsVGVzdFJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBvbmdvaW5nVGVzdHMuZGVsZXRlKHRlc3Rlcik7XG4gICAgICAgICAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIGZpbmFsVGVzdFJlc3VsdCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmaW5hbFRlc3RSZXN1bHQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZXN0UmVzdWx0cy5zZXQodGVzdGVyLCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQpO1xuICAgICAgICAgICAgcmV0dXJuIHN5bmNocm9ub3VzVGVzdFJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICB0ZXN0UmVzdWx0cy5zZXQodGVzdGVyLCBmYWxzZSk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNhY2hlLXRlc3QtcmVzdWx0LmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgbnVtYmVyT2ZJbnB1dHM6IDZcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBDaGFubmVsTWVyZ2VyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyID0gKChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgPyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLW1lcmdlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBdWRpb05vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mSW5wdXRzXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLW1lcmdlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogNixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICBudW1iZXJPZk91dHB1dHM6IDZcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENoYW5uZWxTcGxpdHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyh7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyID0gKChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgPyBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLXNwbGl0dGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBdWRpb05vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb05vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IG5hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2hhbm5lbC1zcGxpdHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtID0gKHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgbmF0aXZlQXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICByZXR1cm4gcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKGF1ZGlvUGFyYW0sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdC1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAob3V0cHV0QXVkaW9Ob2RlcywgZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICBjb25zdCBvdXRwdXRBdWRpb05vZGUgPSBvdXRwdXRBdWRpb05vZGVzW291dHB1dF07XG4gICAgICAgIGlmIChvdXRwdXRBdWRpb05vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIDAsIGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIDApO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAyLCA0NDEwMCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlcjtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB0cnVlO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzY29ubmVjdChuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdGVkLW5hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBvZmZzZXQ6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENvbnN0YW50U291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyID0gKChpc09mZmxpbmUgPyBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyID0gY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM2MiAmICM3NDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgQ29uc3RhbnRTb3VyY2VOb2RlcyBhbmQgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlXG4gICAgICAgICAgICAgKiBmb3IgR2Fpbk5vZGVzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICB0aGlzLl9vZmZzZXQgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvZmZzZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb2Zmc2V0O1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub25lbmRlZCA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uRW5kZWQgPSB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBuYXRpdmVPbkVuZGVkICE9PSBudWxsICYmIG5hdGl2ZU9uRW5kZWQgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25FbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KHdoZW4pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIuc3RhcnQgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUodGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnN0b3Aod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldC52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoc3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RvcChzdG9wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9mZnNldCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vZmZzZXQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2V0IHN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RvcCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0b3AgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ29udmVydE51bWJlclRvVW5zaWduZWRMb25nID0gKHVuaXQzMkFycmF5KSA9PiB7XG4gICAgcmV0dXJuICh2YWx1ZSkgPT4ge1xuICAgICAgICB1bml0MzJBcnJheVswXSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdW5pdDMyQXJyYXlbMF07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBidWZmZXI6IG51bGwsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdjbGFtcGVkLW1heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRpc2FibGVOb3JtYWxpemF0aW9uOiBmYWxzZVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBDb252b2x2ZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBjb252b2x2ZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDb252b2x2ZXJOb2RlLCBjb252b2x2ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUgPSBuYXRpdmVDb252b2x2ZXJOb2RlO1xuICAgICAgICAgICAgaWYgKG1lcmdlZE9wdGlvbnMuYnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgbWVyZ2VkT3B0aW9ucy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgYnVmZmVyKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciA9IHZhbHVlO1xuICAgICAgICAgICAgLy8gQnVnICMxMTU6IFNhZmFyaSBkb2VzIG5vdCBhbGxvdyB0byBzZXQgdGhlIGJ1ZmZlciB0byBudWxsLlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsICYmIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciA9PT0gbnVsbCA/IDAgOiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG5vcm1hbGl6ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbm9ybWFsaXplKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb252b2x2ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVDb252b2x2ZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQ29udm9sdmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnZvbHZlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVDb252b2x2ZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29udm9sdmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG5hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUNvbnZvbHZlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVDb252b2x2ZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQ29udm9sdmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVOb3JtYWxpemF0aW9uOiAhbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnZvbHZlck5vZGUgPSBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29udm9sdmVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVDb252b2x2ZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29udm9sdmVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udm9sdmVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVDb252b2x2ZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZvbHZlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSAoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgLy8gQnVnICMxNDMsICMxNDQgJiAjMTQ2OiBTYWZhcmkgdGhyb3dzIGEgU3ludGF4RXJyb3Igd2hlbiBudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGggb3Igc2FtcGxlUmF0ZSBhcmUgaW52YWxpZC5cbiAgICAgICAgICAgIGlmIChlcnIubmFtZSA9PT0gJ1N5bnRheEVycm9yJykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVEYXRhQ2xvbmVFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdEYXRhQ2xvbmVFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YS1jbG9uZS1lcnJvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgZGV0YWNoQXJyYXlCdWZmZXIgPSAoYXJyYXlCdWZmZXIpID0+IHtcbiAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGNvbnN0IGNsb3NlQW5kUmVzb2x2ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHBvcnQyLm9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgICAgICAgICAgcG9ydDIuY2xvc2UoKTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgcG9ydDIub25tZXNzYWdlID0gKCkgPT4gY2xvc2VBbmRSZXNvbHZlKCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwb3J0MS5wb3N0TWVzc2FnZShhcnJheUJ1ZmZlciwgW2FycmF5QnVmZmVyXSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGNsb3NlQW5kUmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGV0YWNoLWFycmF5LWJ1ZmZlci5qcy5tYXAiLCJpbXBvcnQgeyBkZXRhY2hBcnJheUJ1ZmZlciB9IGZyb20gJy4uL2hlbHBlcnMvZGV0YWNoLWFycmF5LWJ1ZmZlcic7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlY29kZUF1ZGlvRGF0YSA9IChhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZURhdGFDbG9uZUVycm9yLCBjcmVhdGVFbmNvZGluZ0Vycm9yLCBkZXRhY2hlZEFycmF5QnVmZmVycywgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVDb250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHRlc3RQcm9taXNlU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcykgPT4ge1xuICAgIHJldHVybiAoYW55Q29udGV4dCwgYXVkaW9EYXRhKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBpc05hdGl2ZUNvbnRleHQoYW55Q29udGV4dCkgPyBhbnlDb250ZXh0IDogZ2V0TmF0aXZlQ29udGV4dChhbnlDb250ZXh0KTtcbiAgICAgICAgLy8gQnVnICM0MzogT25seSBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYSBEYXRhQ2xvbmVFcnJvci5cbiAgICAgICAgaWYgKGRldGFjaGVkQXJyYXlCdWZmZXJzLmhhcyhhdWRpb0RhdGEpKSB7XG4gICAgICAgICAgICBjb25zdCBlcnIgPSBjcmVhdGVEYXRhQ2xvbmVFcnJvcigpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIGF1ZGlvRGF0YSBwYXJhbWV0ZXIgbWF5YmUgb2YgYSB0eXBlIHdoaWNoIGNhbid0IGJlIGFkZGVkIHRvIGEgV2Vha1NldC5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRldGFjaGVkQXJyYXlCdWZmZXJzLmFkZChhdWRpb0RhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMyMTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgeWV0LlxuICAgICAgICBpZiAoY2FjaGVUZXN0UmVzdWx0KHRlc3RQcm9taXNlU3VwcG9ydCwgKCkgPT4gdGVzdFByb21pc2VTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSkudGhlbigoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMzogU2FmYXJpIGRvZXMgbmV1dGVyIHRoZSBBcnJheUJ1ZmZlci5cbiAgICAgICAgICAgICAgICBkZXRhY2hBcnJheUJ1ZmZlcihhdWRpb0RhdGEpLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE1NzogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0aGUgYnVmZmVyT2Zmc2V0IHRvIGJlIG91dC1vZi1ib3VuZHMuXG4gICAgICAgICAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQoYXVkaW9CdWZmZXIpKSkge1xuICAgICAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3QgcmV0dXJuIGEgUHJvbWlzZSB5ZXQuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb21wbGV0ZSA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMzogU2FmYXJpIGRvZXMgbmV1dGVyIHRoZSBBcnJheUJ1ZmZlci5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBkZXRhY2hBcnJheUJ1ZmZlcihhdWRpb0RhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGZhaWwgPSAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgY29tcGxldGUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBCdWcgIzI2OiBTYWZhcmkgdGhyb3dzIGEgc3luY2hyb25vdXMgZXJyb3IuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTogU2FmYXJpIHJlcXVpcmVzIGEgc3VjY2Vzc0NhbGxiYWNrLlxuICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSwgKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxMDA6IFNhZmFyaSBkb2VzIHRocm93IGEgd3JvbmcgZXJyb3Igd2hlbiBjYWxsaW5nIGdldENoYW5uZWxEYXRhKCkgd2l0aCBhbiBvdXQtb2YtYm91bmRzIHZhbHVlLlxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlKCkudGhlbigoKSA9PiByZXNvbHZlKGF1ZGlvQnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ6IFNhZmFyaSByZXR1cm5zIG51bGwgaW5zdGVhZCBvZiBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFpbChjcmVhdGVFbmNvZGluZ0Vycm9yKCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmFpbChlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgZmFpbChlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlY29kZS1hdWRpby1kYXRhLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uJztcbmV4cG9ydCBjb25zdCBjcmVhdGVEZWNyZW1lbnRDeWNsZUNvdW50ZXIgPSAoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjeWNsZUNvdW50ZXJzLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBnZXROYXRpdmVDb250ZXh0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGNvdW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGN5Y2xlQ291bnRlciA9IGN5Y2xlQ291bnRlcnMuZ2V0KGF1ZGlvTm9kZSk7XG4gICAgICAgIGlmIChjeWNsZUNvdW50ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBleHBlY3RlZCBjeWNsZSBjb3VudC4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChhdWRpb05vZGUuY29udGV4dCk7XG4gICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gY291bnQpIHtcbiAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuZGVsZXRlKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiBpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlU291cmNlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dFsxXSwgb3V0cHV0WzJdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0ob3V0cHV0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSwgb3V0cHV0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuc2V0KGF1ZGlvTm9kZSwgY3ljbGVDb3VudGVyIC0gY291bnQpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWNyZW1lbnQtY3ljbGUtY291bnRlci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBkZWxheVRpbWU6IDAsXG4gICAgbWF4RGVsYXlUaW1lOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGF5Tm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEZWxheU5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIERlbGF5Tm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZSA9IGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGRlbGF5Tm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyKG1lcmdlZE9wdGlvbnMubWF4RGVsYXlUaW1lKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZURlbGF5Tm9kZSwgZGVsYXlOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fZGVsYXlUaW1lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgbWVyZ2VkT3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkZWxheVRpbWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVsYXlUaW1lO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChtYXhEZWxheVRpbWUpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEZWxheU5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlRGVsYXlOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlRGVsYXlOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVEZWxheU5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEZWxheU5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVEZWxheU5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEZWxheU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVEZWxheU5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVEZWxheU5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVEZWxheU5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZWxheVRpbWU6IG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG1heERlbGF5VGltZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlRGVsYXlOb2RlID0gY3JlYXRlTmF0aXZlRGVsYXlOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVEZWxheU5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEZWxheU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZWxheVRpbWUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGVsYXlUaW1lLCBuYXRpdmVEZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZURlbGF5Tm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRGVsYXlOb2RlID0gcmVuZGVyZWROYXRpdmVEZWxheU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVEZWxheU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlRGVsYXlOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZURlbGF5Tm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKHBpY2tFbGVtZW50RnJvbVNldCkgPT4ge1xuICAgIHJldHVybiAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICAgICAgcmV0dXJuIHBpY2tFbGVtZW50RnJvbVNldChhY3RpdmVJbnB1dHNbaW5wdXRdLCAoYWN0aXZlSW5wdXRDb25uZWN0aW9uKSA9PiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSAoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBhdWRpb1dvcmtsZXROb2RlKSA9PiB7XG4gICAgICAgIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVDb250ZXh0KS5kZWxldGUoYXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzRGVsYXlOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnZGVsYXlUaW1lJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsYXktbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzRGVsYXlOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2RlbGF5LW5vZGUnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURldGVjdEN5Y2xlcyA9IChhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRWYWx1ZUZvcktleSkgPT4ge1xuICAgIHJldHVybiBmdW5jdGlvbiBkZXRlY3RDeWNsZXMoY2hhaW4sIG5leHRMaW5rKSB7XG4gICAgICAgIGNvbnN0IGF1ZGlvTm9kZSA9IGlzQXVkaW9Ob2RlKG5leHRMaW5rKSA/IG5leHRMaW5rIDogZ2V0VmFsdWVGb3JLZXkoYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBuZXh0TGluayk7XG4gICAgICAgIGlmIChpc0RlbGF5Tm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYWluWzBdID09PSBhdWRpb05vZGUpIHtcbiAgICAgICAgICAgIHJldHVybiBbY2hhaW5dO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFpbi5pbmNsdWRlcyhhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShvdXRwdXRzKVxuICAgICAgICAgICAgLm1hcCgob3V0cHV0Q29ubmVjdGlvbikgPT4gZGV0ZWN0Q3ljbGVzKFsuLi5jaGFpbiwgYXVkaW9Ob2RlXSwgb3V0cHV0Q29ubmVjdGlvblswXSkpXG4gICAgICAgICAgICAucmVkdWNlKChtZXJnZWRDeWNsZXMsIG5lc3RlZEN5Y2xlcykgPT4gbWVyZ2VkQ3ljbGVzLmNvbmNhdChuZXN0ZWRDeWNsZXMpLCBbXSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZXRlY3QtY3ljbGVzLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmNvbnN0IGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXggPSAoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZSA9IG91dHB1dEF1ZGlvTm9kZXNbb3V0cHV0XTtcbiAgICBpZiAob3V0cHV0QXVkaW9Ob2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZTtcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAob3V0cHV0QXVkaW9Ob2RlcywgZGVzdGluYXRpb25Pck91dHB1dCA9IHVuZGVmaW5lZCwgb3V0cHV0ID0gdW5kZWZpbmVkLCBpbnB1dCA9IDApID0+IHtcbiAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2RlcywgZGVzdGluYXRpb25Pck91dHB1dCkuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSkge1xuICAgICAgICAgICAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaW5wdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIDAsIGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGVzLmZvckVhY2goKG91dHB1dEF1ZGlvTm9kZSkgPT4gb3V0cHV0QXVkaW9Ob2RlLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kaXNjb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGF0dGFjazogMC4wMDMsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdjbGFtcGVkLW1heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGtuZWU6IDMwLFxuICAgIHJhdGlvOiAxMixcbiAgICByZWxlYXNlOiAwLjI1LFxuICAgIHRocmVzaG9sZDogLTI0XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBEeW5hbWljc0NvbXByZXNzb3JOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBkeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBkeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fYXR0YWNrID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgIHRoaXMuX2tuZWUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlO1xuICAgICAgICAgICAgdGhpcy5fcmF0aW8gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICB0aGlzLl9yZWxlYXNlID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVsZWFzZSk7XG4gICAgICAgICAgICB0aGlzLl90aHJlc2hvbGQgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMC4wMDYpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBhdHRhY2soKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXR0YWNrO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTA4OiBTYWZhcmkgYWxsb3dzIGEgY2hhbm5lbENvdW50IG9mIHRocmVlIGFuZCBhYm92ZSB3aGljaCBpcyB3aHkgdGhlIGdldHRlciBhbmQgc2V0dGVyIG5lZWRzIHRvIGJlIG92ZXJ3cml0dGVuIGhlcmUuXG4gICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNDaGFubmVsQ291bnQgPSB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQgPSBwcmV2aW91c0NoYW5uZWxDb3VudDtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTA5OiBPbmx5IENocm9tZSBhbmQgRmlyZWZveCBkaXNhbGxvdyBhIGNoYW5uZWxDb3VudE1vZGUgb2YgJ21heCcgeWV0IHdoaWNoIGlzIHdoeSB0aGUgZ2V0dGVyIGFuZCBzZXR0ZXIgbmVlZHMgdG8gYmVcbiAgICAgICAgICogb3ZlcndyaXR0ZW4gaGVyZS5cbiAgICAgICAgICovXG4gICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNDaGFubmVsQ291bnQgPSB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSBwcmV2aW91c0NoYW5uZWxDb3VudDtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBrbmVlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2tuZWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJhdGlvKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JhdGlvO1xuICAgICAgICB9XG4gICAgICAgIGdldCByZWR1Y3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzExMTogU2FmYXJpIHJldHVybnMgYW4gQXVkaW9QYXJhbSBpbnN0ZWFkIG9mIGEgbnVtYmVyLlxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbi52YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWR1Y3Rpb24udmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWR1Y3Rpb247XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlbGVhc2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmVsZWFzZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdGhyZXNob2xkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RocmVzaG9sZDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZVxuICAgICAgICAgICAgICogY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2sudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAga25lZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByYXRpbzogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpby52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUudGhyZXNob2xkLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuYXR0YWNrLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjayk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5rbmVlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmF0aW8sIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmF0aW8pO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmVsZWFzZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnRocmVzaG9sZCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuYXR0YWNrLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjayk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkua25lZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yYXRpbywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmVsZWFzZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS50aHJlc2hvbGQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUudGhyZXNob2xkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUVuY29kaW5nRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnRW5jb2RpbmdFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZW5jb2RpbmctZXJyb3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV2YWx1YXRlU291cmNlID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoc291cmNlKSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICByZWplY3QobmV3IFN5bnRheEVycm9yKCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhlYWQgPSB3aW5kb3cuZG9jdW1lbnQuaGVhZDtcbiAgICAgICAgaWYgKGhlYWQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICByZWplY3QobmV3IFN5bnRheEVycm9yKCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2NyaXB0ID0gd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuICAgICAgICAgICAgLy8gQHRvZG8gU2FmYXJpIGRvZXNuJ3QgbGlrZSBVUkxzIHdpdGggYSB0eXBlIG9mICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04Jy5cbiAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbc291cmNlXSwgeyB0eXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdCcgfSk7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICAgICAgY29uc3Qgb3JpZ2luYWxPbkVycm9ySGFuZGxlciA9IHdpbmRvdy5vbmVycm9yO1xuICAgICAgICAgICAgY29uc3QgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5vbmVycm9yID0gb3JpZ2luYWxPbkVycm9ySGFuZGxlcjtcbiAgICAgICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgd2luZG93Lm9uZXJyb3IgPSAobWVzc2FnZSwgc3JjLCBsaW5lbm8sIGNvbG5vLCBlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIEVkZ2UgdGhpbmtzIHRoZSBzb3VyY2UgaXMgdGhlIG9uZSBvZiB0aGUgaHRtbCBkb2N1bWVudC5cbiAgICAgICAgICAgICAgICBpZiAoc3JjID09PSB1cmwgfHwgKHNyYyA9PT0gd2luZG93LmxvY2F0aW9uLmhyZWYgJiYgbGluZW5vID09PSAxICYmIGNvbG5vID09PSAxKSkge1xuICAgICAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAob3JpZ2luYWxPbkVycm9ySGFuZGxlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxPbkVycm9ySGFuZGxlcihtZXNzYWdlLCBzcmMsIGxpbmVubywgY29sbm8sIGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsKCk7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgICAgICByZWplY3QobmV3IFN5bnRheEVycm9yKCkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjcmlwdC5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsKCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjcmlwdC5zcmMgPSB1cmw7XG4gICAgICAgICAgICBzY3JpcHQudHlwZSA9ICdtb2R1bGUnO1xuICAgICAgICAgICAgaGVhZC5hcHBlbmRDaGlsZChzY3JpcHQpO1xuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZhbHVhdGUtc291cmNlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yID0gKHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEV2ZW50VGFyZ2V0IHtcbiAgICAgICAgY29uc3RydWN0b3IoX25hdGl2ZUV2ZW50VGFyZ2V0KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldCA9IF9uYXRpdmVFdmVudFRhcmdldDtcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVycyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKGxpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXBwZWRFdmVudExpc3RlbmVyID0gdGhpcy5fbGlzdGVuZXJzLmdldChsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgaWYgKHdyYXBwZWRFdmVudExpc3RlbmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCBsaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVycy5zZXQobGlzdGVuZXIsIHdyYXBwZWRFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5hZGRFdmVudExpc3RlbmVyKHR5cGUsIHdyYXBwZWRFdmVudExpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRXZlbnRUYXJnZXQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSBsaXN0ZW5lciA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHRoaXMuX2xpc3RlbmVycy5nZXQobGlzdGVuZXIpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRXZlbnRUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHdyYXBwZWRFdmVudExpc3RlbmVyLCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGN1cnJlbnRUaW1lLCBzYW1wbGVSYXRlLCBmbikgPT4ge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyh3aW5kb3csIHtcbiAgICAgICAgICAgIGN1cnJlbnRGcmFtZToge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLnJvdW5kKGN1cnJlbnRUaW1lICogc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGN1cnJlbnRUaW1lOiB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gZm4oKTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIGlmICh3aW5kb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgd2luZG93LmN1cnJlbnRGcmFtZTtcbiAgICAgICAgICAgICAgICBkZWxldGUgd2luZG93LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1leHBvc2UtY3VycmVudC1mcmFtZS1hbmQtY3VycmVudC10aW1lLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVGZXRjaFNvdXJjZSA9IChjcmVhdGVBYm9ydEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jICh1cmwpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHJldHVybiBbYXdhaXQgcmVzcG9uc2UudGV4dCgpLCByZXNwb25zZS51cmxdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgIH0gLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1lbXB0eVxuICAgICAgICB0aHJvdyBjcmVhdGVBYm9ydEVycm9yKCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1mZXRjaC1zb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGdhaW46IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBHYWluTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUdhaW5Ob2RlLCBnYWluTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9nYWluID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUdhaW5Ob2RlLmdhaW4sIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2FpbjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2Fpbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlR2Fpbk5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVHYWluTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlR2Fpbk5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlR2Fpbk5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVHYWluTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlR2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBnYWluOiBuYXRpdmVHYWluTm9kZS5nYWluLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVHYWluTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlR2Fpbk5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVHYWluTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGUgPSByZW5kZXJlZE5hdGl2ZUdhaW5Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlR2Fpbk5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2Fpbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSAoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlLCBnZXRWYWx1ZUZvcktleSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSkgPT4gZ2V0VmFsdWVGb3JLZXkoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEF1ZGlvTm9kZVJlbmRlcmVyID0gKGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICBpZiAoYXVkaW9Ob2RlQ29ubmVjdGlvbnMucmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgcmVuZGVyZXIgb2YgdGhlIGdpdmVuIEF1ZGlvTm9kZSBpbiB0aGUgYXVkaW8gZ3JhcGguJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF1ZGlvTm9kZUNvbm5lY3Rpb25zLnJlbmRlcmVyO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLW5vZGUtcmVuZGVyZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lID0gKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSkgPT4geyB2YXIgX2E7IHJldHVybiAoX2EgPSBhdWRpb05vZGVUYWlsVGltZVN0b3JlLmdldChhdWRpb05vZGUpKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiAwOyB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1ub2RlLXRhaWwtdGltZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9QYXJhbVJlbmRlcmVyID0gKGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAoYXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSk7XG4gICAgICAgIGlmIChhdWRpb1BhcmFtQ29ubmVjdGlvbnMucmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgcmVuZGVyZXIgb2YgdGhlIGdpdmVuIEF1ZGlvUGFyYW0gaW4gdGhlIGF1ZGlvIGdyYXBoLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhdWRpb1BhcmFtQ29ubmVjdGlvbnMucmVuZGVyZXI7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tcGFyYW0tcmVuZGVyZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSAoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0ludmFsaWRTdGF0ZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnZhbGlkLXN0YXRlLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCBjcmVhdGVHZXROYXRpdmVDb250ZXh0ID0gKGNvbnRleHRTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoY29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gY29udGV4dFN0b3JlLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW5hdGl2ZS1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSAoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgbGV0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTQxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjcmVhdGluZyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGggbGVzcyB0aGFuIDQ0MTAwIEh6LlxuICAgICAgICBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxLCA0NDEwMCk7XG4gICAgICAgIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5zZXQobmF0aXZlQ29udGV4dCwgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LW9yLWNyZWF0ZS1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgPSAodW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgPSB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgaWYgKHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBjb250ZXh0IGhhcyBubyBzZXQgb2YgQXVkaW9Xb3JrbGV0Tm9kZXMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcztcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZXMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdJbnZhbGlkQWNjZXNzRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludmFsaWQtYWNjZXNzLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLWFjY2Vzcy1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcElJUkZpbHRlck5vZGVHZXRGcmVxdWVuY3lSZXNwb25zZU1ldGhvZCA9IChuYXRpdmVJSVJGaWx0ZXJOb2RlKSA9PiB7XG4gICAgbmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZSA9ICgoZ2V0RnJlcXVlbmN5UmVzcG9uc2UpID0+IHtcbiAgICAgICAgcmV0dXJuIChmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGlmIChmcmVxdWVuY3lIei5sZW5ndGggIT09IG1hZ1Jlc3BvbnNlLmxlbmd0aCB8fCBtYWdSZXNwb25zZS5sZW5ndGggIT09IHBoYXNlUmVzcG9uc2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZ2V0RnJlcXVlbmN5UmVzcG9uc2UuY2FsbChuYXRpdmVJSVJGaWx0ZXJOb2RlLCBmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUlJUkZpbHRlck5vZGUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtaWlyLWZpbHRlci1ub2RlLWdldC1mcmVxdWVuY3ktcmVzcG9uc2UtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IHdyYXBJSVJGaWx0ZXJOb2RlR2V0RnJlcXVlbmN5UmVzcG9uc2VNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtaWlyLWZpbHRlci1ub2RlLWdldC1mcmVxdWVuY3ktcmVzcG9uc2UtbWV0aG9kJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZSwgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIElJUkZpbHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZShuYXRpdmVDb250ZXh0LCBpc09mZmxpbmUgPyBudWxsIDogY29udGV4dC5iYXNlTGF0ZW5jeSwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpaXJGaWx0ZXJOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlcihtZXJnZWRPcHRpb25zLmZlZWRiYWNrLCBtZXJnZWRPcHRpb25zLmZlZWRmb3J3YXJkKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVJSVJGaWx0ZXJOb2RlLCBpaXJGaWx0ZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICMyMyAmICMyNDogRmlyZWZveERldmVsb3BlciBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IuXG4gICAgICAgICAgICAvLyBAdG9kbyBXcml0ZSBhIHRlc3Qgd2hpY2ggYWxsb3dzIG90aGVyIGJyb3dzZXJzIHRvIHJlbWFpbiB1bnBhdGNoZWQuXG4gICAgICAgICAgICB3cmFwSUlSRmlsdGVyTm9kZUdldEZyZXF1ZW5jeVJlc3BvbnNlTWV0aG9kKG5hdGl2ZUlJUkZpbHRlck5vZGUpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlSUlSRmlsdGVyTm9kZSA9IG5hdGl2ZUlJUkZpbHRlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUlJUkZpbHRlck5vZGUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWlyLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsIi8vIFRoaXMgaW1wbGVtZW50YXRpb24gYXMgc2hhbWVsZXNzbHkgaW5zcGlyZWQgYnkgc291cmNlIGNvZGUgb2Zcbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbi8vIHtAbGluayBodHRwczovL2Nocm9taXVtLmdvb2dsZXNvdXJjZS5jb20vY2hyb21pdW0vc3JjLmdpdC8rL21hc3Rlci90aGlyZF9wYXJ0eS9XZWJLaXQvU291cmNlL3BsYXRmb3JtL2F1ZGlvL0lJUkZpbHRlci5jcHB8Q2hyb21pdW0ncyBJSVJGaWx0ZXJ9LlxuZXhwb3J0IGNvbnN0IGZpbHRlckJ1ZmZlciA9IChmZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyLCB5QnVmZmVyLCBidWZmZXJJbmRleCwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGg7XG4gICAgbGV0IGkgPSBidWZmZXJJbmRleDtcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGlucHV0TGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgbGV0IHkgPSBmZWVkZm9yd2FyZFswXSAqIGlucHV0W2pdO1xuICAgICAgICBmb3IgKGxldCBrID0gMTsgayA8IG1pbkxlbmd0aDsgayArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCB4ID0gKGkgLSBrKSAmIChidWZmZXJMZW5ndGggLSAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgICAgICB5ICs9IGZlZWRmb3J3YXJkW2tdICogeEJ1ZmZlclt4XTtcbiAgICAgICAgICAgIHkgLT0gZmVlZGJhY2tba10gKiB5QnVmZmVyW3hdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGsgPSBtaW5MZW5ndGg7IGsgPCBmZWVkZm9yd2FyZExlbmd0aDsgayArPSAxKSB7XG4gICAgICAgICAgICB5ICs9IGZlZWRmb3J3YXJkW2tdICogeEJ1ZmZlclsoaSAtIGspICYgKGJ1ZmZlckxlbmd0aCAtIDEpXTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgayA9IG1pbkxlbmd0aDsgayA8IGZlZWRiYWNrTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIHkgLT0gZmVlZGJhY2tba10gKiB5QnVmZmVyWyhpIC0gaykgJiAoYnVmZmVyTGVuZ3RoIC0gMSldOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgfVxuICAgICAgICB4QnVmZmVyW2ldID0gaW5wdXRbal07XG4gICAgICAgIHlCdWZmZXJbaV0gPSB5O1xuICAgICAgICBpID0gKGkgKyAxKSAmIChidWZmZXJMZW5ndGggLSAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgIG91dHB1dFtqXSA9IHk7XG4gICAgfVxuICAgIHJldHVybiBpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZpbHRlci1idWZmZXIuanMubWFwIiwiaW1wb3J0IHsgZmlsdGVyQnVmZmVyIH0gZnJvbSAnLi4vaGVscGVycy9maWx0ZXItYnVmZmVyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuY29uc3QgZmlsdGVyRnVsbEJ1ZmZlciA9IChyZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgZmVlZGJhY2ssIGZlZWRmb3J3YXJkKSA9PiB7XG4gICAgY29uc3QgY29udmVydGVkRmVlZGJhY2sgPSBmZWVkYmFjayBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRiYWNrIDogbmV3IEZsb2F0NjRBcnJheShmZWVkYmFjayk7XG4gICAgY29uc3QgY29udmVydGVkRmVlZGZvcndhcmQgPSBmZWVkZm9yd2FyZCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRmb3J3YXJkIDogbmV3IEZsb2F0NjRBcnJheShmZWVkZm9yd2FyZCk7XG4gICAgY29uc3QgZmVlZGJhY2tMZW5ndGggPSBjb252ZXJ0ZWRGZWVkYmFjay5sZW5ndGg7XG4gICAgY29uc3QgZmVlZGZvcndhcmRMZW5ndGggPSBjb252ZXJ0ZWRGZWVkZm9yd2FyZC5sZW5ndGg7XG4gICAgY29uc3QgbWluTGVuZ3RoID0gTWF0aC5taW4oZmVlZGJhY2tMZW5ndGgsIGZlZWRmb3J3YXJkTGVuZ3RoKTtcbiAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gIT09IDEpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmZWVkYmFja0xlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb252ZXJ0ZWRGZWVkZm9yd2FyZFtpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZlZWRmb3J3YXJkTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRiYWNrW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGJ1ZmZlckxlbmd0aCA9IDMyO1xuICAgIGNvbnN0IHhCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgY29uc3QgeUJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICBjb25zdCBmaWx0ZXJlZEJ1ZmZlciA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKHJlbmRlcmVkQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMsIHJlbmRlcmVkQnVmZmVyLmxlbmd0aCwgcmVuZGVyZWRCdWZmZXIuc2FtcGxlUmF0ZSk7XG4gICAgY29uc3QgbnVtYmVyT2ZDaGFubmVscyA9IHJlbmRlcmVkQnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNoYW5uZWxzOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSByZW5kZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0ID0gZmlsdGVyZWRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSk7XG4gICAgICAgIHhCdWZmZXIuZmlsbCgwKTtcbiAgICAgICAgeUJ1ZmZlci5maWxsKDApO1xuICAgICAgICBmaWx0ZXJCdWZmZXIoY29udmVydGVkRmVlZGJhY2ssIGZlZWRiYWNrTGVuZ3RoLCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCwgZmVlZGZvcndhcmRMZW5ndGgsIG1pbkxlbmd0aCwgeEJ1ZmZlciwgeUJ1ZmZlciwgMCwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbHRlcmVkQnVmZmVyO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChmZWVkYmFjaywgZmVlZGZvcndhcmQpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IGZpbHRlcmVkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICBsZXQgbmF0aXZlSUlSRmlsdGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlSUlSRmlsdGVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVJSVJGaWx0ZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjOTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgSUlSRmlsdGVyTm9kZXMuXG4gICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFuYXRpdmVJSVJGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgZGVmaW5lcyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVJSVJGaWx0ZXIoKSBhcyBhcnJheXMgb2YgbnVtYmVycy5cbiAgICAgICAgICAgICAgICBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoZmVlZGZvcndhcmQsIGZlZWRiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsID8gbmF0aXZlSUlSRmlsdGVyTm9kZSA6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkQnVmZmVyUHJvbWlzZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0NzogVGhlIEF1ZGlvRGVzdGluYXRpb25Ob2RlIGluIFNhZmFyaSBnZXRzIG5vdCBpbml0aWFsaXplZCBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgICAgICAgIHByb3h5LmNvbnRleHQuZGVzdGluYXRpb24uY2hhbm5lbENvdW50LCBcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgICAgICAgICAgcHJveHkuY29udGV4dC5sZW5ndGgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkQnVmZmVyUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkQnVmZmVyID0gYXdhaXQgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmlsdGVyRnVsbEJ1ZmZlcihyZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgZmVlZGJhY2ssIGZlZWRmb3J3YXJkKTtcbiAgICAgICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyZWRCdWZmZXIgPSBhd2FpdCBmaWx0ZXJlZEJ1ZmZlclByb21pc2U7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IGZpbHRlcmVkQnVmZmVyO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUlJUkZpbHRlck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUlJUkZpbHRlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aWlyLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkgPSAoY3ljbGVDb3VudGVycywgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGlzQWN0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChpc09mZmxpbmUpID0+IHtcbiAgICAgICAgcmV0dXJuIChhdWRpb05vZGUsIGNvdW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjeWNsZUNvdW50ZXIgPSBjeWNsZUNvdW50ZXJzLmdldChhdWRpb05vZGUpO1xuICAgICAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgaXNBY3RpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBvdXRwdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBvdXRwdXRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dFsxXSwgb3V0cHV0WzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0ob3V0cHV0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvUGFyYW0sIG91dHB1dFsxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3ljbGVDb3VudGVycy5zZXQoYXVkaW9Ob2RlLCBjb3VudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjeWNsZUNvdW50ZXJzLnNldChhdWRpb05vZGUsIGN5Y2xlQ291bnRlciArIGNvdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluY3JlbWVudC1jeWNsZS1jb3VudGVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55QXVkaW9Db250ZXh0ID0gKGNvbnRleHRTdG9yZSwgaXNOYXRpdmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBjb250ZXh0U3RvcmUuZ2V0KGFueXRoaW5nKTtcbiAgICAgICAgcmV0dXJuIGlzTmF0aXZlQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpIHx8IGlzTmF0aXZlQXVkaW9Db250ZXh0KGFueXRoaW5nKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueUF1ZGlvTm9kZSA9IChhdWRpb05vZGVTdG9yZSwgaXNOYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiBhdWRpb05vZGVTdG9yZS5oYXMoYW55dGhpbmcpIHx8IGlzTmF0aXZlQXVkaW9Ob2RlKGFueXRoaW5nKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlBdWRpb1BhcmFtID0gKGF1ZGlvUGFyYW1TdG9yZSwgaXNOYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4gYXVkaW9QYXJhbVN0b3JlLmhhcyhhbnl0aGluZykgfHwgaXNOYXRpdmVBdWRpb1BhcmFtKGFueXRoaW5nKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjb250ZXh0U3RvcmUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGNvbnRleHRTdG9yZS5nZXQoYW55dGhpbmcpO1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpIHx8IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChhbnl0aGluZyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dCA9IChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIGFueXRoaW5nIGluc3RhbmNlb2YgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3I7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVBdWRpb05vZGUgPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gd2luZG93ICE9PSBudWxsICYmIHR5cGVvZiB3aW5kb3cuQXVkaW9Ob2RlID09PSAnZnVuY3Rpb24nICYmIGFueXRoaW5nIGluc3RhbmNlb2Ygd2luZG93LkF1ZGlvTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0gPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gd2luZG93ICE9PSBudWxsICYmIHR5cGVvZiB3aW5kb3cuQXVkaW9QYXJhbSA9PT0gJ2Z1bmN0aW9uJyAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIHdpbmRvdy5BdWRpb1BhcmFtO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUNvbnRleHQgPSAoaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIGlzTmF0aXZlQXVkaW9Db250ZXh0KGFueXRoaW5nKSB8fCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoYW55dGhpbmcpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3I7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc1NlY3VyZUNvbnRleHQgPSAod2luZG93KSA9PiB3aW5kb3cgIT09IG51bGwgJiYgd2luZG93LmlzU2VjdXJlQ29udGV4dDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXNlY3VyZS1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTcxOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtZWRpYUVsZW1lbnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLm1lZGlhRWxlbWVudDtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxNzM6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBudWxsKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdHJlYW0oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZS5zdHJlYW07XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAvLyBCdWcgIzE3MjogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWVkaWFTdHJlYW0oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUubWVkaWFTdHJlYW07XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLCBudWxsKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IGlzVmFsaWRMYXRlbmN5SGludCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtdmFsaWQtbGF0ZW5jeS1oaW50JztcbmV4cG9ydCBjb25zdCBjcmVhdGVNaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxBdWRpb0NvbnRleHQgZXh0ZW5kcyBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTIgU2FmYXJpIGRvZXMgdGhyb3cgYSBTeW50YXhFcnJvciBpZiB0aGUgc2FtcGxlUmF0ZSBpcyBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIgJiYgZXJyLm1lc3NhZ2UgPT09ICdzYW1wbGVSYXRlIGlzIG5vdCBpbiByYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxMzEgU2FmYXJpIHJldHVybnMgbnVsbCB3aGVuIHRoZXJlIGFyZSBmb3VyIG90aGVyIEF1ZGlvQ29udGV4dHMgcnVubmluZyBhbHJlYWR5LlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVVua25vd25FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM1MSBPbmx5IENocm9tZSBhbmQgRWRnZSB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gbGF0ZW5jeUhpbnQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgIGlmICghaXNWYWxpZExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHByb3ZpZGVkIHZhbHVlICcke29wdGlvbnMubGF0ZW5jeUhpbnR9JyBpcyBub3QgYSB2YWxpZCBlbnVtIHZhbHVlIG9mIHR5cGUgQXVkaW9Db250ZXh0TGF0ZW5jeUNhdGVnb3J5LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNTAgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgc2V0dGluZyB0aGUgc2FtcGxlUmF0ZS5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNhbXBsZVJhdGUgIT09IHVuZGVmaW5lZCAmJiBuYXRpdmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSAhPT0gb3B0aW9ucy5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvQ29udGV4dCwgMik7XG4gICAgICAgICAgICBjb25zdCB7IGxhdGVuY3lIaW50IH0gPSBvcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgeyBzYW1wbGVSYXRlIH0gPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBAdG9kbyBUaGUgdmFsdWVzIGZvciAnYmFsYW5jZWQnLCAnaW50ZXJhY3RpdmUnIGFuZCAncGxheWJhY2snIGFyZSBqdXN0IGNvcGllZCBmcm9tIENocm9tZSdzIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgdGhpcy5fYmFzZUxhdGVuY3kgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3kgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgICAgID8gbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5XG4gICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gNTEyIC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAyNTYgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDEwMjQgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogLypcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBAdG9kbyBUaGUgbWluICgyNTYpIGFuZCBtYXggKDE2Mzg0KSB2YWx1ZXMgYXJlIHRha2VuIGZyb20gdGhlIGFsbG93ZWQgYnVmZmVyU2l6ZSB2YWx1ZXMgb2YgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFNjcmlwdFByb2Nlc3Nvck5vZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWF0aC5tYXgoMiwgTWF0aC5taW4oMTI4LCBNYXRoLnJvdW5kKChsYXRlbmN5SGludCAqIHNhbXBsZVJhdGUpIC8gMTI4KSkpICogMTI4KSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQgPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBCdWcgIzE4ODogU2FmYXJpIHdpbGwgc2V0IHRoZSBjb250ZXh0J3Mgc3RhdGUgdG8gJ2ludGVycnVwdGVkJyBpbiBjYXNlIHRoZSB1c2VyIHN3aXRjaGVzIHRhYnMuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWUgPSAxZS0zNztcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5jb25uZWN0KHRoaXMuX25hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICMzNDogQ2hyb21lIGFuZCBFZGdlIHByZXRlbmQgdG8gYmUgcnVubmluZyByaWdodCBhd2F5LCBidXQgZmlyZSBhbiBvbnN0YXRlY2hhbmdlIGV2ZW50IHdoZW4gdGhlIHN0YXRlIGFjdHVhbGx5IGNoYW5nZXNcbiAgICAgICAgICAgICAqIHRvICdydW5uaW5nJy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAnc3VzcGVuZGVkJztcbiAgICAgICAgICAgICAgICBjb25zdCByZXZva2VTdGF0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgYmFzZUxhdGVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUxhdGVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlICE9PSBudWxsID8gdGhpcy5fc3RhdGUgOiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzM1OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBBdWRpb0NvbnRleHQgd2FzIGNsb3NlZCBiZWZvcmUuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzM0OiBJZiB0aGUgc3RhdGUgd2FzIHNldCB0byBzdXNwZW5kZWQgYmVmb3JlIGl0IHNob3VsZCBiZSByZXZva2VkIG5vdy5cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUdhaW5Ob2RlICE9PSBudWxsICYmIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdW1lKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVQcm9taXNlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXN1bWUoKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVzdW1lKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTU6IENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IgaW5zdGVhZCBvZiBhbiBJbnZhbGlkU3RhdGVFcnJvci5cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQgfHwgZXJyLmNvZGUgPT09IDE1KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHN1c3BlbmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN1c3BlbmQoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW5pbWFsLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgQ09OVEVYVF9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9MaXN0ZW5lciwgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dCBleHRlbmRzIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgc3VwZXIoX25hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udGV4dCA9IF9uYXRpdmVDb250ZXh0O1xuICAgICAgICAgICAgQ09OVEVYVF9TVE9SRS5zZXQodGhpcywgX25hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChfbmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLnNldChfbmF0aXZlQ29udGV4dCwgbmV3IFNldCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2Rlc3RpbmF0aW9uID0gbmV3IGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IodGhpcywgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lciA9IGNyZWF0ZUF1ZGlvTGlzdGVuZXIodGhpcywgX25hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgdGhpcy5fb25zdGF0ZWNoYW5nZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRlc3RpbmF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3RpbmF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9saXN0ZW5lcjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25zdGF0ZWNoYW5nZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbnN0YXRlY2hhbmdlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbnN0YXRlY2hhbmdlKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udGV4dC5vbnN0YXRlY2hhbmdlID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25TdGF0ZUNoYW5nZSA9IHRoaXMuX25hdGl2ZUNvbnRleHQub25zdGF0ZWNoYW5nZTtcbiAgICAgICAgICAgIHRoaXMuX29uc3RhdGVjaGFuZ2UgPSBuYXRpdmVPblN0YXRlQ2hhbmdlICE9PSBudWxsICYmIG5hdGl2ZU9uU3RhdGVDaGFuZ2UgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25TdGF0ZUNoYW5nZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0UHJvbWlzZVN1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIC8vIFRoaXMgMTIgbnVtYmVycyByZXByZXNlbnQgdGhlIDQ4IGJ5dGVzIG9mIGFuIGVtcHR5IFdBVkUgZmlsZSB3aXRoIGEgc2luZ2xlIHNhbXBsZS5cbiAgICBjb25zdCB1aW50MzJBcnJheSA9IG5ldyBVaW50MzJBcnJheShbMTE3OTAxMTQxMCwgNDAsIDExNjMyODA3MjcsIDU0NDUwMTA5NCwgMTYsIDEzMTA3MywgNDQxMDAsIDE3NjQwMCwgMTA0ODU4MCwgMTYzNTAxNzA2MCwgNCwgMF0pO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIEJ1ZyAjMTogU2FmYXJpIHJlcXVpcmVzIGEgc3VjY2Vzc0NhbGxiYWNrLlxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEodWludDMyQXJyYXkuYnVmZmVyLCAoKSA9PiB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgdGhlIHN1Y2Nlc3MgY2FsbGJhY2suXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocHJvbWlzZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgcmVqZWN0ZWQgZXJyb3JzLlxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtcHJvbWlzZS1zdXBwb3J0LmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIG51bWJlck9mQ2hhbm5lbHM6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzdGFydFJlbmRlcmluZykgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyAjMjEgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgYW5kIHRoZXJlZm9yZSB3b3VsZCBmaXJlIHRoZSBzdGF0ZWNoYW5nZSBldmVudCBiZWZvcmUgdGhlIHByb21pc2UgY2FuIGJlIHJlc29sdmVkLlxuICAgICAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsICgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50ID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlbGF5U3RhdGVDaGFuZ2VFdmVudDtcbiAgICAgICAgICAgICAgICB9KSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbGVuZ3RoID0gbGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlID09PSBudWxsID8gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGF0ZSA6IHRoaXMuX3N0YXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UmVuZGVyaW5nKCkge1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOSAmICM1OTogSXQgaXMgdGhlb3JldGljYWxseSBwb3NzaWJsZSB0aGF0IHN0YXJ0UmVuZGVyaW5nKCkgd2lsbCBmaXJzdCByZW5kZXIgYSBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC4gVGhlcmVmb3JlXG4gICAgICAgICAgICAgKiB0aGUgc3RhdGUgb2YgdGhlIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgbWlnaHQgbm8gdHJhbnNpdGlvbiB0byBydW5uaW5nIGltbWVkaWF0ZWx5LlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3J1bm5pbmcnO1xuICAgICAgICAgICAgcmV0dXJuIHN0YXJ0UmVuZGVyaW5nKHRoaXMuZGVzdGluYXRpb24sIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIF93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLl93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNb25pdG9yQ29ubmVjdGlvbnMgPSAoaW5zZXJ0RWxlbWVudEluU2V0LCBpc05hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Ob2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldCgpO1xuICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdCA9ICgoY29ubmVjdCkgPT4ge1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZCBuby1pbmZlcnJhYmxlLXR5cGVzXG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB3YXNEaXNjb25uZWN0ZWQgPSBjb25uZWN0aW9ucy5zaXplID09PSAwO1xuICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMyBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgICAgICAgICBjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGluc2VydEVsZW1lbnRJblNldChjb25uZWN0aW9ucywgW2Rlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0XSwgKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmIGNvbm5lY3Rpb25bMV0gPT09IG91dHB1dCAmJiBjb25uZWN0aW9uWzJdID09PSBpbnB1dCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh3YXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoZW5Db25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVzdGluYXRpb247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIGluc2VydEVsZW1lbnRJblNldChjb25uZWN0aW9ucywgW2Rlc3RpbmF0aW9uLCBvdXRwdXRdLCAoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICBpZiAod2FzRGlzY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoZW5Db25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QpO1xuICAgICAgICBuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCA9ICgoZGlzY29ubmVjdCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgd2FzQ29ubmVjdGVkID0gY29ubmVjdGlvbnMuc2l6ZSA+IDA7XG4gICAgICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmFwcGx5KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAxIGFyZ3VtZW50IHlldC5cbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25bMV0gPT09IGRlc3RpbmF0aW9uT3JPdXRwdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMyBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAyIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uT3JPdXRwdXQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAob3V0cHV0ID09PSB1bmRlZmluZWQgfHwgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnB1dCA9PT0gdW5kZWZpbmVkIHx8IGNvbm5lY3Rpb25bMl0gPT09IGlucHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpc0Rpc2Nvbm5lY3RlZCA9IGNvbm5lY3Rpb25zLnNpemUgPT09IDA7XG4gICAgICAgICAgICAgICAgaWYgKHdhc0Nvbm5lY3RlZCAmJiBpc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB3aGVuRGlzY29ubmVjdGVkKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bW9uaXRvci1jb25uZWN0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uID0gKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgb3B0aW9uKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW29wdGlvbl07XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG5hdGl2ZUF1ZGlvTm9kZVtvcHRpb25dKSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZVtvcHRpb25dID0gdmFsdWU7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24uanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zID0gKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucykgPT4ge1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsQ291bnQnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCAnY2hhbm5lbENvdW50TW9kZScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsSW50ZXJwcmV0YXRpb24nKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2RTdXBwb3J0ID0gKG5hdGl2ZUFuYWx5c2VyTm9kZSkgPT4ge1xuICAgIHJldHVybiB0eXBlb2YgbmF0aXZlQW5hbHlzZXJOb2RlLmdldEZsb2F0VGltZURvbWFpbkRhdGEgPT09ICdmdW5jdGlvbic7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZCA9IChuYXRpdmVBbmFseXNlck5vZGUpID0+IHtcbiAgICBuYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSA9IChhcnJheSkgPT4ge1xuICAgICAgICBjb25zdCBieXRlVGltZURvbWFpbkRhdGEgPSBuZXcgVWludDhBcnJheShhcnJheS5sZW5ndGgpO1xuICAgICAgICBuYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGJ5dGVUaW1lRG9tYWluRGF0YSk7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGgubWF4KGJ5dGVUaW1lRG9tYWluRGF0YS5sZW5ndGgsIG5hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgYXJyYXlbaV0gPSAoYnl0ZVRpbWVEb21haW5EYXRhW2ldIC0gMTI4KSAqIDAuMDA3ODEyNTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXJyYXk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyB3cmFwQW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeSA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUFuYWx5c2VyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICAgICAgLy8gQnVnICMzNzogRmlyZWZveCBkb2VzIG5vdCBjcmVhdGUgYW4gQW5hbHlzZXJOb2RlIHdpdGggdGhlIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICAvLyBCdWcgIzExODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIG1heERlY2liZWxzIGlzIG5vdCBtb3JlIHRoYW4gbWluRGVjaWJlbHMuXG4gICAgICAgIGlmICghKG9wdGlvbnMubWF4RGVjaWJlbHMgPiBvcHRpb25zLm1pbkRlY2liZWxzKSkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnZmZ0U2l6ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnbWF4RGVjaWJlbHMnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ21pbkRlY2liZWxzJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdzbW9vdGhpbmdUaW1lQ29uc3RhbnQnKTtcbiAgICAgICAgLy8gQnVnICMzNjogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSgpIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2RTdXBwb3J0LCAoKSA9PiB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQobmF0aXZlQW5hbHlzZXJOb2RlKSkpIHtcbiAgICAgICAgICAgIHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kKG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hdGl2ZUFuYWx5c2VyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hbmFseXNlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSAod2luZG93KSA9PiB7XG4gICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnQXVkaW9CdWZmZXInKSkge1xuICAgICAgICByZXR1cm4gd2luZG93LkF1ZGlvQnVmZmVyO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCBhdWRpb1BhcmFtKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBvcHRpb25zW2F1ZGlvUGFyYW1dO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBuYXRpdmVBdWRpb05vZGVbYXVkaW9QYXJhbV0udmFsdWUpIHtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlW2F1ZGlvUGFyYW1dLnZhbHVlID0gdmFsdWU7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZS5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzID0gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCA9ICgoc3RhcnQpID0+IHtcbiAgICAgICAgbGV0IGlzU2NoZWR1bGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNTY2hlZHVsZWQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgaXNTY2hlZHVsZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgPSAobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0YXJ0ID0gKChzdGFydCkgPT4ge1xuICAgICAgICByZXR1cm4gKHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKCh0eXBlb2YgZHVyYXRpb24gPT09ICdudW1iZXInICYmIGR1cmF0aW9uIDwgMCkgfHwgb2Zmc2V0IDwgMCB8fCB3aGVuIDwgMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHBhcmFtZXRlcnMgY2FuJ3QgYmUgbmVnYXRpdmUuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMyBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdGFydCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzID0gKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wID0gKChzdG9wKSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDApID0+IHtcbiAgICAgICAgICAgIGlmICh3aGVuIDwgMCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHBhcmFtZXRlciBjYW4ndCBiZSBuZWdhdGl2ZS5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdG9wLmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxscyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBsaW5nLCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlciwgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucywgJ3BsYXliYWNrUmF0ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnYnVmZmVyJyk7XG4gICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnbG9vcCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnbG9vcEVuZCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAnbG9vcFN0YXJ0Jyk7XG4gICAgICAgIC8vIEJ1ZyAjNjk6IFNhZmFyaSBkb2VzIGFsbG93IGNhbGxzIHRvIHN0YXJ0KCkgb2YgYW4gYWxyZWFkeSBzY2hlZHVsZWQgQXVkaW9CdWZmZXJTb3VyY2VOb2RlLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNTQgJiAjMTU1OiBTYWZhcmkgZG9lcyBub3QgaGFuZGxlIG9mZnNldHMgd2hpY2ggYXJlIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiB0aGUgZHVyYXRpb24gb2YgdGhlIGJ1ZmZlci5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGxpbmcobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE2MjogU2FmYXJpIGRvZXMgdGhyb3cgYW4gZXJyb3Igd2hlbiBzdG9wKCkgaXMgY2FsbGVkIG9uIGFuIEF1ZGlvQnVmZmVyU291cmNlTm9kZSB3aGljaCBoYXMgbm8gYnVmZmVyIGFzc2lnbmVkIHRvIGl0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogU2FmYXJpIGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE5OiBTYWZhcmkgZG9lcyBub3QgaWdub3JlIGNhbGxzIHRvIHN0b3AoKSBvZiBhbiBhbHJlYWR5IHN0b3BwZWQgQXVkaW9CdWZmZXJTb3VyY2VOb2RlLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIEF1ZGlvQnVmZmVyU291cmNlTm9kZSBpcyB1bmNvbm5lY3RlZC5cbiAgICAgICAgYWRkU2lsZW50Q29ubmVjdGlvbihuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb0NvbnRleHQnKSkge1xuICAgICAgICByZXR1cm4gd2luZG93LkF1ZGlvQ29udGV4dDtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnd2Via2l0QXVkaW9Db250ZXh0JykgPyB3aW5kb3cud2Via2l0QXVkaW9Db250ZXh0IDogbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgLy8gQnVnICMxMzI6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudC5cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCAhPT0gY2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE2OTogU2FmYXJpIHRocm93cyBhbiBlcnJvciBvbiBlYWNoIGF0dGVtcHQgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnQuXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM4MzogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50TW9kZS5cbiAgICAgICAgaWYgKGlzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCAmJiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlICE9PSAnZXhwbGljaXQnKSB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlID0gJ2V4cGxpY2l0JztcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGRvZXMgbm90IGluaXRpYWxpemUgdGhlIG1heENoYW5uZWxDb3VudCBwcm9wZXJ0eSBjb3JyZWN0bHkuXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQgPT09IDApIHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSwgJ21heENoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogY2hhbm5lbENvdW50XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE2ODogTm8gYnJvd3NlciBkb2VzIHlldCBoYXZlIGFuIEF1ZGlvRGVzdGluYXRpb25Ob2RlIHdpdGggYW4gb3V0cHV0LlxuICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxDb3VudCcsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGdhaW5Ob2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChnYWluTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE2OTogU2FmYXJpIHRocm93cyBhbiBlcnJvciBvbiBlYWNoIGF0dGVtcHQgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoZ2Fpbk5vZGUsICdjaGFubmVsQ291bnRNb2RlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoZ2Fpbk5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKGdhaW5Ob2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoZ2Fpbk5vZGUsICdjaGFubmVsSW50ZXJwcmV0YXRpb24nLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChnYWluTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwoZ2Fpbk5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdhaW5Ob2RlLCAnbWF4Q2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEB0b2RvIFRoaXMgc2hvdWxkIGJlIGRpc2Nvbm5lY3RlZCB3aGVuIHRoZSBjb250ZXh0IGlzIGNsb3NlZC5cbiAgICAgICAgZ2Fpbk5vZGUuY29ubmVjdChuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgIHJldHVybiBnYWluTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSAod2luZG93KSA9PiB7XG4gICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnQXVkaW9Xb3JrbGV0Tm9kZScpID8gd2luZG93LkF1ZGlvV29ya2xldE5vZGUgOiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RDbG9uYWJpbGl0eU9mQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IHBvcnQxIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtY2xvbmFiaWxpdHktb2YtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgdGVzdENsb25hYmlsaXR5T2ZBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1jbG9uYWJpbGl0eS1vZi1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hbWUsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlQ29udGV4dCwgbmFtZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgICAgIGxldCBvbnByb2Nlc3NvcmVycm9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCB7XG4gICAgICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICAgICAqIEJ1ZyAjNjE6IE92ZXJ3cml0aW5nIHRoZSBwcm9wZXJ0eSBhY2Nlc3NvcnMgZm9yIGNoYW5uZWxDb3VudCBhbmQgY2hhbm5lbENvdW50TW9kZSBpcyBuZWNlc3NhcnkgYXMgbG9uZyBhcyBzb21lXG4gICAgICAgICAgICAgICAgICAgICAqIGJyb3dzZXJzIGhhdmUgbm8gbmF0aXZlIGltcGxlbWVudGF0aW9uIHRvIGFjaGlldmUgYSBjb25zaXN0ZW50IGJlaGF2aW9yLlxuICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNTY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgeWV0IGZpcmUgYW4gRXJyb3JFdmVudC5cbiAgICAgICAgICAgICAgICAgICAgb25wcm9jZXNzb3JlcnJvcjoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBvbnByb2Nlc3NvcmVycm9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwcm9jZXNzb3JlcnJvcicsIG9ucHJvY2Vzc29yZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbnByb2Nlc3NvcmVycm9yID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5hZGRFdmVudExpc3RlbmVyID0gKChhZGRFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09ICdwcm9jZXNzb3JlcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnBhdGNoZWRFdmVudExpc3RlbmVyID0gdHlwZW9mIGFyZ3NbMV0gPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIGFyZ3NbMV0gPT09ICdvYmplY3QnICYmIGFyZ3NbMV0gIT09IG51bGwgJiYgdHlwZW9mIGFyZ3NbMV0uaGFuZGxlRXZlbnQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXJnc1sxXS5oYW5kbGVFdmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1bnBhdGNoZWRFdmVudExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2Vycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhldmVudCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogeyB2YWx1ZTogJ3Byb2Nlc3NvcmVycm9yJyB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhdGNoZWRFdmVudExpc3RlbmVyKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIobmV3IEVycm9yRXZlbnQoYXJnc1swXSwgeyAuLi5ldmVudCB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5zZXQodW5wYXRjaGVkRXZlbnRMaXN0ZW5lciwgYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAnZXJyb3InLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhZGRFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgLi4uYXJncyk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5hZGRFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSAoKHJlbW92ZUV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ3Byb2Nlc3NvcmVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzg6IENocm9tZSBhbmQgRWRnZSBkbyBmaXJlIGFuIGV2ZW50IG9mIHR5cGUgZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgJ2Vycm9yJywgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzg2OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGludm9rZSB0aGUgcHJvY2VzcygpIGZ1bmN0aW9uIGlmIHRoZSBjb3JyZXNwb25kaW5nIEF1ZGlvV29ya2xldE5vZGUgaXMgdW5jb25uZWN0ZWQgYnV0XG4gICAgICAgICAgICAgICAgICogaGFzIGFuIG91dHB1dC5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZk91dHB1dHMgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4gbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gbmF0aXZlR2Fpbk5vZGUuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gRGlzY29ubmVjdCB0aGUgY29ubmVjdGlvbiB3aGVuIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gb2YgdGhlIEF1ZGlvV29ya2xldE5vZGUgcmV0dXJucyBmYWxzZS5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MDogQ2hyb21lICYgRWRnZSB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciBpbnN0ZWFkIG9mIGEgTm90U3VwcG9ydGVkRXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM2MTogT25seSBDaHJvbWUgJiBFZGdlIGhhdmUgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIEF1ZGlvV29ya2xldE5vZGUgeWV0LlxuICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICB0ZXN0Q2xvbmFiaWxpdHlPZkF1ZGlvV29ya2xldE5vZGVPcHRpb25zKG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNvbXB1dGVCdWZmZXJTaXplID0gKGJhc2VMYXRlbmN5LCBzYW1wbGVSYXRlKSA9PiB7XG4gICAgaWYgKGJhc2VMYXRlbmN5ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiA1MTI7XG4gICAgfVxuICAgIHJldHVybiBNYXRoLm1heCg1MTIsIE1hdGgubWluKDE2Mzg0LCBNYXRoLnBvdygyLCBNYXRoLnJvdW5kKE1hdGgubG9nMihiYXNlTGF0ZW5jeSAqIHNhbXBsZVJhdGUpKSkpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb21wdXRlLWJ1ZmZlci1zaXplLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjbG9uZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBwb3J0MSwgcG9ydDIgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBwb3J0MS5vbm1lc3NhZ2UgPSAoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgICAgcG9ydDEub25tZXNzYWdlZXJyb3IgPSAoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVqZWN0KGRhdGEpO1xuICAgICAgICB9O1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQyLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jbG9uZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBjbG9uZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi9jbG9uZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSA9IGFzeW5jIChwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBjbG9uZWRBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IGF3YWl0IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIHJldHVybiBuZXcgcHJvY2Vzc29yQ29uc3RydWN0b3IoY2xvbmVkQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wcm9taXNlLmpzLm1hcCIsImltcG9ydCB7IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgfSBmcm9tICcuL2NyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wcm9taXNlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgbGV0IG5vZGVUb1Byb2Nlc3Nvck1hcCA9IE5PREVfVE9fUFJPQ0VTU09SX01BUFMuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgIGlmIChub2RlVG9Qcm9jZXNzb3JNYXAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBub2RlVG9Qcm9jZXNzb3JNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBOT0RFX1RPX1BST0NFU1NPUl9NQVBTLnNldChuYXRpdmVDb250ZXh0LCBub2RlVG9Qcm9jZXNzb3JNYXApO1xuICAgIH1cbiAgICBjb25zdCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZShwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIG5vZGVUb1Byb2Nlc3Nvck1hcC5zZXQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSk7XG4gICAgcmV0dXJuIGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBjb21wdXRlQnVmZmVyU2l6ZSB9IGZyb20gJy4uL2hlbHBlcnMvY29tcHV0ZS1idWZmZXItc2l6ZSc7XG5pbXBvcnQgeyBjb3B5RnJvbUNoYW5uZWwgfSBmcm9tICcuLi9oZWxwZXJzL2NvcHktZnJvbS1jaGFubmVsJztcbmltcG9ydCB7IGNvcHlUb0NoYW5uZWwgfSBmcm9tICcuLi9oZWxwZXJzL2NvcHktdG8tY2hhbm5lbCc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBjcmVhdGVOZXN0ZWRBcnJheXMgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZS1uZXN0ZWQtYXJyYXlzJztcbmltcG9ydCB7IFJlYWRPbmx5TWFwIH0gZnJvbSAnLi4vcmVhZC1vbmx5LW1hcCc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeSA9IChjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mSW5wdXRzID09PSAwICYmIG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxDb3VudCA9IEFycmF5LmlzQXJyYXkob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpXG4gICAgICAgICAgICA/IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50XG4gICAgICAgICAgICA6IEFycmF5LmZyb20ob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpO1xuICAgICAgICAvLyBAdG9kbyBDaGVjayBpZiBhbnkgb2YgdGhlIGNoYW5uZWxDb3VudCB2YWx1ZXMgaXMgZ3JlYXRlciB0aGFuIHRoZSBpbXBsZW1lbnRhdGlvbidzIG1heGltdW0gbnVtYmVyIG9mIGNoYW5uZWxzLlxuICAgICAgICBpZiAob3V0cHV0Q2hhbm5lbENvdW50LnNvbWUoKGNoYW5uZWxDb3VudCkgPT4gY2hhbm5lbENvdW50IDwgMSkpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dENoYW5uZWxDb3VudC5sZW5ndGggIT09IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNjE6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIGJ1dCByZXF1aXJlZCBmb3IgdGhlIGZha2VyIHRvIHdvcmsuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbnVtYmVyT2ZJbnB1dENoYW5uZWxzID0gb3B0aW9ucy5jaGFubmVsQ291bnQgKiBvcHRpb25zLm51bWJlck9mSW5wdXRzO1xuICAgICAgICBjb25zdCBudW1iZXJPZk91dHB1dENoYW5uZWxzID0gb3V0cHV0Q2hhbm5lbENvdW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApO1xuICAgICAgICBjb25zdCBudW1iZXJPZlBhcmFtZXRlcnMgPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkID8gMCA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmxlbmd0aDtcbiAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgaWYgKG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycyA+IDYgfHwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA+IDYpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWVzc2FnZUNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgY29uc3QgZ2Fpbk5vZGVzID0gW107XG4gICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGdhaW5Ob2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGVzID0gW107XG4gICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHsgZGVmYXVsdFZhbHVlLCBtYXhWYWx1ZSwgbWluVmFsdWUsIG5hbWUgfSBvZiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMucGFyYW1ldGVyRGF0YVtuYW1lXSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICA/IG9wdGlvbnMucGFyYW1ldGVyRGF0YVtuYW1lXVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWUgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gKGRlZmF1bHRWYWx1ZSA9PT0gdW5kZWZpbmVkID8gMCA6IGRlZmF1bHRWYWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgbWF4VmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gKG1heFZhbHVlID09PSB1bmRlZmluZWQgPyBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCA6IG1heFZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBtaW5WYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAobWluVmFsdWUgPT09IHVuZGVmaW5lZCA/IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUIDogbWluVmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGVzLnB1c2goY29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnMpXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBidWZmZXJTaXplID0gY29tcHV0ZUJ1ZmZlclNpemUoYmFzZUxhdGVuY3ksIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZUNvbnRleHQsIGJ1ZmZlclNpemUsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycywgXG4gICAgICAgIC8vIEJ1ZyAjODc6IE9ubHkgRmlyZWZveCB3aWxsIGZpcmUgYW4gQXVkaW9Qcm9jZXNzaW5nRXZlbnQgaWYgdGhlcmUgaXMgbm8gY29ubmVjdGVkIG91dHB1dC5cbiAgICAgICAgTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscykpO1xuICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscylcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IG91dHB1dENoYW5uZWxDb3VudFtpXVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICBnYWluTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldKTtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCBqLCBpICogb3B0aW9ucy5jaGFubmVsQ291bnQgKyBqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJhbWV0ZXJNYXAgPSBuZXcgUmVhZE9ubHlNYXAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5tYXAoKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNvbnN0YW50U291cmNlTm9kZXNbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIDAsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGluZGV4KTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtuYW1lLCBjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0XTtcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICBsZXQgY2hhbm5lbEludGVycHJldGF0aW9uID0gb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIGxldCBvbnByb2Nlc3NvcmVycm9yID0gbnVsbDtcbiAgICAgICAgLy8gQnVnICM4NzogRXhwb3NlIGF0IGxlYXN0IG9uZSBvdXRwdXQgdG8gbWFrZSB0aGlzIG5vZGUgY29ubmVjdGFibGUuXG4gICAgICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZXMgPSBvcHRpb25zLm51bWJlck9mT3V0cHV0cyA9PT0gMCA/IFtzY3JpcHRQcm9jZXNzb3JOb2RlXSA6IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlcztcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclNpemU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudChfKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUoXykge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNjE6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIGJ1dCByZXF1aXJlZCBmb3IgdGhlIGZha2VyIHRvIHdvcmsuXG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBjaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZ2Fpbk5vZGUgb2YgZ2Fpbk5vZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlcztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9ucHJvY2Vzc29yZXJyb3IoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9ucHJvY2Vzc29yZXJyb3I7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG9ucHJvY2Vzc29yZXJyb3IodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9ucHJvY2Vzc29yZXJyb3IgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlci5hZGRFdmVudExpc3RlbmVyKCdwcm9jZXNzb3JlcnJvcicsIG9ucHJvY2Vzc29yZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcGFyYW1ldGVycygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFyYW1ldGVyTWFwO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3J0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlQ2hhbm5lbC5wb3J0MjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbm5lY3Q6IGNvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRBdWRpb05vZGVzKSxcbiAgICAgICAgICAgIGRpc2Nvbm5lY3Q6IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRBdWRpb05vZGVzKSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5hZGRFdmVudExpc3RlbmVyID0gKChhZGRFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHR5cGVvZiBhcmdzWzFdID09PSAnb2JqZWN0JyAmJiBhcmdzWzFdICE9PSBudWxsICYmIHR5cGVvZiBhcmdzWzFdLmhhbmRsZUV2ZW50ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdLmhhbmRsZUV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICBpZiAodW5wYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKG5hdGl2ZUNvbnRleHQuY3VycmVudFRpbWUsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgKCkgPT4gdW5wYXRjaGVkRXZlbnRMaXN0ZW5lcihldmVudCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLnNldCh1bnBhdGNoZWRFdmVudExpc3RlbmVyLCBhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYWRkRXZlbnRMaXN0ZW5lci5jYWxsKG1lc3NhZ2VDaGFubmVsLnBvcnQxLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5yZW1vdmVFdmVudExpc3RlbmVyID0gKChyZW1vdmVFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ21lc3NhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5kZWxldGUoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbChtZXNzYWdlQ2hhbm5lbC5wb3J0MSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShtZXNzYWdlQ2hhbm5lbC5wb3J0MS5yZW1vdmVFdmVudExpc3RlbmVyKTtcbiAgICAgICAgbGV0IG9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXNzYWdlQ2hhbm5lbC5wb3J0MSwgJ29ubWVzc2FnZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gb25tZXNzYWdlLFxuICAgICAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ubWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb25tZXNzYWdlID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5zdGFydCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnByb3RvdHlwZS5wb3J0ID0gbWVzc2FnZUNoYW5uZWwucG9ydDE7XG4gICAgICAgIGxldCBhdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSBudWxsO1xuICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpO1xuICAgICAgICBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlLnRoZW4oKGRXcmtsdFByY3NzcikgPT4gKGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IGRXcmtsdFByY3NzcikpO1xuICAgICAgICBjb25zdCBpbnB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZklucHV0cywgb3B0aW9ucy5jaGFubmVsQ291bnQpO1xuICAgICAgICBjb25zdCBvdXRwdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzLCBvdXRwdXRDaGFubmVsQ291bnQpO1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBbXVxuICAgICAgICAgICAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5yZWR1Y2UoKHBybXRycywgeyBuYW1lIH0pID0+ICh7IC4uLnBybXRycywgW25hbWVdOiBuZXcgRmxvYXQzMkFycmF5KDEyOCkgfSksIHt9KTtcbiAgICAgICAgbGV0IGlzQWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdE91dHB1dHNHcmFwaCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mT3V0cHV0cyA+IDApIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdXRwdXRDaGFubmVsQ291bnRbaV07IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBqLCBqKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0SW5kZXhlcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciwgb3V0cHV0QnVmZmVyIH0pID0+IHtcbiAgICAgICAgICAgIGlmIChhdWRpb1dvcmtsZXRQcm9jZXNzb3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbnB1dHMgPSBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlcik7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWZmZXJTaXplOyBpICs9IDEyOCkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKGlucHV0QnVmZmVyLCBpbnB1dHNbal0sIGssIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5mb3JFYWNoKCh7IG5hbWUgfSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwoaW5wdXRCdWZmZXIsIHBhcmFtZXRlcnMsIG5hbWUsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGluZGV4LCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG91dHB1dENoYW5uZWxDb3VudFtqXTsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3V0cHV0c1tqXVtrXS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dHNbal1ba10gPSBuZXcgRmxvYXQzMkFycmF5KDEyOCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3RlbnRpYWxseUVtcHR5SW5wdXRzID0gaW5wdXRzLm1hcCgoaW5wdXQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWN0aXZlSW5wdXQgPSBhY3RpdmVJbnB1dHNbaW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY3RpdmVJbnB1dC5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVJbnB1dEluZGV4ZXMuc2V0KGluZGV4LCBidWZmZXJTaXplIC8gMTI4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb3VudCA9IGFjdGl2ZUlucHV0SW5kZXhlcy5nZXQoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlucHV0LmV2ZXJ5KChjaGFubmVsRGF0YSkgPT4gY2hhbm5lbERhdGEuZXZlcnkoKHNhbXBsZSkgPT4gc2FtcGxlID09PSAwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVJbnB1dEluZGV4ZXMuZGVsZXRlKGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5zZXQoaW5kZXgsIGNvdW50IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVTb3VyY2VGbGFnID0gZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSArIGkgLyBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgKCkgPT4gYXVkaW9Xb3JrbGV0UHJvY2Vzc29yLnByb2Nlc3MocG90ZW50aWFsbHlFbXB0eUlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNBY3RpdmUgPSBhY3RpdmVTb3VyY2VGbGFnO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weVRvQ2hhbm5lbChvdXRwdXRCdWZmZXIsIG91dHB1dHNbal0sIGssIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBrLCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbal07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLmRpc3BhdGNoRXZlbnQobmV3IEVycm9yRXZlbnQoJ3Byb2Nlc3NvcmVycm9yJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG5vOiBlcnJvci5jb2xubyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogZXJyb3IuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZW5vOiBlcnJvci5saW5lbm8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGVzW2pdLmRpc2Nvbm5lY3QoaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tqXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0uZGlzY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCBrLCBqICogb3B0aW9ucy5jaGFubmVsQ291bnQgKyBrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNvbnN0YW50U291cmNlTm9kZXNbal07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5kaXNjb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIDAsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGopO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbE1lcmdlck5vZGUuZGlzY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSBudWxsOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0T3V0cHV0c0dyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIC8vIEJ1ZyAjODc6IE9ubHkgRmlyZWZveCB3aWxsIGZpcmUgYW4gQXVkaW9Qcm9jZXNzaW5nRXZlbnQgaWYgdGhlcmUgaXMgbm8gY29ubmVjdGVkIG91dHB1dC5cbiAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY29ubmVjdEZha2VHcmFwaCA9ICgpID0+IHNjcmlwdFByb2Nlc3Nvck5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdEZha2VHcmFwaCA9ICgpID0+IHtcbiAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBuYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3V0cHV0Q2hhbm5lbENvdW50W2ldOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0T3V0cHV0c0dyYXBoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICBjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdRJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdkZXR1bmUnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ2ZyZXF1ZW5jeScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnZ2FpbicpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAndHlwZScpO1xuICAgIHJldHVybiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1iaXF1YWQtZmlsdGVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeSA9IChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgd3JhcENoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDaGFubmVsTWVyZ2VyKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMpO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzIwOiBTYWZhcmkgcmVxdWlyZXMgYSBjb25uZWN0aW9uIG9mIGFueSBraW5kIHRvIHRyZWF0IHRoZSBpbnB1dCBzaWduYWwgY29ycmVjdGx5LlxuICAgICAgICAgKiBAdG9kbyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGlzIG5vIHdheSB0byB0ZXN0IGZvciB0aGlzIGJlaGF2aW9yIGluIGEgc3luY2hyb25vdXMgZmFzaGlvbiB3aGljaCBpcyB3aHkgdGVzdGluZyBmb3IgdGhlIGV4aXN0ZW5jZSBvZlxuICAgICAgICAgKiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgIHdyYXBDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jaGFubmVsLW1lcmdlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW52YWxpZC1zdGF0ZS1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUgPSAoY2hhbm5lbFNwbGl0dGVyTm9kZSkgPT4ge1xuICAgIGNvbnN0IGNoYW5uZWxDb3VudCA9IGNoYW5uZWxTcGxpdHRlck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgIC8vIEJ1ZyAjOTc6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIGF0dGVtcHRpbmcgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnQgdG8gc29tZXRoaW5nIG90aGVyIHRoYW4gaXRzIGluaXRpYWwgdmFsdWUuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxTcGxpdHRlck5vZGUsICdjaGFubmVsQ291bnQnLCB7XG4gICAgICAgIGdldDogKCkgPT4gY2hhbm5lbENvdW50LFxuICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgLy8gQnVnICMzMDogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudE1vZGUgdG8gc29tZXRoaW5nIG90aGVyIHRoYW4gZXhwbGljaXQuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxTcGxpdHRlck5vZGUsICdjaGFubmVsQ291bnRNb2RlJywge1xuICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgLy8gQnVnICMzMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxJbnRlcnByZXRhdGlvbiB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBkaXNjcmV0ZS5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiAnZGlzY3JldGUnLFxuICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSAnZGlzY3JldGUnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBDaGFubmVsU3BsaXR0ZXJOb2RlIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWNoYW5uZWwtc3BsaXR0ZXItbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzKTtcbiAgICAvLyBCdWcgIzk2OiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnQuXG4gICAgLy8gQnVnICMyOTogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50TW9kZS5cbiAgICAvLyBCdWcgIzMxOiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsSW50ZXJwcmV0YXRpb24uXG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBvcHRpb25zKTtcbiAgICAvLyBCdWcgIzI5LCAjMzAsICMzMSwgIzMyLCAjOTYgJiAjOTc6IE9ubHkgQ2hyb21lLCBFZGdlICYgRmlyZWZveCBwYXJ0aWFsbHkgc3VwcG9ydCB0aGUgc3BlYyB5ZXQuXG4gICAgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgcmV0dXJuIG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNoYW5uZWwtc3BsaXR0ZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWN0b3J5ID0gKGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBCdWcgIzYyOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBDb25zdGFudFNvdXJjZU5vZGVzLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIG9wdGlvbnMsICdvZmZzZXQnKTtcbiAgICAgICAgLy8gQnVnICM0NDogU2FmYXJpIGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQ29uc3RhbnRTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaW50ZXJjZXB0Q29ubmVjdGlvbnMgPSAob3JpZ2luYWwsIGludGVyY2VwdG9yKSA9PiB7XG4gICAgb3JpZ2luYWwuY29ubmVjdCA9IGludGVyY2VwdG9yLmNvbm5lY3QuYmluZChpbnRlcmNlcHRvcik7XG4gICAgb3JpZ2luYWwuZGlzY29ubmVjdCA9IGludGVyY2VwdG9yLmRpc2Nvbm5lY3QuYmluZChpbnRlcmNlcHRvcik7XG4gICAgcmV0dXJuIG9yaWdpbmFsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludGVyY2VwdC1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlckZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IG9mZnNldCwgLi4uYXVkaW9Ob2RlT3B0aW9ucyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMiwgNDQxMDApO1xuICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiBvZmZzZXQgfSk7XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgLy8gQnVnICM5NTogU2FmYXJpIGRvZXMgbm90IHBsYXkgb3IgbG9vcCBvbmUgc2FtcGxlIGJ1ZmZlcnMuXG4gICAgICAgIGNoYW5uZWxEYXRhWzBdID0gMTtcbiAgICAgICAgY2hhbm5lbERhdGFbMV0gPSAxO1xuICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gYXVkaW9CdWZmZXI7XG4gICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wID0gdHJ1ZTtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9mZnNldCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb25lbmRlZCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0LmNhbGwoYXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AuY2FsbChhdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3QoZ2Fpbk5vZGUpO1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoZ2Fpbk5vZGUpO1xuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIEF1ZGlvQnVmZmVyU291cmNlTm9kZSBpcyB1bmNvbm5lY3RlZC5cbiAgICAgICAgYWRkU2lsZW50Q29ubmVjdGlvbihuYXRpdmVDb250ZXh0LCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyLCBnYWluTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnZvbHZlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNvbnZvbHZlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICAvLyBUaGUgbm9ybWFsaXplIHByb3BlcnR5IG5lZWRzIHRvIGJlIHNldCBiZWZvcmUgc2V0dGluZyB0aGUgYnVmZmVyLlxuICAgICAgICBpZiAob3B0aW9ucy5kaXNhYmxlTm9ybWFsaXphdGlvbiA9PT0gbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemUpIHtcbiAgICAgICAgICAgIG5hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplID0gIW9wdGlvbnMuZGlzYWJsZU5vcm1hbGl6YXRpb247XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUNvbnZvbHZlck5vZGUsIG9wdGlvbnMsICdidWZmZXInKTtcbiAgICAgICAgLy8gQnVnICMxMTM6IFNhZmFyaSBkb2VzIGFsbG93IHRvIHNldCB0aGUgY2hhbm5lbENvdW50IHRvIGEgdmFsdWUgbGFyZ2VyIHRoYW4gMi5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50ID4gMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlQ29udm9sdmVyTm9kZSwgJ2NoYW5uZWxDb3VudCcsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKG5hdGl2ZUNvbnZvbHZlck5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IDIpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldC5jYWxsKG5hdGl2ZUNvbnZvbHZlck5vZGUsIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE0OiBTYWZhcmkgYWxsb3dzIHRvIHNldCB0aGUgY2hhbm5lbENvdW50TW9kZSB0byAnbWF4Jy5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZUNvbnZvbHZlck5vZGUsICdjaGFubmVsQ291bnRNb2RlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnZvbHZlck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29udm9sdmVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlRGVsYXlOb2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVEZWxheU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZURlbGF5KG9wdGlvbnMubWF4RGVsYXlUaW1lKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZURlbGF5Tm9kZSwgb3B0aW9ucyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZURlbGF5Tm9kZSwgb3B0aW9ucywgJ2RlbGF5VGltZScpO1xuICAgIHJldHVybiBuYXRpdmVEZWxheU5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWRlbGF5LW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICAvLyBCdWcgIzEwODogU2FmYXJpIGFsbG93cyBhIGNoYW5uZWxDb3VudCBvZiB0aHJlZSBhbmQgYWJvdmUuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDk6IE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IGRpc2FsbG93IGEgY2hhbm5lbENvdW50TW9kZSBvZiAnbWF4Jy5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdhdHRhY2snKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdrbmVlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAncmF0aW8nKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdyZWxlYXNlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAndGhyZXNob2xkJyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVHYWluTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUdhaW5Ob2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlR2Fpbk5vZGUsIG9wdGlvbnMsICdnYWluJyk7XG4gICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1nYWluLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG9wdGlvbnMpID0+IHtcbiAgICAgICAgLy8gQnVnICM5OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBJSVJGaWx0ZXJOb2Rlcy5cbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQuY3JlYXRlSUlSRmlsdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgZGVmaW5lcyB0aGUgcGFyYW1ldGVycyBvZiBjcmVhdGVJSVJGaWx0ZXIoKSBhcyBhcnJheXMgb2YgbnVtYmVycy5cbiAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKG9wdGlvbnMuZmVlZGZvcndhcmQsIG9wdGlvbnMuZmVlZGJhY2spO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUlJUkZpbHRlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBjb21wdXRlQnVmZmVyU2l6ZSB9IGZyb20gJy4uL2hlbHBlcnMvY29tcHV0ZS1idWZmZXItc2l6ZSc7XG5pbXBvcnQgeyBmaWx0ZXJCdWZmZXIgfSBmcm9tICcuLi9oZWxwZXJzL2ZpbHRlci1idWZmZXInO1xuaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5mdW5jdGlvbiBkaXZpZGUoYSwgYikge1xuICAgIGNvbnN0IGRlbm9taW5hdG9yID0gYlswXSAqIGJbMF0gKyBiWzFdICogYlsxXTtcbiAgICByZXR1cm4gWyhhWzBdICogYlswXSArIGFbMV0gKiBiWzFdKSAvIGRlbm9taW5hdG9yLCAoYVsxXSAqIGJbMF0gLSBhWzBdICogYlsxXSkgLyBkZW5vbWluYXRvcl07XG59XG5mdW5jdGlvbiBtdWx0aXBseShhLCBiKSB7XG4gICAgcmV0dXJuIFthWzBdICogYlswXSAtIGFbMV0gKiBiWzFdLCBhWzBdICogYlsxXSArIGFbMV0gKiBiWzBdXTtcbn1cbmZ1bmN0aW9uIGV2YWx1YXRlUG9seW5vbWlhbChjb2VmZmljaWVudCwgeikge1xuICAgIGxldCByZXN1bHQgPSBbMCwgMF07XG4gICAgZm9yIChsZXQgaSA9IGNvZWZmaWNpZW50Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgICAgIHJlc3VsdCA9IG11bHRpcGx5KHJlc3VsdCwgeik7XG4gICAgICAgIHJlc3VsdFswXSArPSBjb2VmZmljaWVudFtpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5ID0gKGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgeyBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudE1vZGUsIGNoYW5uZWxJbnRlcnByZXRhdGlvbiwgZmVlZGJhY2ssIGZlZWRmb3J3YXJkIH0pID0+IHtcbiAgICAgICAgY29uc3QgYnVmZmVyU2l6ZSA9IGNvbXB1dGVCdWZmZXJTaXplKGJhc2VMYXRlbmN5LCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRGZWVkYmFjayA9IGZlZWRiYWNrIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGJhY2sgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRiYWNrKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkRmVlZGZvcndhcmQgPSBmZWVkZm9yd2FyZCBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRmb3J3YXJkIDogbmV3IEZsb2F0NjRBcnJheShmZWVkZm9yd2FyZCk7XG4gICAgICAgIGNvbnN0IGZlZWRiYWNrTGVuZ3RoID0gY29udmVydGVkRmVlZGJhY2subGVuZ3RoO1xuICAgICAgICBjb25zdCBmZWVkZm9yd2FyZExlbmd0aCA9IGNvbnZlcnRlZEZlZWRmb3J3YXJkLmxlbmd0aDtcbiAgICAgICAgY29uc3QgbWluTGVuZ3RoID0gTWF0aC5taW4oZmVlZGJhY2tMZW5ndGgsIGZlZWRmb3J3YXJkTGVuZ3RoKTtcbiAgICAgICAgaWYgKGZlZWRiYWNrTGVuZ3RoID09PSAwIHx8IGZlZWRiYWNrTGVuZ3RoID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnZlcnRlZEZlZWRiYWNrWzBdID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmZWVkZm9yd2FyZExlbmd0aCA9PT0gMCB8fCBmZWVkZm9yd2FyZExlbmd0aCA+IDIwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb252ZXJ0ZWRGZWVkZm9yd2FyZFswXSA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gIT09IDEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmVlZGZvcndhcmRMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRmb3J3YXJkW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBmZWVkYmFja0xlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29udmVydGVkRmVlZGJhY2tbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgYnVmZmVyU2l6ZSwgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnQpO1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IGNoYW5uZWxDb3VudDtcbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlID0gY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSBjaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIGNvbnN0IGJ1ZmZlckxlbmd0aCA9IDMyO1xuICAgICAgICBjb25zdCBidWZmZXJJbmRleGVzID0gW107XG4gICAgICAgIGNvbnN0IHhCdWZmZXJzID0gW107XG4gICAgICAgIGNvbnN0IHlCdWZmZXJzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbENvdW50OyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ1ZmZlckluZGV4ZXMucHVzaCgwKTtcbiAgICAgICAgICAgIGNvbnN0IHhCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgICAgICAgICBjb25zdCB5QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgICAgICAgICAgeEJ1ZmZlci5maWxsKDApO1xuICAgICAgICAgICAgeUJ1ZmZlci5maWxsKDApO1xuICAgICAgICAgICAgeEJ1ZmZlcnMucHVzaCh4QnVmZmVyKTtcbiAgICAgICAgICAgIHlCdWZmZXJzLnB1c2goeUJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlucHV0QnVmZmVyID0gZXZlbnQuaW5wdXRCdWZmZXI7XG4gICAgICAgICAgICBjb25zdCBvdXRwdXRCdWZmZXIgPSBldmVudC5vdXRwdXRCdWZmZXI7XG4gICAgICAgICAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gaW5wdXRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZDaGFubmVsczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBpbnB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSk7XG4gICAgICAgICAgICAgICAgYnVmZmVySW5kZXhlc1tpXSA9IGZpbHRlckJ1ZmZlcihjb252ZXJ0ZWRGZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGNvbnZlcnRlZEZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyc1tpXSwgeUJ1ZmZlcnNbaV0sIGJ1ZmZlckluZGV4ZXNbaV0sIGJ1ZmZlckxlbmd0aCwgaW5wdXQsIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IG55cXVpc3QgPSBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUgLyAyO1xuICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyU2l6ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbc2NyaXB0UHJvY2Vzc29yTm9kZV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIERpc3NhbGxvdyBhZGRpbmcgYW4gYXVkaW9wcm9jZXNzIGxpc3RlbmVyLlxuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICBpZiAoZnJlcXVlbmN5SHoubGVuZ3RoICE9PSBtYWdSZXNwb25zZS5sZW5ndGggfHwgbWFnUmVzcG9uc2UubGVuZ3RoICE9PSBwaGFzZVJlc3BvbnNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gZnJlcXVlbmN5SHoubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb21lZ2EgPSAtTWF0aC5QSSAqIChmcmVxdWVuY3lIeltpXSAvIG55cXVpc3QpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB6ID0gW01hdGguY29zKG9tZWdhKSwgTWF0aC5zaW4ob21lZ2EpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJhdG9yID0gZXZhbHVhdGVQb2x5bm9taWFsKGNvbnZlcnRlZEZlZWRmb3J3YXJkLCB6KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVub21pbmF0b3IgPSBldmFsdWF0ZVBvbHlub21pYWwoY29udmVydGVkRmVlZGJhY2ssIHopO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGRpdmlkZShudW1lcmF0b3IsIGRlbm9taW5hdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgbWFnUmVzcG9uc2VbaV0gPSBNYXRoLnNxcnQocmVzcG9uc2VbMF0gKiByZXNwb25zZVswXSArIHJlc3BvbnNlWzFdICogcmVzcG9uc2VbMV0pO1xuICAgICAgICAgICAgICAgICAgICBwaGFzZVJlc3BvbnNlW2ldID0gTWF0aC5hdGFuMihyZXNwb25zZVsxXSwgcmVzcG9uc2VbMF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyLCBzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIHJldHVybiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKG9wdGlvbnMubWVkaWFFbGVtZW50KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IChuYXRpdmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIG9wdGlvbnMpO1xuICAgIC8vIEJ1ZyAjMTc0OiBTYWZhcmkgZG9lcyBleHBvc2UgYSB3cm9uZyBudW1iZXJPZk91dHB1dHMuXG4gICAgaWYgKG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUubnVtYmVyT2ZPdXRwdXRzID09PSAxKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCAnbnVtYmVyT2ZPdXRwdXRzJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSAobmF0aXZlQXVkaW9Db250ZXh0LCB7IG1lZGlhU3RyZWFtIH0pID0+IHtcbiAgICBjb25zdCBhdWRpb1N0cmVhbVRyYWNrcyA9IG1lZGlhU3RyZWFtLmdldEF1ZGlvVHJhY2tzKCk7XG4gICAgLypcbiAgICAgKiBCdWcgIzE1MTogU2FmYXJpIGRvZXMgbm90IHVzZSB0aGUgYXVkaW8gdHJhY2sgYXMgaW5wdXQgYW55bW9yZSBpZiBpdCBnZXRzIHJlbW92ZWQgZnJvbSB0aGUgbWVkaWFTdHJlYW0gYWZ0ZXIgY29uc3RydWN0aW9uLlxuICAgICAqIEJ1ZyAjMTU5OiBTYWZhcmkgcGlja3MgdGhlIGZpcnN0IGF1ZGlvIHRyYWNrIGlmIHRoZSBNZWRpYVN0cmVhbSBoYXMgbW9yZSB0aGFuIG9uZSBhdWRpbyB0cmFjay5cbiAgICAgKi9cbiAgICBhdWRpb1N0cmVhbVRyYWNrcy5zb3J0KChhLCBiKSA9PiAoYS5pZCA8IGIuaWQgPyAtMSA6IGEuaWQgPiBiLmlkID8gMSA6IDApKTtcbiAgICBjb25zdCBmaWx0ZXJlZEF1ZGlvU3RyZWFtVHJhY2tzID0gYXVkaW9TdHJlYW1UcmFja3Muc2xpY2UoMCwgMSk7XG4gICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UobmV3IE1lZGlhU3RyZWFtKGZpbHRlcmVkQXVkaW9TdHJlYW1UcmFja3MpKTtcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTUxICYgIzE1OTogVGhlIGdpdmVuIG1lZGlhU3RyZWFtIGdldHMgcmVjb25zdHJ1Y3RlZCBiZWZvcmUgaXQgZ2V0cyBwYXNzZWQgdG8gdGhlIG5hdGl2ZSBub2RlIHdoaWNoIGlzIHdoeSB0aGUgYWNjZXNzb3IgbmVlZHNcbiAgICAgKiB0byBiZSBvdmVyd3JpdHRlbiBhcyBpdCB3b3VsZCBvdGhlcndpc2UgZXhwb3NlIHRoZSByZWNvbnN0cnVjdGVkIHZlcnNpb24uXG4gICAgICovXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCAnbWVkaWFTdHJlYW0nLCB7IHZhbHVlOiBtZWRpYVN0cmVhbSB9KTtcbiAgICByZXR1cm4gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Db250ZXh0LCB7IG1lZGlhU3RyZWFtVHJhY2sgfSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzEyMTogT25seSBGaXJlZm94IGRvZXMgeWV0IHN1cHBvcnQgdGhlIE1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUuXG4gICAgICAgIGlmICh0eXBlb2YgbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tTb3VyY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1UcmFja1NvdXJjZShtZWRpYVN0cmVhbVRyYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZWRpYVN0cmVhbSA9IG5ldyBNZWRpYVN0cmVhbShbbWVkaWFTdHJlYW1UcmFja10pO1xuICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShtZWRpYVN0cmVhbSk7XG4gICAgICAgIC8vIEJ1ZyAjMTIwOiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBtZWRpYVN0cmVhbSBoYXMgbm8gYXVkaW8gdHJhY2suXG4gICAgICAgIGlmIChtZWRpYVN0cmVhbVRyYWNrLmtpbmQgIT09ICdhdWRpbycpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzI6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgd2l0aCBhbiBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUF1ZGlvQ29udGV4dCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdPZmZsaW5lQXVkaW9Db250ZXh0JykpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5PZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCd3ZWJraXRPZmZsaW5lQXVkaW9Db250ZXh0JykgPyB3aW5kb3cud2Via2l0T2ZmbGluZUF1ZGlvQ29udGV4dCA6IG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGVGYWN0b3J5ID0gKGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ2RldHVuZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlT3NjaWxsYXRvck5vZGUsIG9wdGlvbnMsICdmcmVxdWVuY3knKTtcbiAgICAgICAgaWYgKG9wdGlvbnMucGVyaW9kaWNXYXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnNldFBlcmlvZGljV2F2ZShvcHRpb25zLnBlcmlvZGljV2F2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlT3NjaWxsYXRvck5vZGUsIG9wdGlvbnMsICd0eXBlJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBDaHJvbWUgJiBFZGdlIHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTk6IFNhZmFyaSBkb2VzIG5vdCBpZ25vcmUgY2FsbHMgdG8gc3RvcCgpIG9mIGFuIGFscmVhZHkgc3RvcHBlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlT3NjaWxsYXRvck5vZGUsIG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIE9zY2lsbGF0b3JOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU9zY2lsbGF0b3JOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW9zY2lsbGF0b3Itbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVBhbm5lck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgICAgICAvLyBCdWcgIzEyNDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZ5aW5nIHRoZSBvcmllbnRhdGlvbiBhbmQgdGhlIHBvc2l0aW9uIHdpdGggQXVkaW9QYXJhbXMuXG4gICAgICAgIGlmIChuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnb3JpZW50YXRpb25YJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnb3JpZW50YXRpb25ZJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnb3JpZW50YXRpb25aJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncG9zaXRpb25YJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncG9zaXRpb25ZJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncG9zaXRpb25aJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnY29uZUlubmVyQW5nbGUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdjb25lT3V0ZXJBbmdsZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2NvbmVPdXRlckdhaW4nKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdkaXN0YW5jZU1vZGVsJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnbWF4RGlzdGFuY2UnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwYW5uaW5nTW9kZWwnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdyZWZEaXN0YW5jZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3JvbGxvZmZGYWN0b3InKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVBhbm5lck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGFubmVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5ID0gKGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0Rmlyc3RTYW1wbGUsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBjb25lSW5uZXJBbmdsZSwgY29uZU91dGVyQW5nbGUsIGNvbmVPdXRlckdhaW4sIGRpc3RhbmNlTW9kZWwsIG1heERpc3RhbmNlLCBvcmllbnRhdGlvblgsIG9yaWVudGF0aW9uWSwgb3JpZW50YXRpb25aLCBwYW5uaW5nTW9kZWwsIHBvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblosIHJlZkRpc3RhbmNlLCByb2xsb2ZmRmFjdG9yLCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgcGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgICAgIC8vIEJ1ZyAjMTI1OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICBpZiAoYXVkaW9Ob2RlT3B0aW9ucy5jaGFubmVsQ291bnQgPiAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTI2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICBpZiAoYXVkaW9Ob2RlT3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKHBhbm5lck5vZGUsIGF1ZGlvTm9kZU9wdGlvbnMpO1xuICAgICAgICBjb25zdCBTSU5HTEVfQ0hBTk5FTF9PUFRJT05TID0ge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJ1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICBudW1iZXJPZklucHV0czogNlxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3Qgb3JpZW50YXRpb25YR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uWUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBvcmllbnRhdGlvblpHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25YR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uWUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBwb3NpdGlvblpHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgMjU2LCA2LCAxKTtcbiAgICAgICAgY29uc3Qgd2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IG5ldyBGbG9hdDMyQXJyYXkoWzEsIDFdKSxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6ICdub25lJ1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGxhc3RPcmllbnRhdGlvbiA9IFtvcmllbnRhdGlvblgsIG9yaWVudGF0aW9uWSwgb3JpZW50YXRpb25aXTtcbiAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFtwb3NpdGlvblgsIHBvc2l0aW9uWSwgcG9zaXRpb25aXTtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheSgxKTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbiA9IFtcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAwKSxcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAxKSxcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAyKVxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0T3JpZW50YXRpb24oLi4ub3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgbGFzdE9yaWVudGF0aW9uID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW1xuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDMpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDQpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDUpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKHBvc2l0b24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnNldFBvc2l0aW9uKC4uLnBvc2l0b24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9yaWVudGF0aW9uWUdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9yaWVudGF0aW9uWkdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvc2l0aW9uWEdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvc2l0aW9uWUdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBvc2l0aW9uWkdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29uZUlubmVyQW5nbGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29uZUlubmVyQW5nbGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNvbmVJbm5lckFuZ2xlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbmVPdXRlckdhaW4oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29uZU91dGVyR2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZU91dGVyR2Fpbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI3OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gSW52YWxpZFN0YXRlRXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY29uZU91dGVyR2FpbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGRpc3RhbmNlTW9kZWwoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgZGlzdGFuY2VNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWF4RGlzdGFuY2UoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubWF4RGlzdGFuY2U7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG1heERpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLm1heERpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvcmllbnRhdGlvblgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWVudGF0aW9uWEdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9yaWVudGF0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb25ZR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3JpZW50YXRpb25aKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvblpHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwYW5uaW5nTW9kZWwoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUucGFubmluZ01vZGVsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBwYW5uaW5nTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnBhbm5pbmdNb2RlbCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWEdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25ZR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25aKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblpHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCByZWZEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5yZWZEaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgcmVmRGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyOTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucmVmRGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcm9sbG9mZkZhY3RvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMzA6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3IgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGNvbmVJbm5lckFuZ2xlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZUlubmVyQW5nbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lSW5uZXJBbmdsZSA9IGNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25lT3V0ZXJBbmdsZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckFuZ2xlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyQW5nbGUgPSBjb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZU91dGVyR2FpbiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckdhaW4pIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJHYWluID0gY29uZU91dGVyR2FpbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzdGFuY2VNb2RlbCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmRpc3RhbmNlTW9kZWwpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5kaXN0YW5jZU1vZGVsID0gZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF4RGlzdGFuY2UgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5tYXhEaXN0YW5jZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm1heERpc3RhbmNlID0gbWF4RGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yaWVudGF0aW9uWCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWC52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWC52YWx1ZSA9IG9yaWVudGF0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZW50YXRpb25ZICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25ZLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25ZLnZhbHVlID0gb3JpZW50YXRpb25ZO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmllbnRhdGlvblogIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvbloudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvbloudmFsdWUgPSBvcmllbnRhdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhbm5pbmdNb2RlbCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBhbm5pbmdNb2RlbCkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBhbm5pbmdNb2RlbCA9IHBhbm5pbmdNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb25YICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25YLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25YLnZhbHVlID0gcG9zaXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvblkgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblkudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblkudmFsdWUgPSBwb3NpdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uWiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWi52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWi52YWx1ZSA9IHBvc2l0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVmRGlzdGFuY2UgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yZWZEaXN0YW5jZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnJlZkRpc3RhbmNlID0gcmVmRGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJvbGxvZmZGYWN0b3IgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yb2xsb2ZmRmFjdG9yKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucm9sbG9mZkZhY3RvciA9IHJvbGxvZmZGYWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhc3RPcmllbnRhdGlvblswXSAhPT0gMSB8fCBsYXN0T3JpZW50YXRpb25bMV0gIT09IDAgfHwgbGFzdE9yaWVudGF0aW9uWzJdICE9PSAwKSB7XG4gICAgICAgICAgICBwYW5uZXJOb2RlLnNldE9yaWVudGF0aW9uKC4uLmxhc3RPcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgfVxuICAgICAgICBpZiAobGFzdFBvc2l0aW9uWzBdICE9PSAwIHx8IGxhc3RQb3NpdGlvblsxXSAhPT0gMCB8fCBsYXN0UG9zaXRpb25bMl0gIT09IDApIHtcbiAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0UG9zaXRpb24oLi4ubGFzdFBvc2l0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocGFubmVyTm9kZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKGlucHV0R2Fpbk5vZGUsIHdhdmVTaGFwZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3Qob3JpZW50YXRpb25YR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChvcmllbnRhdGlvbllHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KG9yaWVudGF0aW9uWkdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAyKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocG9zaXRpb25YR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDMpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChwb3NpdGlvbllHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgNCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KHBvc2l0aW9uWkdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCA1KTtcbiAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChwYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShpbnB1dEdhaW5Ob2RlLCB3YXZlU2hhcGVyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG9yaWVudGF0aW9uWEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvcmllbnRhdGlvbllHYWluTm9kZSk7XG4gICAgICAgICAgICBvcmllbnRhdGlvbllHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3JpZW50YXRpb25aR2Fpbk5vZGUpO1xuICAgICAgICAgICAgb3JpZW50YXRpb25aR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBvc2l0aW9uWEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHBvc2l0aW9uWEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwb3NpdGlvbllHYWluTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGlvbllHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocG9zaXRpb25aR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpb25aR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5kaXNjb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVBhbm5lck5vZGVGYWtlciwgcGFubmVyTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZUZhY3RvcnkgPSAoY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgZGlzYWJsZU5vcm1hbGl6YXRpb24sIGltYWcsIHJlYWwgfSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzE4MDogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHVzZSBvcmRpbmFyeSBhcnJheXMuXG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZEltYWcgPSBpbWFnIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gaW1hZyA6IG5ldyBGbG9hdDMyQXJyYXkoaW1hZyk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZFJlYWwgPSByZWFsIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gcmVhbCA6IG5ldyBGbG9hdDMyQXJyYXkocmVhbCk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVBlcmlvZGljV2F2ZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlKGNvbnZlcnRlZFJlYWwsIGNvbnZlcnRlZEltYWcsIHsgZGlzYWJsZU5vcm1hbGl6YXRpb24gfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTgxOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gSW5kZXhTaXplRXJyb3Igc28gZmFyIGlmIHRoZSBnaXZlbiBhcnJheXMgaGF2ZSBsZXNzIHRoYW4gdHdvIHZhbHVlcy5cbiAgICAgICAgaWYgKEFycmF5LmZyb20oaW1hZykubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlUGVyaW9kaWNXYXZlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXBlcmlvZGljLXdhdmUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSA9IChuYXRpdmVDb250ZXh0LCBidWZmZXJTaXplLCBudW1iZXJPZklucHV0Q2hhbm5lbHMsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpID0+IHtcbiAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoYnVmZmVyU2l6ZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1zY3JpcHQtcHJvY2Vzc29yLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbm5lbENvdW50TW9kZSA9IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDU6IFRoZSBjaGFubmVsQ291bnRNb2RlIG9mICdjbGFtcGVkLW1heCcgc2hvdWxkIGJlIHN1cHBvcnRlZC4gSG93ZXZlciBpdCBpcyBub3QgcG9zc2libGUgdG8gd3JpdGUgYSBwb2x5ZmlsbCBmb3IgU2FmYXJpXG4gICAgICAgICAqIHdoaWNoIHN1cHBvcnRzIGl0IGFuZCB0aGVyZWZvcmUgaXQgY2FuJ3QgYmUgc3VwcG9ydGVkIGF0IGFsbC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChjaGFubmVsQ291bnRNb2RlID09PSAnY2xhbXBlZC1tYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTA1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCB0aGUgU3RlcmVvUGFubmVyTm9kZS5cbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBvcHRpb25zLCAncGFuJyk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTA1OiBUaGUgY2hhbm5lbENvdW50TW9kZSBvZiAnY2xhbXBlZC1tYXgnIHNob3VsZCBiZSBzdXBwb3J0ZWQuIEhvd2V2ZXIgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHdyaXRlIGEgcG9seWZpbGwgZm9yIFNhZmFyaVxuICAgICAgICAgKiB3aGljaCBzdXBwb3J0cyBpdCBhbmQgdGhlcmVmb3JlIGl0IGNhbid0IGJlIHN1cHBvcnRlZCBhdCBhbGwuXG4gICAgICAgICAqL1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IGNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gY2hhbm5lbENvdW50TW9kZSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIC8vIFRoZSBjdXJ2ZSBoYXMgYSBzaXplIG9mIDE0Yml0IHBsdXMgMSB2YWx1ZSB0byBoYXZlIGFuIGV4YWN0IHJlcHJlc2VudGF0aW9uIGZvciB6ZXJvLiBUaGlzIHZhbHVlIGhhcyBiZWVuIGRldGVybWluZWQgZXhwZXJpbWVudGFsbHkuXG4gICAgY29uc3QgQ1VSVkVfU0laRSA9IDE2Mzg1O1xuICAgIGNvbnN0IERDX0NVUlZFID0gbmV3IEZsb2F0MzJBcnJheShbMSwgMV0pO1xuICAgIGNvbnN0IEhBTEZfUEkgPSBNYXRoLlBJIC8gMjtcbiAgICBjb25zdCBTSU5HTEVfQ0hBTk5FTF9PUFRJT05TID0geyBjaGFubmVsQ291bnQ6IDEsIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyB9O1xuICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMgPSB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIG92ZXJzYW1wbGU6ICdub25lJyB9O1xuICAgIGNvbnN0IGJ1aWxkSW50ZXJuYWxHcmFwaEZvck1vbm8gPSAobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCByaWdodFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQ1VSVkVfU0laRTsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCB4ID0gKGkgLyAoQ1VSVkVfU0laRSAtIDEpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICBsZWZ0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5jb3MoeCk7XG4gICAgICAgICAgICByaWdodFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguc2luKHgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxlZnRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgbGVmdFdhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IGxlZnRXYXZlU2hhcGVyQ3VydmUgfSkpO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBwYW5XYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiBEQ19DVVJWRSB9KSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHJpZ2h0V2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogcmlnaHRXYXZlU2hhcGVyQ3VydmUgfSkpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChsZWZ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocmlnaHRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChsZWZ0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBsZWZ0V2F2ZVNoYXBlck5vZGUgOiBsZWZ0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyByaWdodFdhdmVTaGFwZXJOb2RlIDogcmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGxlZnRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KGxlZnRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGxlZnRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IGxlZnRXYXZlU2hhcGVyTm9kZSA6IGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHJpZ2h0V2F2ZVNoYXBlck5vZGUgOiByaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QobGVmdEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoRm9yU3RlcmVvID0gKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IGNlbnRlckluZGV4ID0gTWF0aC5mbG9vcihDVVJWRV9TSVpFIC8gMik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQ1VSVkVfU0laRTsgaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAoaSA+IGNlbnRlckluZGV4KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeCA9ICgoaSAtIGNlbnRlckluZGV4KSAvIChDVVJWRV9TSVpFIC0gMSAtIGNlbnRlckluZGV4KSkgKiBIQUxGX1BJO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguc2luKHgpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMDtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeCA9IChpIC8gKENVUlZFX1NJWkUgLSAxIC0gY2VudGVySW5kZXgpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDE7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAwO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5jb3MoeCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogMlxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBwYW5XYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiBEQ19DVVJWRSB9KSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLFxuICAgICAgICAgICAgY3VydmU6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5jb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGNvbnN0IGJ1aWxkSW50ZXJuYWxHcmFwaCA9IChuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICBpZiAoY2hhbm5lbENvdW50ID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gYnVpbGRJbnRlcm5hbEdyYXBoRm9yTW9ubyhuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFubmVsQ291bnQgPT09IDIpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZEludGVybmFsR3JhcGhGb3JTdGVyZW8obmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgIH07XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50TW9kZSwgcGFuLCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uYXVkaW9Ob2RlT3B0aW9ucyxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBudW1iZXJPZklucHV0czogMlxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnRNb2RlLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBwYW5HYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiBwYW5cbiAgICAgICAgfSk7XG4gICAgICAgIGxldCB7IGNvbm5lY3RHcmFwaCwgZGlzY29ubmVjdEdyYXBoIH0gPSBidWlsZEludGVybmFsR3JhcGgobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFuR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFuR2Fpbk5vZGUuZ2FpbiwgJ21heFZhbHVlJywgeyBnZXQ6ICgpID0+IDEgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnbWluVmFsdWUnLCB7IGdldDogKCkgPT4gLTEgfSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKHsgY29ubmVjdEdyYXBoLCBkaXNjb25uZWN0R3JhcGggfSA9IGJ1aWxkSW50ZXJuYWxHcmFwaChuYXRpdmVDb250ZXh0LCB2YWx1ZSwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnY2xhbXBlZC1tYXgnIHx8IHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFuR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5LCBjaGFubmVsTWVyZ2VyTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgY29ycmVjdGx5IG1hcCB0aGUgdmFsdWVzLlxuICAgICAgICAgKiBAdG9kbyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGlzIG5vIHdheSB0byB0ZXN0IGZvciB0aGlzIGJlaGF2aW9yIGluIGEgc3luY2hyb25vdXMgZmFzaGlvbiB3aGljaCBpcyB3aHkgdGVzdGluZyBmb3IgdGhlIGV4aXN0ZW5jZSBvZlxuICAgICAgICAgKiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuIFRlc3RpbmcgZm9yIHRoZSBhdXRvbWF0aW9uUmF0ZSBwcm9wZXJ0eSBpcyBuZWNlc3NhcnkgYmVjYXVzZSB0aGlzIHdvcmthcm91bmRcbiAgICAgICAgICogaXNuJ3QgbmVjZXNzYXJ5IGFueW1vcmUgc2luY2UgdjE0LjAuMiBvZiBTYWZhcmkuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiZcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnICYmXG4gICAgICAgICAgICBuYXRpdmVDb250ZXh0LmNyZWF0ZUdhaW4oKS5nYWluLmF1dG9tYXRpb25SYXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBjdXJ2ZSA9IG9wdGlvbnMuY3VydmUgPT09IG51bGwgfHwgb3B0aW9ucy5jdXJ2ZSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IG9wdGlvbnMuY3VydmUgOiBuZXcgRmxvYXQzMkFycmF5KG9wdGlvbnMuY3VydmUpO1xuICAgICAgICAvLyBCdWcgIzEwNDogQ2hyb21lIGFuZCBFZGdlIHdpbGwgdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgIGlmIChjdXJ2ZSAhPT0gbnVsbCAmJiBjdXJ2ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE9ubHkgdmFsdWVzIG9mIHR5cGUgRmxvYXQzMkFycmF5IGNhbiBiZSBhc3NpZ25lZCB0byB0aGUgY3VydmUgcHJvcGVydHkuXG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVXYXZlU2hhcGVyTm9kZSwgeyBjdXJ2ZSB9LCAnY3VydmUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBvcHRpb25zLCAnb3ZlcnNhbXBsZScpO1xuICAgICAgICBsZXQgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsICdjdXJ2ZScsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKG5hdGl2ZVdhdmVTaGFwZXJOb2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChuYXRpdmVXYXZlU2hhcGVyTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRENDdXJ2ZSh2YWx1ZSkgJiYgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIWlzRENDdXJ2ZSh2YWx1ZSkgJiYgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlKSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGN1cnZlLCBvdmVyc2FtcGxlLCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICBjb25zdCBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IGludmVydEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAtMSB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IHJldmVydEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAtMSB9KTtcbiAgICAgICAgbGV0IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgbGV0IHVubW9kaWZpZWRDdXJ2ZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICByZXZlcnRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICByZXZlcnRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bm1vZGlmaWVkQ3VydmU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGN1cnZlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDI6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnZlTGVuZ3RoID0gdmFsdWUubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZWdhdGl2ZUN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShjdXJ2ZUxlbmd0aCArIDIgLSAoY3VydmVMZW5ndGggJSAyKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aXZlQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KGN1cnZlTGVuZ3RoICsgMiAtIChjdXJ2ZUxlbmd0aCAlIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVswXSA9IHZhbHVlWzBdO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZUN1cnZlWzBdID0gLXZhbHVlW2N1cnZlTGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IE1hdGguY2VpbCgoY3VydmVMZW5ndGggKyAxKSAvIDIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjZW50ZXJJbmRleCA9IChjdXJ2ZUxlbmd0aCArIDEpIC8gMiAtIDE7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRoZW9yZXRpY0luZGV4ID0gKGkgLyBsZW5ndGgpICogY2VudGVySW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb3dlckluZGV4ID0gTWF0aC5mbG9vcih0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlQ3VydmVbaV0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VySW5kZXggPT09IHVwcGVySW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZVtsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogdmFsdWVbbG93ZXJJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgLSAodXBwZXJJbmRleCAtIHRoZW9yZXRpY0luZGV4KSkgKiB2YWx1ZVt1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlQ3VydmVbaV0gPVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvd2VySW5kZXggPT09IHVwcGVySW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAtdmFsdWVbY3VydmVMZW5ndGggLSAxIC0gbG93ZXJJbmRleF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAtKCgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogdmFsdWVbY3VydmVMZW5ndGggLSAxIC0gbG93ZXJJbmRleF0pIC1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIC0gKHVwcGVySW5kZXggLSB0aGVvcmV0aWNJbmRleCkpICogdmFsdWVbY3VydmVMZW5ndGggLSAxIC0gdXBwZXJJbmRleF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVtsZW5ndGhdID0gY3VydmVMZW5ndGggJSAyID09PSAxID8gdmFsdWVbbGVuZ3RoIC0gMV0gOiAodmFsdWVbbGVuZ3RoIC0gMl0gKyB2YWx1ZVtsZW5ndGggLSAxXSkgLyAyO1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gbmVnYXRpdmVDdXJ2ZTtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHBvc2l0aXZlQ3VydmU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHVubW9kaWZpZWRDdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHVubW9kaWZpZWRDdXJ2ZSkgJiYgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbaW5wdXRHYWluTm9kZV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IG92ZXJzYW1wbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGN1cnZlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBPbmx5IHZhbHVlcyBvZiB0eXBlIEZsb2F0MzJBcnJheSBjYW4gYmUgYXNzaWduZWQgdG8gdGhlIGN1cnZlIHByb3BlcnR5LlxuICAgICAgICAgICAgbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlci5jdXJ2ZSA9IGN1cnZlIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gY3VydmUgOiBuZXcgRmxvYXQzMkFycmF5KGN1cnZlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3ZlcnNhbXBsZSAhPT0gbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlci5vdmVyc2FtcGxlKSB7XG4gICAgICAgICAgICBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSkuY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QoaW52ZXJ0R2Fpbk5vZGUpLmNvbm5lY3QocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSkuY29ubmVjdChyZXZlcnRHYWluTm9kZSkuY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHVubW9kaWZpZWRDdXJ2ZSkpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChpbnZlcnRHYWluTm9kZSk7XG4gICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5kaXNjb25uZWN0KHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJldmVydEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmRpc2Nvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIG91dHB1dEdhaW5Ob2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdOb3RTdXBwb3J0ZWRFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bm90LXN1cHBvcnRlZC1lcnJvci5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQXVkaW9HcmFwaCB9IGZyb20gJy4uL2hlbHBlcnMvZGVhY3RpdmF0ZS1hdWRpby1ncmFwaCc7XG5pbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBudW1iZXJPZkNoYW5uZWxzOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHN0YXJ0UmVuZGVyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE9mZmxpbmVBdWRpb0NvbnRleHQgZXh0ZW5kcyBiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihhLCBiLCBjKSB7XG4gICAgICAgICAgICBsZXQgb3B0aW9ucztcbiAgICAgICAgICAgIGlmICh0eXBlb2YgYSA9PT0gJ251bWJlcicgJiYgYiAhPT0gdW5kZWZpbmVkICYmIGMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSB7IGxlbmd0aDogYiwgbnVtYmVyT2ZDaGFubmVsczogYSwgc2FtcGxlUmF0ZTogYyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGEgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBnaXZlbiBwYXJhbWV0ZXJzIGFyZSBub3QgdmFsaWQuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyAjMjEgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgYW5kIHRoZXJlZm9yZSB3b3VsZCBmaXJlIHRoZSBzdGF0ZWNoYW5nZSBldmVudCBiZWZvcmUgdGhlIHByb21pc2UgY2FuIGJlIHJlc29sdmVkLlxuICAgICAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsICgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50ID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgZGVsYXlTdGF0ZUNoYW5nZUV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlbGF5U3RhdGVDaGFuZ2VFdmVudDtcbiAgICAgICAgICAgICAgICB9KSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbGVuZ3RoID0gbGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlID09PSBudWxsID8gdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGF0ZSA6IHRoaXMuX3N0YXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0UmVuZGVyaW5nKCkge1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOSAmICM1OTogSXQgaXMgdGhlb3JldGljYWxseSBwb3NzaWJsZSB0aGF0IHN0YXJ0UmVuZGVyaW5nKCkgd2lsbCBmaXJzdCByZW5kZXIgYSBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC4gVGhlcmVmb3JlXG4gICAgICAgICAgICAgKiB0aGUgc3RhdGUgb2YgdGhlIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgbWlnaHQgbm8gdHJhbnNpdGlvbiB0byBydW5uaW5nIGltbWVkaWF0ZWx5LlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3J1bm5pbmcnO1xuICAgICAgICAgICAgcmV0dXJuIHN0YXJ0UmVuZGVyaW5nKHRoaXMuZGVzdGluYXRpb24sIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIF93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLl93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRldHVuZTogMCxcbiAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICBwZXJpb2RpY1dhdmU6IHVuZGVmaW5lZCxcbiAgICB0eXBlOiAnc2luZSdcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgT3NjaWxsYXRvck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgb3NjaWxsYXRvck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIGNvbnN0IG55cXVpc3QgPSBjb250ZXh0LnNhbXBsZVJhdGUgLyAyO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvc2NpbGxhdG9yTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjODE6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2RldHVuZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUsIDE1MzYwMCwgLTE1MzYwMCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc2OiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeSwgbnlxdWlzdCwgLW55cXVpc3QpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVPc2NpbGxhdG9yTm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciA9IG9zY2lsbGF0b3JOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCAmJiBtZXJnZWRPcHRpb25zLnBlcmlvZGljV2F2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5wZXJpb2RpY1dhdmUgPVxuICAgICAgICAgICAgICAgICAgICBtZXJnZWRPcHRpb25zLnBlcmlvZGljV2F2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgZGV0dW5lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldHVuZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZnJlcXVlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25lbmRlZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbmVuZGVkKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUub25lbmRlZCA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uRW5kZWQgPSB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIGdldCB0eXBlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHR5cGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnR5cGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5wZXJpb2RpY1dhdmUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9IHBlcmlvZGljV2F2ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdGFydCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIuc3RhcnQgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3Aod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIuc3RvcCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9zY2lsbGF0b3Itbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBwZXJpb2RpY1dhdmUgPSBudWxsO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZU9zY2lsbGF0b3JOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVPc2NpbGxhdG9yTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZU9zY2lsbGF0b3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlT3NjaWxsYXRvck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGV0dW5lOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeTogbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmU6IHBlcmlvZGljV2F2ZSA9PT0gbnVsbCA/IHVuZGVmaW5lZCA6IHBlcmlvZGljV2F2ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoc3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZU9zY2lsbGF0b3JOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmZyZXF1ZW5jeSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlT3NjaWxsYXRvck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgcGVyaW9kaWNXYXZlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RvcCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0b3AgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU9zY2lsbGF0b3JOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9zY2lsbGF0b3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdjbGFtcGVkLW1heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGNvbmVJbm5lckFuZ2xlOiAzNjAsXG4gICAgY29uZU91dGVyQW5nbGU6IDM2MCxcbiAgICBjb25lT3V0ZXJHYWluOiAwLFxuICAgIGRpc3RhbmNlTW9kZWw6ICdpbnZlcnNlJyxcbiAgICBtYXhEaXN0YW5jZTogMTAwMDAsXG4gICAgb3JpZW50YXRpb25YOiAxLFxuICAgIG9yaWVudGF0aW9uWTogMCxcbiAgICBvcmllbnRhdGlvblo6IDAsXG4gICAgcGFubmluZ01vZGVsOiAnZXF1YWxwb3dlcicsXG4gICAgcG9zaXRpb25YOiAwLFxuICAgIHBvc2l0aW9uWTogMCxcbiAgICBwb3NpdGlvblo6IDAsXG4gICAgcmVmRGlzdGFuY2U6IDEsXG4gICAgcm9sbG9mZkZhY3RvcjogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBQYW5uZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBwYW5uZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVQYW5uZXJOb2RlLCBwYW5uZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZSA9IG5hdGl2ZVBhbm5lck5vZGU7XG4gICAgICAgICAgICAvLyBCdWcgIzc0OiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25YID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25ZID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb3JpZW50YXRpb25aID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25aLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25YID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25YLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25ZID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fcG9zaXRpb25aID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25aLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgLy8gQHRvZG8gRGV0ZXJtaW5lIGEgbWVhbmluZ2Z1bCB0YWlsLXRpbWUgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIG9uZSBzZWNvbmQuXG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29uZUlubmVyQW5nbGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZUlubmVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29uZU91dGVyQW5nbGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckdhaW47XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNvbmVPdXRlckdhaW4odmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkaXN0YW5jZU1vZGVsKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgZGlzdGFuY2VNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1heERpc3RhbmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG1heERpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLm1heERpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9yaWVudGF0aW9uWCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9yaWVudGF0aW9uWSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9yaWVudGF0aW9uWigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcmllbnRhdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnBhbm5pbmdNb2RlbDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgcGFubmluZ01vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnBhbm5pbmdNb2RlbCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3NpdGlvblgoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3NpdGlvblkoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25ZO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGdldCByZWZEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIHNldCByZWZEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yZWZEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucm9sbG9mZkZhY3RvcjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgcm9sbG9mZkZhY3Rvcih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCByZW5kZXJlZEJ1ZmZlclByb21pc2UgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVHYWluTm9kZSA9IG51bGw7XG4gICAgICAgICAgICBsZXQgbmF0aXZlUGFubmVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICBjb25zdCBjb21tb25BdWRpb05vZGVPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlUGFubmVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlUGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlUGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb25cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgIGNvbmVJbm5lckFuZ2xlOiBuYXRpdmVQYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlLFxuICAgICAgICAgICAgICAgIGNvbmVPdXRlckFuZ2xlOiBuYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlLFxuICAgICAgICAgICAgICAgIGNvbmVPdXRlckdhaW46IG5hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbixcbiAgICAgICAgICAgICAgICBkaXN0YW5jZU1vZGVsOiBuYXRpdmVQYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWwsXG4gICAgICAgICAgICAgICAgbWF4RGlzdGFuY2U6IG5hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2UsXG4gICAgICAgICAgICAgICAgcGFubmluZ01vZGVsOiBuYXRpdmVQYW5uZXJOb2RlLnBhbm5pbmdNb2RlbCxcbiAgICAgICAgICAgICAgICByZWZEaXN0YW5jZTogbmF0aXZlUGFubmVyTm9kZS5yZWZEaXN0YW5jZSxcbiAgICAgICAgICAgICAgICByb2xsb2ZmRmFjdG9yOiBuYXRpdmVQYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3JcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlUGFubmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVBhbm5lck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVQYW5uZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTI0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZnlpbmcgdGhlIG9yaWVudGF0aW9uIGFuZCB0aGUgcG9zaXRpb24gd2l0aCBBdWRpb1BhcmFtcy5cbiAgICAgICAgICAgIGlmICgnYnVmZmVyU2l6ZScgaW4gbmF0aXZlUGFubmVyTm9kZSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZVBhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWDogbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWTogbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblkudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvbloudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblkudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvbloudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVHYWluTm9kZSA9PT0gbnVsbCA/IG5hdGl2ZVBhbm5lck5vZGUgOiBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBpZiAobmF0aXZlR2Fpbk5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDYsIFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgICAgICAgICBwcm94eS5jb250ZXh0Lmxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA2XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyZWRCdWZmZXJQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMgPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkub3JpZW50YXRpb25YLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5Lm9yaWVudGF0aW9uWSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5vcmllbnRhdGlvblosXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkucG9zaXRpb25YLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5LnBvc2l0aW9uWSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3NpdGlvblpcbiAgICAgICAgICAgICAgICAgICAgICAgIF0ubWFwKGFzeW5jIChhdWRpb1BhcmFtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBpbmRleCA9PT0gMCA/IDEgOiAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNjsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlc1tpXS5jb25uZWN0KG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzW2ldLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZEJ1ZmZlciA9IGF3YWl0IHJlbmRlcmVkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBpbnB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlbmRlcmVkQnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsRGF0YXMucHVzaChyZW5kZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBsYXN0T3JpZW50YXRpb24gPSBbY2hhbm5lbERhdGFzWzBdWzBdLCBjaGFubmVsRGF0YXNbMV1bMF0sIGNoYW5uZWxEYXRhc1syXVswXV07XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFtjaGFubmVsRGF0YXNbM11bMF0sIGNoYW5uZWxEYXRhc1s0XVswXSwgY2hhbm5lbERhdGFzWzVdWzBdXTtcbiAgICAgICAgICAgICAgICBsZXQgZ2F0ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICAgICAgICAgIGxldCBwYXJ0aWFsUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAuLi5jb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBsYXN0T3JpZW50YXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWTogbGFzdE9yaWVudGF0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblo6IGxhc3RPcmllbnRhdGlvblsyXSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBsYXN0UG9zaXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogbGFzdFBvc2l0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblo6IGxhc3RQb3NpdGlvblsyXVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChnYXRlR2Fpbk5vZGUpLmNvbm5lY3QocGFydGlhbFBhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsUGFubmVyTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTI4OyBpIDwgcmVuZGVyZWRCdWZmZXIubGVuZ3RoOyBpICs9IDEyOCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvcmllbnRhdGlvbiA9IFtjaGFubmVsRGF0YXNbMF1baV0sIGNoYW5uZWxEYXRhc1sxXVtpXSwgY2hhbm5lbERhdGFzWzJdW2ldXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRvbiA9IFtjaGFubmVsRGF0YXNbM11baV0sIGNoYW5uZWxEYXRhc1s0XVtpXSwgY2hhbm5lbERhdGFzWzVdW2ldXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdG9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbiA9IHBvc2l0b247XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGkgLyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRlR2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWDogbGFzdE9yaWVudGF0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWTogbGFzdE9yaWVudGF0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbGFzdE9yaWVudGF0aW9uWzJdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogbGFzdFBvc2l0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWTogbGFzdFBvc2l0aW9uWzFdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbGFzdFBvc2l0aW9uWzJdXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDEsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChnYXRlR2Fpbk5vZGUpLmNvbm5lY3QocGFydGlhbFBhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVHYWluTm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblosIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25aKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblosIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25aKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblkpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblopO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWCwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblkpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlUGFubmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVBhbm5lck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVBhbm5lck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVHYWluTm9kZU9yTmF0aXZlUGFubmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVHYWluTm9kZU9yTmF0aXZlUGFubmVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgZGlzYWJsZU5vcm1hbGl6YXRpb246IGZhbHNlXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yID0gKGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZSwgZ2V0TmF0aXZlQ29udGV4dCwgcGVyaW9kaWNXYXZlU3RvcmUsIHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucykgPT4ge1xuICAgIHJldHVybiBjbGFzcyBQZXJpb2RpY1dhdmUge1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMoeyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfSk7XG4gICAgICAgICAgICBjb25zdCBwZXJpb2RpY1dhdmUgPSBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBwZXJpb2RpY1dhdmVTdG9yZS5hZGQocGVyaW9kaWNXYXZlKTtcbiAgICAgICAgICAgIC8vIFRoaXMgZG9lcyB2aW9sYXRlIGFsbCBnb29kIHByYXRpY2VzIGJ1dCBpdCBpcyB1c2VkIGhlcmUgdG8gc2ltcGxpZnkgdGhlIGhhbmRsaW5nIG9mIHBlcmlvZGljIHdhdmVzLlxuICAgICAgICAgICAgcmV0dXJuIHBlcmlvZGljV2F2ZTtcbiAgICAgICAgfVxuICAgICAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0oaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHJldHVybiAoKGluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiBpbnN0YW5jZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGluc3RhbmNlKSA9PT0gUGVyaW9kaWNXYXZlLnByb3RvdHlwZSkgfHxcbiAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmVTdG9yZS5oYXMoaW5zdGFuY2UpKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGVyaW9kaWMtd2F2ZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlUmVuZGVyQXV0b21hdGlvbiA9IChnZXRBdWRpb1BhcmFtUmVuZGVyZXIsIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgbmF0aXZlQXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtUmVuZGVyZXIgPSBnZXRBdWRpb1BhcmFtUmVuZGVyZXIoYXVkaW9QYXJhbSk7XG4gICAgICAgIGF1ZGlvUGFyYW1SZW5kZXJlci5yZXBsYXkobmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgIHJldHVybiByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oYXVkaW9QYXJhbSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW5kZXItYXV0b21hdGlvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb05vZGUgPSAoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBpc1BhcnRPZkFDeWNsZSkgPT4ge1xuICAgIHJldHVybiBhc3luYyAoYXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChhdWRpb05vZGVDb25uZWN0aW9ucy5hY3RpdmVJbnB1dHNcbiAgICAgICAgICAgIC5tYXAoKGNvbm5lY3Rpb25zLCBpbnB1dCkgPT4gQXJyYXkuZnJvbShjb25uZWN0aW9ucykubWFwKGFzeW5jIChbc291cmNlLCBvdXRwdXRdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhdWRpb05vZGVSZW5kZXJlciA9IGdldEF1ZGlvTm9kZVJlbmRlcmVyKHNvdXJjZSk7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IGF3YWl0IGF1ZGlvTm9kZVJlbmRlcmVyLnJlbmRlcihzb3VyY2UsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZGVzdGluYXRpb24gPSBhdWRpb05vZGUuY29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgICAgIGlmICghaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSAmJiAoYXVkaW9Ob2RlICE9PSBkZXN0aW5hdGlvbiB8fCAhaXNQYXJ0T2ZBQ3ljbGUoYXVkaW9Ob2RlKSkpIHtcbiAgICAgICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKVxuICAgICAgICAgICAgLnJlZHVjZSgoYWxsUmVuZGVyaW5nUHJvbWlzZXMsIHJlbmRlcmluZ1Byb21pc2VzKSA9PiBbLi4uYWxsUmVuZGVyaW5nUHJvbWlzZXMsIC4uLnJlbmRlcmluZ1Byb21pc2VzXSwgW10pKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1pbnB1dHMtb2YtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtID0gKGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMsIGlzUGFydE9mQUN5Y2xlKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChhdWRpb1BhcmFtLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoQXJyYXkuZnJvbShhdWRpb1BhcmFtQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzKS5tYXAoYXN5bmMgKFtzb3VyY2UsIG91dHB1dF0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvTm9kZVJlbmRlcmVyID0gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gYXdhaXQgYXVkaW9Ob2RlUmVuZGVyZXIucmVuZGVyKHNvdXJjZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1pbnB1dHMtb2YtYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5leHBvcnQgY29uc3QgY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCB0ZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIGlmIChjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE1ODogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBhZHZhbmNlIGN1cnJlbnRUaW1lIGlmIGl0IGlzIG5vdCBhY2Nlc3NlZCB3aGlsZSByZW5kZXJpbmcgdGhlIGF1ZGlvLlxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjYWNoZVRlc3RSZXN1bHQodGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQsIHRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KSkudGhlbigoaXNPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ZWQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIDUxMiwgMCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSBudWxsOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICgpID0+IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3VycmVudFRpbWU7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jb25uZWN0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAvLyBCdWcgIzQ4OiBTYWZhcmkgZG9lcyBub3QgcmVuZGVyIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aG91dCBhbnkgY29ubmVjdGVkIG5vZGUuXG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lm9uY29tcGxldGUgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShldmVudC5yZW5kZXJlZEJ1ZmZlcik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZ2Fpbk5vZGUuY29ubmVjdChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW5kZXItbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlU2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IChhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFjdGl2ZUlucHV0cykgPT4ge1xuICAgICAgICBhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUuc2V0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGFjdGl2ZUlucHV0cyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lID0gKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgdGFpbFRpbWUpID0+IGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUuc2V0KGF1ZGlvTm9kZSwgdGFpbFRpbWUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1hdWRpby1ub2RlLXRhaWwtdGltZS5qcy5tYXAiLCJpbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcywgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoZGVzdGluYXRpb24pXG4gICAgICAgIC5yZW5kZXIoZGVzdGluYXRpb24sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpXG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjODYgJiAjODc6IEludm9raW5nIHRoZSByZW5kZXJlciBvZiBhbiBBdWRpb1dvcmtsZXROb2RlIG1pZ2h0IGJlIG5lY2Vzc2FyeSBpZiBpdCBoYXMgbm8gZGlyZWN0IG9yIGluZGlyZWN0IGNvbm5lY3Rpb24gdG8gdGhlXG4gICAgICAgICAqIGRlc3RpbmF0aW9uLlxuICAgICAgICAgKi9cbiAgICAgICAgLnRoZW4oKCkgPT4gUHJvbWlzZS5hbGwoQXJyYXkuZnJvbShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpLm1hcCgoYXVkaW9Xb3JrbGV0Tm9kZSkgPT4gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoYXVkaW9Xb3JrbGV0Tm9kZSkucmVuZGVyKGF1ZGlvV29ya2xldE5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKSkpXG4gICAgICAgIC50aGVuKCgpID0+IHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpXG4gICAgICAgIC50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgICAgIC8vIEJ1ZyAjMTAwOiBTYWZhcmkgZG9lcyB0aHJvdyBhIHdyb25nIGVycm9yIHdoZW4gY2FsbGluZyBnZXRDaGFubmVsRGF0YSgpIHdpdGggYW4gb3V0LW9mLWJvdW5kcyB2YWx1ZS5cbiAgICAgICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NzogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0aGUgYnVmZmVyT2Zmc2V0IHRvIGJlIG91dC1vZi1ib3VuZHMuXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RhcnQtcmVuZGVyaW5nLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgLypcbiAgICAgKiBCdWcgIzEwNTogVGhlIGNoYW5uZWxDb3VudE1vZGUgc2hvdWxkIGJlICdjbGFtcGVkLW1heCcgYWNjb3JkaW5nIHRvIHRoZSBzcGVjIGJ1dCBpcyBzZXQgdG8gJ2V4cGxpY2l0JyB0byBhY2hpZXZlIGNvbnNpc3RlbnRcbiAgICAgKiBiZWhhdmlvci5cbiAgICAgKi9cbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBwYW46IDBcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBTdGVyZW9QYW5uZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBzdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBzdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fcGFuID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFuKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhbjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBwYW46IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVTdGVyZW9QYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGFuLCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLnBhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wYW4sIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RlcmVvLXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiLy8gQnVnICMzMzogU2FmYXJpIGV4cG9zZXMgYW4gQXVkaW9CdWZmZXIgYnV0IGl0IGNhbid0IGJlIHVzZWQgYXMgYSBjb25zdHJ1Y3Rvci5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQgPSAobmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG5ldyBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoOiAxLCBzYW1wbGVSYXRlOiA0NDEwMCB9KTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLXN1cHBvcnQuanMubWFwIiwiLy8gQnVnICMxNzk6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdG8gdHJhbnNmZXIgYW55IGJ1ZmZlciB3aGljaCBoYXMgYmVlbiBwYXNzZWQgdG8gdGhlIHByb2Nlc3MoKSBtZXRob2QgYXMgYW4gYXJndW1lbnQuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCA9IChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNjE6IElmIHRoZXJlIGlzIG5vIG5hdGl2ZSBBdWRpb1dvcmtsZXROb2RlIGl0IGdldHMgZmFrZWQgYW5kIHRoZXJlZm9yZSBpdCBpcyBubyBwcm9ibGVtIGlmIHRoZSBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFsnY2xhc3MgQSBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3Nvcntwcm9jZXNzKGkpe3RoaXMucG9ydC5wb3N0TWVzc2FnZShpLFtpWzBdWzBdLmJ1ZmZlcl0pfX1yZWdpc3RlclByb2Nlc3NvcihcImFcIixBKSddLCB7XG4gICAgICAgICAgICB0eXBlOiAnYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCdcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTQxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjcmVhdGluZyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGggbGVzcyB0aGFuIDQ0MTAwIEh6LlxuICAgICAgICBjb25zdCBvZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxMjgsIDQ0MTAwKTtcbiAgICAgICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgbGV0IGlzRW1pdHRpbmdNZXNzYWdlRXZlbnRzID0gZmFsc2U7XG4gICAgICAgIGxldCBpc0VtaXR0aW5nUHJvY2Vzc29yRXJyb3JFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IG9mZmxpbmVBdWRpb0NvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZSh1cmwpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3Iob2ZmbGluZUF1ZGlvQ29udGV4dCwgJ2EnLCB7IG51bWJlck9mT3V0cHV0czogMCB9KTtcbiAgICAgICAgICAgIGNvbnN0IG9zY2lsbGF0b3IgPSBvZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgICAgIGF1ZGlvV29ya2xldE5vZGUucG9ydC5vbm1lc3NhZ2UgPSAoKSA9PiAoaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgPSB0cnVlKTtcbiAgICAgICAgICAgIGF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvciA9ICgpID0+IChpc0VtaXR0aW5nUHJvY2Vzc29yRXJyb3JFdmVudHMgPSB0cnVlKTtcbiAgICAgICAgICAgIG9zY2lsbGF0b3IuY29ubmVjdChhdWRpb1dvcmtsZXROb2RlKTtcbiAgICAgICAgICAgIG9zY2lsbGF0b3Iuc3RhcnQoMCk7XG4gICAgICAgICAgICBhd2FpdCBvZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgJiYgIWlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cztcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcG9zdC1tZXNzYWdlLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ID0gKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxLCA0NDEwMCk7XG4gICAgICAgIC8vIEJ1ZyAjNDg6IFNhZmFyaSBkb2VzIG5vdCByZW5kZXIgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRob3V0IGFueSBjb25uZWN0ZWQgbm9kZS5cbiAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogMFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMyMTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgeWV0LlxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmN1cnJlbnRUaW1lICE9PSAwKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY3VycmVudC10aW1lLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVVua25vd25FcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdVbmtub3duRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXVua25vd24tZXJyb3IuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgY3VydmU6IG51bGwsXG4gICAgb3ZlcnNhbXBsZTogJ25vbmUnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBXYXZlU2hhcGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCB3YXZlU2hhcGVyTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgLy8gQHRvZG8gQWRkIGEgbWVjaGFuaXNtIHRvIG9ubHkgc3dpdGNoIGEgV2F2ZVNoYXBlck5vZGUgdG8gYWN0aXZlIHdoaWxlIGl0IGlzIGNvbm5lY3RlZC5cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB3YXZlU2hhcGVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlV2F2ZVNoYXBlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0N1cnZlTnVsbGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGN1cnZlKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzEwMzogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHNldCB0aGUgY3VydmUgdG8gbnVsbC5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShbMCwgMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDI6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTA0OiBDaHJvbWUgYW5kIEVkZ2Ugd2lsbCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9pc0N1cnZlTnVsbGlmaWVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvdmVyc2FtcGxlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdmUtc2hhcGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVXYXZlU2hhcGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlV2F2ZVNoYXBlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVXYXZlU2hhcGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlV2F2ZVNoYXBlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBjdXJ2ZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJzYW1wbGU6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlV2F2ZVNoYXBlck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVdhdmVTaGFwZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVXYXZlU2hhcGVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13YXZlLXNoYXBlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdpbmRvdyA9ICgpID0+ICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiB3aW5kb3cpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2luZG93LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgPSAoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nLCBjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsID0gKGRlc3RpbmF0aW9uLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgIGlmIChjaGFubmVsTnVtYmVyID49IGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJMZW5ndGggPSBhdWRpb0J1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgZGVzdGluYXRpb25MZW5ndGggPSBkZXN0aW5hdGlvbi5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gYnVmZmVyT2Zmc2V0IDwgMCA/IC1idWZmZXJPZmZzZXQgOiAwOyBpICsgYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXJMZW5ndGggJiYgaSA8IGRlc3RpbmF0aW9uTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbltpXSA9IGNoYW5uZWxEYXRhW2kgKyBidWZmZXJPZmZzZXRdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID0gKHNvdXJjZSwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTnVtYmVyID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGNoYW5uZWxOdW1iZXJBc051bWJlcik7XG4gICAgICAgICAgICBpZiAoY2hhbm5lbE51bWJlciA+PSBhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyTGVuZ3RoID0gYXVkaW9CdWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUxlbmd0aCA9IHNvdXJjZS5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gYnVmZmVyT2Zmc2V0IDwgMCA/IC1idWZmZXJPZmZzZXQgOiAwOyBpICsgYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXJMZW5ndGggJiYgaSA8IHNvdXJjZUxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbERhdGFbaSArIGJ1ZmZlck9mZnNldF0gPSBzb3VyY2VbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMgPSAoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPSAoKGNvcHlGcm9tQ2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5RnJvbUNoYW5uZWwuY2FsbChhdWRpb0J1ZmZlciwgZGVzdGluYXRpb24sIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsKTtcbiAgICAgICAgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCA9ICgoY29weVRvQ2hhbm5lbCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIChzb3VyY2UsIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsTnVtYmVyID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGNoYW5uZWxOdW1iZXJBc051bWJlcik7XG4gICAgICAgICAgICAgICAgaWYgKGJ1ZmZlck9mZnNldCA8IGF1ZGlvQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29weVRvQ2hhbm5lbC5jYWxsKGF1ZGlvQnVmZmVyLCBzb3VyY2UsIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkoYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlciA9IChvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBudWxsaWZpZWRCdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCA0NDEwMCk7XG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbnVsbGlmaWVkQnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsICdidWZmZXInLCAoZ2V0KSA9PiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gdmFsdWUgPT09IG51bGxpZmllZEJ1ZmZlciA/IG51bGwgOiB2YWx1ZTtcbiAgICAgICAgfSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB2YWx1ZSA9PT0gbnVsbCA/IG51bGxpZmllZEJ1ZmZlciA6IHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUgPSAoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgLy8gQnVnICMxNTogU2FmYXJpIGRvZXMgbm90IHJldHVybiB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5jaGFubmVsQ291bnQgPSAxO1xuICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gJ2V4cGxpY2l0JztcbiAgICAgICAgLy8gQnVnICMxNjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gc2V0dGluZyBhIGRpZmZlcmVudCBjaGFubmVsQ291bnQgb3IgY2hhbm5lbENvdW50TW9kZS5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxNZXJnZXJOb2RlLCAnY2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiAxLFxuICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsTWVyZ2VyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMyMDogU2FmYXJpIHJlcXVpcmVzIGEgY29ubmVjdGlvbiBvZiBhbnkga2luZCB0byB0cmVhdCB0aGUgaW5wdXQgc2lnbmFsIGNvcnJlY3RseS5cbiAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGNoYW5uZWxNZXJnZXJOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IGF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgbW9uaXRvckNvbm5lY3Rpb25zKGNoYW5uZWxNZXJnZXJOb2RlLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtY2hhbm5lbC1tZXJnZXItbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgZ2V0Rmlyc3RTYW1wbGUgPSAoYXVkaW9CdWZmZXIsIGJ1ZmZlciwgY2hhbm5lbE51bWJlcikgPT4ge1xuICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICBpZiAoYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpWzBdO1xuICAgIH1cbiAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwoYnVmZmVyLCBjaGFubmVsTnVtYmVyKTtcbiAgICByZXR1cm4gYnVmZmVyWzBdO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1maXJzdC1zYW1wbGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzRENDdXJ2ZSA9IChjdXJ2ZSkgPT4ge1xuICAgIGlmIChjdXJ2ZSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGxlbmd0aCA9IGN1cnZlLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoICUgMiAhPT0gMCkge1xuICAgICAgICByZXR1cm4gY3VydmVbTWF0aC5mbG9vcihsZW5ndGggLyAyKV0gIT09IDA7XG4gICAgfVxuICAgIHJldHVybiBjdXJ2ZVtsZW5ndGggLyAyIC0gMV0gKyBjdXJ2ZVtsZW5ndGggLyAyXSAhPT0gMDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1kYy1jdXJ2ZS5qcy5tYXAiLCJleHBvcnQgY29uc3Qgb3ZlcndyaXRlQWNjZXNzb3JzID0gKG9iamVjdCwgcHJvcGVydHksIGNyZWF0ZUdldHRlciwgY3JlYXRlU2V0dGVyKSA9PiB7XG4gICAgbGV0IHByb3RvdHlwZSA9IG9iamVjdDtcbiAgICB3aGlsZSAoIXByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvdHlwZSk7XG4gICAgfVxuICAgIGNvbnN0IHsgZ2V0LCBzZXQgfSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocHJvdG90eXBlLCBwcm9wZXJ0eSk7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iamVjdCwgcHJvcGVydHksIHsgZ2V0OiBjcmVhdGVHZXR0ZXIoZ2V0KSwgc2V0OiBjcmVhdGVTZXR0ZXIoc2V0KSB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vdmVyd3JpdGUtYWNjZXNzb3JzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBvdXRwdXRDaGFubmVsQ291bnQ6IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50ICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnRcbiAgICAgICAgICAgIDogb3B0aW9ucy5udW1iZXJPZklucHV0cyA9PT0gMSAmJiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyA9PT0gMVxuICAgICAgICAgICAgICAgID8gLypcbiAgICAgICAgICAgICAgICAgICAqIEJ1ZyAjNjE6IFRoaXMgc2hvdWxkIGJlIHRoZSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMsIGJ1dCB1bmZvcnR1bmF0ZWx5IHRoYXQgaXMgYWxtb3N0IGltcG9zc2libGUgdG8gZmFrZS4gVGhhdCdzIHdoeVxuICAgICAgICAgICAgICAgICAgICogdGhlIGNoYW5uZWxDb3VudE1vZGUgaXMgcmVxdWlyZWQgdG8gYmUgJ2V4cGxpY2l0JyBhcyBsb25nIGFzIHRoZXJlIGlzIG5vdCBhIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBpbiBldmVyeSBicm93c2VyLiBUaGF0XG4gICAgICAgICAgICAgICAgICAgKiBtYWtlcyBzdXJlIHRoZSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgZXF1aXZpbGFudCB0byB0aGUgY2hhbm5lbENvdW50IHdoaWNoIG1ha2VzIGl0IG11Y2ggZWFzaWVyIHRvIGNvbXB1dGUuXG4gICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgW29wdGlvbnMuY2hhbm5lbENvdW50XVxuICAgICAgICAgICAgICAgIDogQXJyYXkuZnJvbSh7IGxlbmd0aDogb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfSwgKCkgPT4gMSlcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNhbml0aXplLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMgPSAob3B0aW9ucykgPT4ge1xuICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGNoYW5uZWxDb3VudDogb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgeyBpbWFnLCByZWFsIH0gPSBvcHRpb25zO1xuICAgIGlmIChpbWFnID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKHJlYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgaW1hZzogWzAsIDBdLCByZWFsOiBbMCwgMF0gfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnOiBBcnJheS5mcm9tKHJlYWwsICgpID0+IDApLCByZWFsIH07XG4gICAgfVxuICAgIGlmIChyZWFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgaW1hZywgcmVhbDogQXJyYXkuZnJvbShpbWFnLCAoKSA9PiAwKSB9O1xuICAgIH1cbiAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnLCByZWFsIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2FuaXRpemUtcGVyaW9kaWMtd2F2ZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUgPSAoYXVkaW9QYXJhbSwgdmFsdWUsIHN0YXJ0VGltZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKGVyci5jb2RlICE9PSA5KSB7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKGF1ZGlvUGFyYW0sIHZhbHVlLCBzdGFydFRpbWUgKyAxZS03KTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LXZhbHVlLWF0LXRpbWUtdW50aWwtcG9zc2libGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIDQ0MTAwKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXI7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KDAsIDEpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXItc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KC0xKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgUmFuZ2VFcnJvcjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgNDQxMDApO1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKC0xKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgUmFuZ2VFcnJvcjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHkgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yIGlmIHRoZSBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyBhcmUgbm90IGNsb25hYmxlLlxuICAgICAgICBwb3J0MS5wb3N0TWVzc2FnZShhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgfVxuICAgIGZpbmFsbHkge1xuICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLWNsb25hYmlsaXR5LmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZyA9IChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQgPSAoKHN0YXJ0KSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyO1xuICAgICAgICAgICAgLy8gQnVnICMxNTQ6IFNhZmFyaSBkb2VzIG5vdCBjbGFtcCB0aGUgb2Zmc2V0IGlmIGl0IGlzIGVxdWFsIHRvIG9yIGdyZWF0ZXIgdGhhbiB0aGUgZHVyYXRpb24gb2YgdGhlIGJ1ZmZlci5cbiAgICAgICAgICAgIGNvbnN0IGNsYW1wZWRPZmZzZXQgPSBidWZmZXIgPT09IG51bGwgPyBvZmZzZXQgOiBNYXRoLm1pbihidWZmZXIuZHVyYXRpb24sIG9mZnNldCk7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NTogU2FmYXJpIGRvZXMgbm90IGhhbmRsZSB0aGUgb2Zmc2V0IGNvcnJlY3RseSBpZiBpdCB3b3VsZCBjYXVzZSB0aGUgYnVmZmVyIHRvIGJlIG5vdCBiZSBwbGF5ZWQgYXQgYWxsLlxuICAgICAgICAgICAgaWYgKGJ1ZmZlciAhPT0gbnVsbCAmJiBjbGFtcGVkT2Zmc2V0ID4gYnVmZmVyLmR1cmF0aW9uIC0gMC41IC8gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbnRleHQuc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuLCAwLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0YXJ0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuLCBjbGFtcGVkT2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyA9IChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICBjb25zdCBkaXNjb25uZWN0R2Fpbk5vZGUgPSAoKGRpc2Nvbm5lY3QpID0+IHtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDEgYXJndW1lbnQgeWV0LlxuICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdEdhaW5Ob2RlKTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuZGlzY29ubmVjdCk7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdEdhaW5Ob2RlKTtcbiAgICBpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCA9ICgoc3RvcCkgPT4ge1xuICAgICAgICBsZXQgaXNTdG9wcGVkID0gZmFsc2U7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDApID0+IHtcbiAgICAgICAgICAgIGlmIChpc1N0b3BwZWQpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBzdG9wLmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHdoZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgICAgIGlzU3RvcHBlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3ApO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwRXZlbnRMaXN0ZW5lciA9ICh0YXJnZXQsIGV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gKGV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7IHZhbHVlOiB0YXJnZXQgfTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoZXZlbnQsIHtcbiAgICAgICAgICAgIGN1cnJlbnRUYXJnZXQ6IGRlc2NyaXB0b3IsXG4gICAgICAgICAgICB0YXJnZXQ6IGRlc2NyaXB0b3JcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlb2YgZXZlbnRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50TGlzdGVuZXIuY2FsbCh0YXJnZXQsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZXZlbnRMaXN0ZW5lci5oYW5kbGVFdmVudC5jYWxsKHRhcmdldCwgZXZlbnQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1ldmVudC1saXN0ZW5lci5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50IH0gZnJvbSAnYXV0b21hdGlvbi1ldmVudHMnO1xuaW1wb3J0IHsgY3JlYXRlQWJvcnRFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2Fib3J0LWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWF1ZGlvLXdvcmtsZXQtbW9kdWxlJztcbmltcG9ydCB7IGNyZWF0ZUFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUFkZFNpbGVudENvbm5lY3Rpb24gfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtc2lsZW50LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hbmFseXNlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tZGVzdGluYXRpb24tbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvTGlzdGVuZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tbGlzdGVuZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1wYXJhbS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLXJlbmRlcmVyJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2JpcXVhZC1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ2FjaGVUZXN0UmVzdWx0IH0gZnJvbSAnLi9mYWN0b3JpZXMvY2FjaGUtdGVzdC1yZXN1bHQnO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLW1lcmdlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1zcGxpdHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0QXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL2Nvbm5lY3QtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlQ29ubmVjdE11bHRpcGxlT3V0cHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdGVkLW5hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ29udmVydE51bWJlclRvVW5zaWduZWRMb25nIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29udmVydC1udW1iZXItdG8tdW5zaWduZWQtbG9uZyc7XG5pbXBvcnQgeyBjcmVhdGVDb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29udm9sdmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvY3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlRGF0YUNsb25lRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9kYXRhLWNsb25lLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZURlY29kZUF1ZGlvRGF0YSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlY29kZS1hdWRpby1kYXRhJztcbmltcG9ydCB7IGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlciB9IGZyb20gJy4vZmFjdG9yaWVzL2RlY3JlbWVudC1jeWNsZS1jb3VudGVyJztcbmltcG9ydCB7IGNyZWF0ZURlbGF5Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsYXktbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVEZWxheU5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxheS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlRGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGV0ZS11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVEZXRlY3RDeWNsZXMgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZXRlY3QtY3ljbGVzJztcbmltcG9ydCB7IGNyZWF0ZURpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9kaXNjb25uZWN0LW11bHRpcGxlLW91dHB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVFbmNvZGluZ0Vycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZW5jb2RpbmctZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlRXZhbHVhdGVTb3VyY2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9ldmFsdWF0ZS1zb3VyY2UnO1xuaW1wb3J0IHsgY3JlYXRlRXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2V2ZW50LXRhcmdldC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSB9IGZyb20gJy4vZmFjdG9yaWVzL2V4cG9zZS1jdXJyZW50LWZyYW1lLWFuZC1jdXJyZW50LXRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlRmV0Y2hTb3VyY2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9mZXRjaC1zb3VyY2UnO1xuaW1wb3J0IHsgY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2dhaW4tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVHYWluTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2dhaW4tbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYXVkaW8tbm9kZS1yZW5kZXJlcic7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb05vZGVUYWlsVGltZSB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXRhaWwtdGltZSc7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb1BhcmFtUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYXVkaW8tcGFyYW0tcmVuZGVyZXInO1xuaW1wb3J0IHsgY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtbmF0aXZlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LW9yLWNyZWF0ZS1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZXMnO1xuaW1wb3J0IHsgY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaWlyLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvaW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVJbmRleFNpemVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2luZGV4LXNpemUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaW52YWxpZC1hY2Nlc3MtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUlzQW55QXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlBdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueUF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtYW55LW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNTZWN1cmVDb250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtc2VjdXJlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNTdXBwb3J0ZWRQcm9taXNlIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtc3VwcG9ydGVkLXByb21pc2UnO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21pbmltYWwtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21pbmltYWwtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1vbml0b3JDb25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL21vbml0b3ItY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hbmFseXNlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWJpcXVhZC1maWx0ZXItbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY2hhbm5lbC1tZXJnZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY2hhbm5lbC1zcGxpdHRlci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1kZWxheS1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWdhaW4tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW9zY2lsbGF0b3Itbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc2NyaXB0LXByb2Nlc3Nvci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9ub3Qtc3VwcG9ydGVkLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL29mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvb3NjaWxsYXRvci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvb3NjaWxsYXRvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlUGFubmVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvcGFubmVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL3Bhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9wZXJpb2RpYy13YXZlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlckF1dG9tYXRpb24gfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItYXV0b21hdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvc2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzJztcbmltcG9ydCB7IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvc2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lJztcbmltcG9ydCB7IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nIH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RhcnQtcmVuZGVyaW5nJztcbmltcG9ydCB7IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3N0ZXJlby1wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1idWZmZXItY29uc3RydWN0b3Itc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNTdWJhcnJheVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1zdWJhcnJheS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRDbG9zZU1ldGhvZFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWNvbnRleHQtY2xvc2UtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dERlY29kZUF1ZGlvRGF0YU1ldGhvZFR5cGVFcnJvclN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWNvbnRleHQtZGVjb2RlLWF1ZGlvLWRhdGEtbWV0aG9kLXR5cGUtZXJyb3Itc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Db250ZXh0T3B0aW9uc1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWNvbnRleHQtb3B0aW9ucy1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb05vZGVDb25uZWN0TWV0aG9kU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tbm9kZS1jb25uZWN0LW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JOb091dHB1dHNTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1uby1vdXRwdXRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcG9zdC1tZXNzYWdlLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdENoYW5uZWxNZXJnZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY2hhbm5lbC1tZXJnZXItbm9kZS1jaGFubmVsLWNvdW50LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdENvbnN0YW50U291cmNlTm9kZUFjY3VyYXRlU2NoZWR1bGluZ1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNvbnN0YW50LXNvdXJjZS1ub2RlLWFjY3VyYXRlLXNjaGVkdWxpbmctc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUJ1ZmZlclJlYXNzaWduYWJpbGl0eVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNvbnZvbHZlci1ub2RlLWJ1ZmZlci1yZWFzc2lnbmFiaWxpdHktc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUNoYW5uZWxDb3VudFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNvbnZvbHZlci1ub2RlLWNoYW5uZWwtY291bnQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0SXNTZWN1cmVDb250ZXh0U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtaXMtc2VjdXJlLWNvbnRleHQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0TWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVNZWRpYVN0cmVhbVdpdGhvdXRBdWRpb1RyYWNrU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLW1lZGlhLXN0cmVhbS13aXRob3V0LWF1ZGlvLXRyYWNrLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LW9mZmxpbmUtYXVkaW8tY29udGV4dC1jdXJyZW50LXRpbWUtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0U3RlcmVvUGFubmVyTm9kZURlZmF1bHRWYWx1ZVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LXN0ZXJlby1wYW5uZXItbm9kZS1kZWZhdWx0LXZhbHVlLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVW5rbm93bkVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvdW5rbm93bi1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVXYXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL3dhdmUtc2hhcGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVXaW5kb3cgfSBmcm9tICcuL2ZhY3Rvcmllcy93aW5kb3cnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzIH0gZnJvbSAnLi9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzJztcbmltcG9ydCB7IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlcic7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWNoYW5uZWwtbWVyZ2VyLW5vZGUnO1xuaW1wb3J0IHsgQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSwgQVVESU9fTk9ERV9TVE9SRSwgQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUsIEFVRElPX1BBUkFNX1NUT1JFLCBDT05URVhUX1NUT1JFLCBDWUNMRV9DT1VOVEVSUyB9IGZyb20gJy4vZ2xvYmFscyc7XG5pbXBvcnQgeyBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS10by1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9kaXNjb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLWZyb20tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRGaXJzdFNhbXBsZSB9IGZyb20gJy4vaGVscGVycy9nZXQtZmlyc3Qtc2FtcGxlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9QYXJhbSB9IGZyb20gJy4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9oZWxwZXJzL2dldC12YWx1ZS1mb3Ita2V5JztcbmltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4vaGVscGVycy9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNEQ0N1cnZlIH0gZnJvbSAnLi9oZWxwZXJzL2lzLWRjLWN1cnZlJztcbmltcG9ydCB7IGlzUGFydE9mQUN5Y2xlIH0gZnJvbSAnLi9oZWxwZXJzL2lzLXBhcnQtb2YtYS1jeWNsZSc7XG5pbXBvcnQgeyBpc1Bhc3NpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtcGFzc2l2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IG92ZXJ3cml0ZUFjY2Vzc29ycyB9IGZyb20gJy4vaGVscGVycy9vdmVyd3JpdGUtYWNjZXNzb3JzJztcbmltcG9ydCB7IHBpY2tFbGVtZW50RnJvbVNldCB9IGZyb20gJy4vaGVscGVycy9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuaW1wb3J0IHsgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvc2FuaXRpemUtY2hhbm5lbC1zcGxpdHRlci1vcHRpb25zJztcbmltcG9ydCB7IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1wZXJpb2RpYy13YXZlLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlIH0gZnJvbSAnLi9oZWxwZXJzL3NldC12YWx1ZS1hdC10aW1lLXVudGlsLXBvc3NpYmxlJztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmctc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLWNsb25hYmlsaXR5JztcbmltcG9ydCB7IHRlc3REb21FeGNlcHRpb25Db25zdHJ1Y3RvclN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1kb20tZXhjZXB0aW9uLWNvbnN0cnVjdG9yLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RUcmFuc2ZlcmFibGVzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LXRyYW5zZmVyYWJsZXMtc3VwcG9ydCc7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZyB9IGZyb20gJy4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyB9IGZyb20gJy4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscyc7XG5pbXBvcnQgeyB3cmFwRXZlbnRMaXN0ZW5lciB9IGZyb20gJy4vaGVscGVycy93cmFwLWV2ZW50LWxpc3RlbmVyJztcbi8qXG4gKiBAdG9kbyBFeHBsaWNpdGx5IHJlZmVyZW5jaW5nIHRoZSBiYXJyZWwgZmlsZSBzZWVtcyB0byBiZSBuZWNlc3Nhcnkgd2hlbiBlbmFibGluZyB0aGVcbiAqIGlzb2xhdGVkTW9kdWxlcyBjb21waWxlciBvcHRpb24uXG4gKi9cbmV4cG9ydCAqIGZyb20gJy4vaW50ZXJmYWNlcy9pbmRleCc7XG5leHBvcnQgKiBmcm9tICcuL3R5cGVzL2luZGV4JztcbmNvbnN0IGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gY3JlYXRlQWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoaW5zZXJ0RWxlbWVudEluU2V0KTtcbmNvbnN0IGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGNyZWF0ZUFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShpbnNlcnRFbGVtZW50SW5TZXQpO1xuY29uc3QgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBjcmVhdGVEZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwaWNrRWxlbWVudEZyb21TZXQpO1xuY29uc3QgYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBnZXRBdWRpb05vZGVUYWlsVGltZSA9IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpO1xuY29uc3QgY2FjaGVUZXN0UmVzdWx0ID0gY3JlYXRlQ2FjaGVUZXN0UmVzdWx0KG5ldyBNYXAoKSwgbmV3IFdlYWtNYXAoKSk7XG5jb25zdCB3aW5kb3cgPSBjcmVhdGVXaW5kb3coKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZUZhY3RvcnkoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCBnZXRBdWRpb05vZGVSZW5kZXJlciA9IGNyZWF0ZUdldEF1ZGlvTm9kZVJlbmRlcmVyKGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKTtcbmNvbnN0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlID0gY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb05vZGUoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBpc1BhcnRPZkFDeWNsZSk7XG5jb25zdCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZ2V0TmF0aXZlQ29udGV4dCA9IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQoQ09OVEVYVF9TVE9SRSk7XG5jb25zdCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuY29uc3QgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IgPSBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yKHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGlzTmF0aXZlQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNOYXRpdmVBdWRpb0NvbnRleHQobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuY29uc3QgaXNOYXRpdmVBdWRpb05vZGUgPSBjcmVhdGVJc05hdGl2ZUF1ZGlvTm9kZSh3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVBdWRpb1BhcmFtID0gY3JlYXRlSXNOYXRpdmVBdWRpb1BhcmFtKHdpbmRvdyk7XG5jb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGF1ZGlvTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9Ob2RlQ29uc3RydWN0b3IoY3JlYXRlQWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnMoQVVESU9fTk9ERV9DT05ORUNUSU9OU19TVE9SRSksIGNyZWF0ZUFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVRhaWxUaW1lLCBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIGluc2VydEVsZW1lbnRJblNldCwgaXNBY3RpdmVBdWRpb05vZGUsIGlzUGFydE9mQUN5Y2xlLCBpc1Bhc3NpdmVBdWRpb05vZGUpLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkoQ1lDTEVfQ09VTlRFUlMsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBpc0FjdGl2ZUF1ZGlvTm9kZSksIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVEZWNyZW1lbnRDeWNsZUNvdW50ZXIoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBDWUNMRV9DT1VOVEVSUywgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNBY3RpdmVBdWRpb05vZGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCksIGNyZWF0ZURldGVjdEN5Y2xlcyhhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRWYWx1ZUZvcktleSksIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVBdWRpb1BhcmFtLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvcik7XG5jb25zdCBhbmFseXNlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmV4cG9ydCB7IGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yIGFzIEFuYWx5c2VyTm9kZSB9O1xuY29uc3QgYXVkaW9CdWZmZXJTdG9yZSA9IG5ldyBXZWFrU2V0KCk7XG5jb25zdCBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgY29udmVydE51bWJlclRvVW5zaWduZWRMb25nID0gY3JlYXRlQ29udmVydE51bWJlclRvVW5zaWduZWRMb25nKG5ldyBVaW50MzJBcnJheSgxKSk7XG5jb25zdCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgPSBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nLCBjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyA9IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyk7XG5jb25zdCBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvcihhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKSwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyk7XG5leHBvcnQgeyBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yIGFzIEF1ZGlvQnVmZmVyIH07XG5jb25zdCBhZGRTaWxlbnRDb25uZWN0aW9uID0gY3JlYXRlQWRkU2lsZW50Q29ubmVjdGlvbihjcmVhdGVOYXRpdmVHYWluTm9kZSk7XG5jb25zdCByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gPSBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgaXNQYXJ0T2ZBQ3ljbGUpO1xuY29uc3QgY29ubmVjdEF1ZGlvUGFyYW0gPSBjcmVhdGVDb25uZWN0QXVkaW9QYXJhbShyZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0pO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZywgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIob3ZlcndyaXRlQWNjZXNzb3JzKSwgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKTtcbmNvbnN0IHJlbmRlckF1dG9tYXRpb24gPSBjcmVhdGVSZW5kZXJBdXRvbWF0aW9uKGNyZWF0ZUdldEF1ZGlvUGFyYW1SZW5kZXJlcihnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMpLCByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0pO1xuY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgPSBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjcmVhdGVBdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkoY3JlYXRlQWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zKEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFKSwgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBBVURJT19QQVJBTV9TVE9SRSwgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyLCBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50LCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKTtcbmNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKTtcbmV4cG9ydCB7IGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIEF1ZGlvQnVmZmVyU291cmNlTm9kZSB9O1xuY29uc3QgYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBvdmVyd3JpdGVBY2Nlc3NvcnMpLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgc2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSBjcmVhdGVTZXRBdWRpb05vZGVUYWlsVGltZShhdWRpb05vZGVUYWlsVGltZVN0b3JlKTtcbmNvbnN0IGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgbW9uaXRvckNvbm5lY3Rpb25zID0gY3JlYXRlTW9uaXRvckNvbm5lY3Rpb25zKGluc2VydEVsZW1lbnRJblNldCwgaXNOYXRpdmVBdWRpb05vZGUpO1xuY29uc3Qgd3JhcENoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlV3JhcENoYW5uZWxNZXJnZXJOb2RlKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZUZhY3RvcnkobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHdyYXBDaGFubmVsTWVyZ2VyTm9kZSk7XG5jb25zdCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyLCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQpO1xuY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUgPSBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlRmFjdG9yeShjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgb3ZlcndyaXRlQWNjZXNzb3JzKTtcbmNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVDb252b2x2ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVEZWxheU5vZGVSZW5kZXJlciA9IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGRlbGF5Tm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVGYWN0b3J5KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciA9IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIgPSBjcmVhdGVHYWluTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZ2Fpbk5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUdhaW5Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyRmFjdG9yeShjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcik7XG5jb25zdCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVUZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydChjcmVhdGVOYXRpdmVHYWluTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSk7XG5jb25zdCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIpO1xuY29uc3QgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlLCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlQXVkaW9MaXN0ZW5lciA9IGNyZWF0ZUF1ZGlvTGlzdGVuZXJGYWN0b3J5KGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXRGaXJzdFNhbXBsZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvdmVyd3JpdGVBY2Nlc3NvcnMpO1xuY29uc3QgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0xpc3RlbmVyLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUsIHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpO1xuY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciA9IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlT3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBpc0RDQ3VydmUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFjdG9yeShjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLCBpc0RDQ3VydmUsIG1vbml0b3JDb25uZWN0aW9ucywgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG92ZXJ3cml0ZUFjY2Vzc29ycyk7XG5jb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5KGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0Rmlyc3RTYW1wbGUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyKTtcbmNvbnN0IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciA9IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgcGFubmVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlUGFubmVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlLCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlID0gY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeShjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCBwZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciA9IGNyZWF0ZVBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yKGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZSwgZ2V0TmF0aXZlQ29udGV4dCwgbmV3IFdlYWtTZXQoKSwgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zKTtcbmNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWN0b3J5KG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnksIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciA9IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBpc1NlY3VyZUNvbnRleHQgPSBjcmVhdGVJc1NlY3VyZUNvbnRleHQod2luZG93KTtcbmNvbnN0IGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lID0gY3JlYXRlRXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUod2luZG93KTtcbmNvbnN0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuLy8gVGhlIGFkZEF1ZGlvV29ya2xldE1vZHVsZSgpIGZ1bmN0aW9uIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgU2VjdXJlQ29udGV4dC5cbmV4cG9ydCBjb25zdCBhZGRBdWRpb1dvcmtsZXRNb2R1bGUgPSBpc1NlY3VyZUNvbnRleHRcbiAgICA/IGNyZWF0ZUFkZEF1ZGlvV29ya2xldE1vZHVsZShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVFdmFsdWF0ZVNvdXJjZSh3aW5kb3cpLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgY3JlYXRlRmV0Y2hTb3VyY2UoY3JlYXRlQWJvcnRFcnJvciksIGdldE5hdGl2ZUNvbnRleHQsIGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5ldyBXZWFrTWFwKCksIG5ldyBXZWFrTWFwKCksIGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBcbiAgICAvLyBAdG9kbyB3aW5kb3cgaXMgZ3VhcmFudGVlZCB0byBiZSBkZWZpbmVkIGJlY2F1c2UgaXNTZWN1cmVDb250ZXh0IGNoZWNrcyB0aGF0IGFzIHdlbGwuXG4gICAgd2luZG93KVxuICAgIDogdW5kZWZpbmVkO1xuY29uc3QgaXNOYXRpdmVDb250ZXh0ID0gY3JlYXRlSXNOYXRpdmVDb250ZXh0KGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IGRlY29kZUF1ZGlvRGF0YSA9IGNyZWF0ZURlY29kZUF1ZGlvRGF0YShhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZURhdGFDbG9uZUVycm9yLCBjcmVhdGVFbmNvZGluZ0Vycm9yLCBuZXcgV2Vha1NldCgpLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUNvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgdGVzdFByb21pc2VTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmNvbnN0IGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZUJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihhZGRBdWRpb1dvcmtsZXRNb2R1bGUsIGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciwgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yLCBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IsIGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yLCBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IsIGRlY29kZUF1ZGlvRGF0YSwgZGVsYXlOb2RlQ29uc3RydWN0b3IsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciwgZ2Fpbk5vZGVDb25zdHJ1Y3RvciwgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yLCBwYW5uZXJOb2RlQ29uc3RydWN0b3IsIHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yLCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IsIHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IpO1xuY29uc3QgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVGYWN0b3J5KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0KTtcbmNvbnN0IGF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5leHBvcnQgeyBhdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBBdWRpb0NvbnRleHQgfTtcbmNvbnN0IGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2Rlcyh1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlKTtcbmNvbnN0IGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKTtcbmNvbnN0IGNvbm5lY3RNdWx0aXBsZU91dHB1dHMgPSBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzKGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlRGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKTtcbmNvbnN0IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMgPSBjcmVhdGVEaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzKGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyhhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIGdldFZhbHVlRm9yS2V5KTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlckZhY3RvcnkoY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWN0b3J5KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciA9IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQoYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlKTtcbmNvbnN0IHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSk7XG4vLyBUaGUgQXVkaW9Xb3JrbGV0Tm9kZSBjb25zdHJ1Y3RvciBpcyBvbmx5IGF2YWlsYWJsZSBpbiBhIFNlY3VyZUNvbnRleHQuXG5jb25zdCBhdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSBpc1NlY3VyZUNvbnRleHRcbiAgICA/IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zLCBzZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzLCB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSwgd3JhcEV2ZW50TGlzdGVuZXIpXG4gICAgOiB1bmRlZmluZWQ7XG5leHBvcnQgeyBhdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgYXMgQXVkaW9Xb3JrbGV0Tm9kZSB9O1xuZXhwb3J0IHsgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yIGFzIEJpcXVhZEZpbHRlck5vZGUgfTtcbmV4cG9ydCB7IGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IgYXMgQ2hhbm5lbE1lcmdlck5vZGUgfTtcbmV4cG9ydCB7IGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciBhcyBDaGFubmVsU3BsaXR0ZXJOb2RlIH07XG5leHBvcnQgeyBjb252b2x2ZXJOb2RlQ29uc3RydWN0b3IgYXMgQ29udm9sdmVyTm9kZSB9O1xuZXhwb3J0IHsgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgQ29uc3RhbnRTb3VyY2VOb2RlIH07XG5leHBvcnQgeyBkZWxheU5vZGVDb25zdHJ1Y3RvciBhcyBEZWxheU5vZGUgfTtcbmV4cG9ydCB7IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciBhcyBEeW5hbWljc0NvbXByZXNzb3JOb2RlIH07XG5leHBvcnQgeyBnYWluTm9kZUNvbnN0cnVjdG9yIGFzIEdhaW5Ob2RlIH07XG5leHBvcnQgeyBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgYXMgSUlSRmlsdGVyTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgYXMgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUgfTtcbmNvbnN0IG1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuZXhwb3J0IHsgbWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIE1pbmltYWxBdWRpb0NvbnRleHQgfTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVDcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuY29uc3Qgc3RhcnRSZW5kZXJpbmcgPSBjcmVhdGVTdGFydFJlbmRlcmluZyhhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyk7XG5jb25zdCBtaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzdGFydFJlbmRlcmluZyk7XG5leHBvcnQgeyBtaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIE1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0IH07XG5jb25zdCBvZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzdGFydFJlbmRlcmluZyk7XG5leHBvcnQgeyBvZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgT2ZmbGluZUF1ZGlvQ29udGV4dCB9O1xuZXhwb3J0IHsgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciBhcyBPc2NpbGxhdG9yTm9kZSB9O1xuZXhwb3J0IHsgcGFubmVyTm9kZUNvbnN0cnVjdG9yIGFzIFBhbm5lck5vZGUgfTtcbmV4cG9ydCB7IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yIGFzIFBlcmlvZGljV2F2ZSB9O1xuZXhwb3J0IHsgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yIGFzIFN0ZXJlb1Bhbm5lck5vZGUgfTtcbmV4cG9ydCB7IHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgYXMgV2F2ZVNoYXBlck5vZGUgfTtcbmV4cG9ydCBjb25zdCBpc0FueUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUlzQW55QXVkaW9Db250ZXh0KENPTlRFWFRfU1RPUkUsIGlzTmF0aXZlQXVkaW9Db250ZXh0KTtcbmV4cG9ydCBjb25zdCBpc0FueUF1ZGlvTm9kZSA9IGNyZWF0ZUlzQW55QXVkaW9Ob2RlKEFVRElPX05PREVfU1RPUkUsIGlzTmF0aXZlQXVkaW9Ob2RlKTtcbmV4cG9ydCBjb25zdCBpc0FueUF1ZGlvUGFyYW0gPSBjcmVhdGVJc0FueUF1ZGlvUGFyYW0oQVVESU9fUEFSQU1fU1RPUkUsIGlzTmF0aXZlQXVkaW9QYXJhbSk7XG5leHBvcnQgY29uc3QgaXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0KENPTlRFWFRfU1RPUkUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgY29uc3QgaXNTdXBwb3J0ZWQgPSAoKSA9PiBjcmVhdGVJc1N1cHBvcnRlZFByb21pc2UoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNTdWJhcnJheVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dENsb3NlTWV0aG9kU3VwcG9ydChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb0NvbnRleHREZWNvZGVBdWRpb0RhdGFNZXRob2RUeXBlRXJyb3JTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRPcHRpb25zU3VwcG9ydChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb05vZGVDb25uZWN0TWV0aG9kU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yTm9PdXRwdXRzU3VwcG9ydChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RDaGFubmVsTWVyZ2VyTm9kZUNoYW5uZWxDb3VudFN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnN0YW50U291cmNlTm9kZUFjY3VyYXRlU2NoZWR1bGluZ1N1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVCdWZmZXJSZWFzc2lnbmFiaWxpdHlTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCB0ZXN0RG9tRXhjZXB0aW9uQ29uc3RydWN0b3JTdXBwb3J0LCBjcmVhdGVUZXN0SXNTZWN1cmVDb250ZXh0U3VwcG9ydCh3aW5kb3cpLCBjcmVhdGVUZXN0TWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVNZWRpYVN0cmVhbVdpdGhvdXRBdWRpb1RyYWNrU3VwcG9ydChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RTdGVyZW9QYW5uZXJOb2RlRGVmYXVsdFZhbHVlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCB0ZXN0VHJhbnNmZXJhYmxlc1N1cHBvcnQpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bW9kdWxlLmpzLm1hcCIsIi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIHN0YXRlbWVudCBpcyB0cnVlLCBvdGhlcndpc2UgaW52b2tlIHRoZSBlcnJvci5cbiAqIEBwYXJhbSBzdGF0ZW1lbnRcbiAqIEBwYXJhbSBlcnJvciBUaGUgbWVzc2FnZSB3aGljaCBpcyBwYXNzZWQgaW50byBhbiBFcnJvclxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0KHN0YXRlbWVudCwgZXJyb3IpIHtcbiAgICBpZiAoIXN0YXRlbWVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIHdpdGhpbiB0aGUgcmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydFJhbmdlKHZhbHVlLCBndGUsIGx0ZSA9IEluZmluaXR5KSB7XG4gICAgaWYgKCEoZ3RlIDw9IHZhbHVlICYmIHZhbHVlIDw9IGx0ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFZhbHVlIG11c3QgYmUgd2l0aGluIFske2d0ZX0sICR7bHRlfV0sIGdvdDogJHt2YWx1ZX1gKTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBpcyB3aXRoaW4gdGhlIHJhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRDb250ZXh0UnVubmluZyhjb250ZXh0KSB7XG4gICAgLy8gYWRkIGEgd2FybmluZyBpZiB0aGUgY29udGV4dCBpcyBub3Qgc3RhcnRlZFxuICAgIGlmICghY29udGV4dC5pc09mZmxpbmUgJiYgY29udGV4dC5zdGF0ZSAhPT0gXCJydW5uaW5nXCIpIHtcbiAgICAgICAgd2FybihcIlRoZSBBdWRpb0NvbnRleHQgaXMgXFxcInN1c3BlbmRlZFxcXCIuIEludm9rZSBUb25lLnN0YXJ0KCkgZnJvbSBhIHVzZXIgYWN0aW9uIHRvIHN0YXJ0IHRoZSBhdWRpby5cIik7XG4gICAgfVxufVxuLyoqXG4gKiBUaGUgZGVmYXVsdCBsb2dnZXIgaXMgdGhlIGNvbnNvbGVcbiAqL1xubGV0IGRlZmF1bHRMb2dnZXIgPSBjb25zb2xlO1xuLyoqXG4gKiBTZXQgdGhlIGxvZ2dpbmcgaW50ZXJmYWNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRMb2dnZXIobG9nZ2VyKSB7XG4gICAgZGVmYXVsdExvZ2dlciA9IGxvZ2dlcjtcbn1cbi8qKlxuICogTG9nIGFueXRoaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2coLi4uYXJncykge1xuICAgIGRlZmF1bHRMb2dnZXIubG9nKC4uLmFyZ3MpO1xufVxuLyoqXG4gKiBXYXJuIGFueXRoaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YXJuKC4uLmFyZ3MpIHtcbiAgICBkZWZhdWx0TG9nZ2VyLndhcm4oLi4uYXJncyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWJ1Zy5qcy5tYXAiLCIvKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVW5kZWYoYXJnKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwidW5kZWZpbmVkXCI7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBub3QgdW5kZWZpbmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RlZmluZWQoYXJnKSB7XG4gICAgcmV0dXJuICFpc1VuZGVmKGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBhIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB0eXBlb2YgYXJnID09PSBcImZ1bmN0aW9uXCI7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgbnVtYmVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcIm51bWJlclwiKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgZ2l2ZW4gYXJndW1lbnQgaXMgYW4gb2JqZWN0IGxpdGVyYWwgKGkuZS4gYHt9YCk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgICByZXR1cm4gKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcmcpID09PSBcIltvYmplY3QgT2JqZWN0XVwiICYmIGFyZy5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBib29sZWFuLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNCb29sZWFuKGFyZykge1xuICAgIHJldHVybiAodHlwZW9mIGFyZyA9PT0gXCJib29sZWFuXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhbiBBcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheShhcmcpIHtcbiAgICByZXR1cm4gKEFycmF5LmlzQXJyYXkoYXJnKSk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcInN0cmluZ1wiKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgaW4gdGhlIGZvcm0gb2YgYSBub3RlIGluIHNjaWVudGlmaWMgcGl0Y2ggbm90YXRpb24uXG4gKiBlLmcuIFwiQzRcIlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb3RlKGFyZykge1xuICAgIHJldHVybiBpc1N0cmluZyhhcmcpICYmIC9eKFthLWddezF9KD86YnwjfHh8YmIpPykoLT9bMC05XSspL2kudGVzdChhcmcpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHlwZUNoZWNrLmpzLm1hcCIsImltcG9ydCB7IEF1ZGlvQ29udGV4dCBhcyBzdGRBdWRpb0NvbnRleHQsIEF1ZGlvV29ya2xldE5vZGUgYXMgc3RkQXVkaW9Xb3JrbGV0Tm9kZSwgT2ZmbGluZUF1ZGlvQ29udGV4dCBhcyBzdGRPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGlvQ29udGV4dChvcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBzdGRBdWRpb0NvbnRleHQob3B0aW9ucyk7XG59XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBPZmZsaW5lQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0KGNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpIHtcbiAgICByZXR1cm4gbmV3IHN0ZE9mZmxpbmVBdWRpb0NvbnRleHQoY2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG59XG4vKipcbiAqIEEgcmVmZXJlbmNlIHRvIHRoZSB3aW5kb3cgb2JqZWN0XG4gKiBAaGlkZGVuXG4gKi9cbmV4cG9ydCBjb25zdCB0aGVXaW5kb3cgPSB0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiA/IHNlbGYgOiBudWxsO1xuLyoqXG4gKiBJZiB0aGUgYnJvd3NlciBoYXMgYSB3aW5kb3cgb2JqZWN0IHdoaWNoIGhhcyBhbiBBdWRpb0NvbnRleHRcbiAqIEBoaWRkZW5cbiAqL1xuZXhwb3J0IGNvbnN0IGhhc0F1ZGlvQ29udGV4dCA9IHRoZVdpbmRvdyAmJlxuICAgICh0aGVXaW5kb3cuaGFzT3duUHJvcGVydHkoXCJBdWRpb0NvbnRleHRcIikgfHwgdGhlV2luZG93Lmhhc093blByb3BlcnR5KFwid2Via2l0QXVkaW9Db250ZXh0XCIpKTtcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpIHtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKHN0ZEF1ZGlvV29ya2xldE5vZGUpLCBcIlRoaXMgbm9kZSBvbmx5IHdvcmtzIGluIGEgc2VjdXJlIGNvbnRleHQgKGh0dHBzIG9yIGxvY2FsaG9zdClcIik7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBuZXcgc3RkQXVkaW9Xb3JrbGV0Tm9kZShjb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbn1cbi8qKlxuICogVGhpcyBwcm9taXNlIHJlc29sdmVzIHRvIGEgYm9vbGVhbiB3aGljaCBpbmRpY2F0ZXMgaWYgdGhlXG4gKiBmdW5jdGlvbmFsaXR5IGlzIHN1cHBvcnRlZCB3aXRoaW4gdGhlIGN1cnJlbnRseSB1c2VkIGJyb3dzZS5cbiAqIFRha2VuIGZyb20gW3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XShodHRwczovL2dpdGh1Yi5jb20vY2hyaXNndXR0YW5kaW4vc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQjaXNzdXBwb3J0ZWQpXG4gKi9cbmV4cG9ydCB7IGlzU3VwcG9ydGVkIGFzIHN1cHBvcnRlZCB9IGZyb20gXCJzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXVkaW9Db250ZXh0LmpzLm1hcCIsIi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uXHJcblxyXG5QZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQvb3IgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGZvciBhbnlcclxucHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLlxyXG5cclxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiBBTkQgVEhFIEFVVEhPUiBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSFxyXG5SRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFlcclxuQU5EIEZJVE5FU1MuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgRElSRUNULFxyXG5JTkRJUkVDVCwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST01cclxuTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1JcclxuT1RIRVIgVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUlxyXG5QRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4dGVuZHMoZCwgYikge1xyXG4gICAgaWYgKHR5cGVvZiBiICE9PSBcImZ1bmN0aW9uXCIgJiYgYiAhPT0gbnVsbClcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2xhc3MgZXh0ZW5kcyB2YWx1ZSBcIiArIFN0cmluZyhiKSArIFwiIGlzIG5vdCBhIGNvbnN0cnVjdG9yIG9yIG51bGxcIik7XHJcbiAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19hc3NpZ24gPSBmdW5jdGlvbigpIHtcclxuICAgIF9fYXNzaWduID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiBfX2Fzc2lnbih0KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcywgaSA9IDEsIG4gPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHMgPSBhcmd1bWVudHNbaV07XHJcbiAgICAgICAgICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSkgdFtwXSA9IHNbcF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIF9fYXNzaWduLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Jlc3QocywgZSkge1xyXG4gICAgdmFyIHQgPSB7fTtcclxuICAgIGZvciAodmFyIHAgaW4gcykgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzLCBwKSAmJiBlLmluZGV4T2YocCkgPCAwKVxyXG4gICAgICAgIHRbcF0gPSBzW3BdO1xyXG4gICAgaWYgKHMgIT0gbnVsbCAmJiB0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gXCJmdW5jdGlvblwiKVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBwID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhzKTsgaSA8IHAubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDAgJiYgT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHMsIHBbaV0pKVxyXG4gICAgICAgICAgICAgICAgdFtwW2ldXSA9IHNbcFtpXV07XHJcbiAgICAgICAgfVxyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19lc0RlY29yYXRlKGN0b3IsIGRlc2NyaXB0b3JJbiwgZGVjb3JhdG9ycywgY29udGV4dEluLCBpbml0aWFsaXplcnMsIGV4dHJhSW5pdGlhbGl6ZXJzKSB7XHJcbiAgICBmdW5jdGlvbiBhY2NlcHQoZikgeyBpZiAoZiAhPT0gdm9pZCAwICYmIHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJGdW5jdGlvbiBleHBlY3RlZFwiKTsgcmV0dXJuIGY7IH1cclxuICAgIHZhciBraW5kID0gY29udGV4dEluLmtpbmQsIGtleSA9IGtpbmQgPT09IFwiZ2V0dGVyXCIgPyBcImdldFwiIDoga2luZCA9PT0gXCJzZXR0ZXJcIiA/IFwic2V0XCIgOiBcInZhbHVlXCI7XHJcbiAgICB2YXIgdGFyZ2V0ID0gIWRlc2NyaXB0b3JJbiAmJiBjdG9yID8gY29udGV4dEluW1wic3RhdGljXCJdID8gY3RvciA6IGN0b3IucHJvdG90eXBlIDogbnVsbDtcclxuICAgIHZhciBkZXNjcmlwdG9yID0gZGVzY3JpcHRvckluIHx8ICh0YXJnZXQgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgY29udGV4dEluLm5hbWUpIDoge30pO1xyXG4gICAgdmFyIF8sIGRvbmUgPSBmYWxzZTtcclxuICAgIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgdmFyIGNvbnRleHQgPSB7fTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbikgY29udGV4dFtwXSA9IHAgPT09IFwiYWNjZXNzXCIgPyB7fSA6IGNvbnRleHRJbltwXTtcclxuICAgICAgICBmb3IgKHZhciBwIGluIGNvbnRleHRJbi5hY2Nlc3MpIGNvbnRleHQuYWNjZXNzW3BdID0gY29udGV4dEluLmFjY2Vzc1twXTtcclxuICAgICAgICBjb250ZXh0LmFkZEluaXRpYWxpemVyID0gZnVuY3Rpb24gKGYpIHsgaWYgKGRvbmUpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgYWRkIGluaXRpYWxpemVycyBhZnRlciBkZWNvcmF0aW9uIGhhcyBjb21wbGV0ZWRcIik7IGV4dHJhSW5pdGlhbGl6ZXJzLnB1c2goYWNjZXB0KGYgfHwgbnVsbCkpOyB9O1xyXG4gICAgICAgIHZhciByZXN1bHQgPSAoMCwgZGVjb3JhdG9yc1tpXSkoa2luZCA9PT0gXCJhY2Nlc3NvclwiID8geyBnZXQ6IGRlc2NyaXB0b3IuZ2V0LCBzZXQ6IGRlc2NyaXB0b3Iuc2V0IH0gOiBkZXNjcmlwdG9yW2tleV0sIGNvbnRleHQpO1xyXG4gICAgICAgIGlmIChraW5kID09PSBcImFjY2Vzc29yXCIpIHtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdm9pZCAwKSBjb250aW51ZTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCB0eXBlb2YgcmVzdWx0ICE9PSBcIm9iamVjdFwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkXCIpO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuZ2V0KSkgZGVzY3JpcHRvci5nZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuc2V0KSkgZGVzY3JpcHRvci5zZXQgPSBfO1xyXG4gICAgICAgICAgICBpZiAoXyA9IGFjY2VwdChyZXN1bHQuaW5pdCkpIGluaXRpYWxpemVycy5wdXNoKF8pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChfID0gYWNjZXB0KHJlc3VsdCkpIHtcclxuICAgICAgICAgICAgaWYgKGtpbmQgPT09IFwiZmllbGRcIikgaW5pdGlhbGl6ZXJzLnB1c2goXyk7XHJcbiAgICAgICAgICAgIGVsc2UgZGVzY3JpcHRvcltrZXldID0gXztcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAodGFyZ2V0KSBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSwgZGVzY3JpcHRvcik7XHJcbiAgICBkb25lID0gdHJ1ZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3J1bkluaXRpYWxpemVycyh0aGlzQXJnLCBpbml0aWFsaXplcnMsIHZhbHVlKSB7XHJcbiAgICB2YXIgdXNlVmFsdWUgPSBhcmd1bWVudHMubGVuZ3RoID4gMjtcclxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5pdGlhbGl6ZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgdmFsdWUgPSB1c2VWYWx1ZSA/IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcsIHZhbHVlKSA6IGluaXRpYWxpemVyc1tpXS5jYWxsKHRoaXNBcmcpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVzZVZhbHVlID8gdmFsdWUgOiB2b2lkIDA7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wcm9wS2V5KHgpIHtcclxuICAgIHJldHVybiB0eXBlb2YgeCA9PT0gXCJzeW1ib2xcIiA/IHggOiBcIlwiLmNvbmNhdCh4KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NldEZ1bmN0aW9uTmFtZShmLCBuYW1lLCBwcmVmaXgpIHtcclxuICAgIGlmICh0eXBlb2YgbmFtZSA9PT0gXCJzeW1ib2xcIikgbmFtZSA9IG5hbWUuZGVzY3JpcHRpb24gPyBcIltcIi5jb25jYXQobmFtZS5kZXNjcmlwdGlvbiwgXCJdXCIpIDogXCJcIjtcclxuICAgIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoZiwgXCJuYW1lXCIsIHsgY29uZmlndXJhYmxlOiB0cnVlLCB2YWx1ZTogcHJlZml4ID8gXCJcIi5jb25jYXQocHJlZml4LCBcIiBcIiwgbmFtZSkgOiBuYW1lIH0pO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChnICYmIChnID0gMCwgb3BbMF0gJiYgKF8gPSAwKSksIF8pIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChmID0gMSwgeSAmJiAodCA9IG9wWzBdICYgMiA/IHlbXCJyZXR1cm5cIl0gOiBvcFswXSA/IHlbXCJ0aHJvd1wiXSB8fCAoKHQgPSB5W1wicmV0dXJuXCJdKSAmJiB0LmNhbGwoeSksIDApIDogeS5uZXh0KSAmJiAhKHQgPSB0LmNhbGwoeSwgb3BbMV0pKS5kb25lKSByZXR1cm4gdDtcclxuICAgICAgICAgICAgaWYgKHkgPSAwLCB0KSBvcCA9IFtvcFswXSAmIDIsIHQudmFsdWVdO1xyXG4gICAgICAgICAgICBzd2l0Y2ggKG9wWzBdKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDA6IGNhc2UgMTogdCA9IG9wOyBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgNDogXy5sYWJlbCsrOyByZXR1cm4geyB2YWx1ZTogb3BbMV0sIGRvbmU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICBjYXNlIDU6IF8ubGFiZWwrKzsgeSA9IG9wWzFdOyBvcCA9IFswXTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDc6IG9wID0gXy5vcHMucG9wKCk7IF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIGlmICghKHQgPSBfLnRyeXMsIHQgPSB0Lmxlbmd0aCA+IDAgJiYgdFt0Lmxlbmd0aCAtIDFdKSAmJiAob3BbMF0gPT09IDYgfHwgb3BbMF0gPT09IDIpKSB7IF8gPSAwOyBjb250aW51ZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gMyAmJiAoIXQgfHwgKG9wWzFdID4gdFswXSAmJiBvcFsxXSA8IHRbM10pKSkgeyBfLmxhYmVsID0gb3BbMV07IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSA2ICYmIF8ubGFiZWwgPCB0WzFdKSB7IF8ubGFiZWwgPSB0WzFdOyB0ID0gb3A7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQgJiYgXy5sYWJlbCA8IHRbMl0pIHsgXy5sYWJlbCA9IHRbMl07IF8ub3BzLnB1c2gob3ApOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0WzJdKSBfLm9wcy5wb3AoKTtcclxuICAgICAgICAgICAgICAgICAgICBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9wID0gYm9keS5jYWxsKHRoaXNBcmcsIF8pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgb3AgPSBbNiwgZV07IHkgPSAwOyB9IGZpbmFsbHkgeyBmID0gdCA9IDA7IH1cclxuICAgICAgICBpZiAob3BbMF0gJiA1KSB0aHJvdyBvcFsxXTsgcmV0dXJuIHsgdmFsdWU6IG9wWzBdID8gb3BbMV0gOiB2b2lkIDAsIGRvbmU6IHRydWUgfTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2NyZWF0ZUJpbmRpbmcgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG0sIGspO1xyXG4gICAgaWYgKCFkZXNjIHx8IChcImdldFwiIGluIGRlc2MgPyAhbS5fX2VzTW9kdWxlIDogZGVzYy53cml0YWJsZSB8fCBkZXNjLmNvbmZpZ3VyYWJsZSkpIHtcclxuICAgICAgICBkZXNjID0geyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9O1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGsyLCBkZXNjKTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogZmFsc2UgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG52YXIgX19zZXRNb2R1bGVEZWZhdWx0ID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgXCJkZWZhdWx0XCIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHYgfSk7XHJcbn0pIDogZnVuY3Rpb24obywgdikge1xyXG4gICAgb1tcImRlZmF1bHRcIl0gPSB2O1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0U3Rhcihtb2QpIHtcclxuICAgIGlmIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpIHJldHVybiBtb2Q7XHJcbiAgICB2YXIgcmVzdWx0ID0ge307XHJcbiAgICBpZiAobW9kICE9IG51bGwpIGZvciAodmFyIGsgaW4gbW9kKSBpZiAoayAhPT0gXCJkZWZhdWx0XCIgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZCwgaykpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwgayk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuIiwiLyoqXG4gKiBBIGNsYXNzIHdoaWNoIHByb3ZpZGVzIGEgcmVsaWFibGUgY2FsbGJhY2sgdXNpbmcgZWl0aGVyXG4gKiBhIFdlYiBXb3JrZXIsIG9yIGlmIHRoYXQgaXNuJ3Qgc3VwcG9ydGVkLCBmYWxscyBiYWNrIHRvIHNldFRpbWVvdXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrZXIge1xuICAgIGNvbnN0cnVjdG9yKGNhbGxiYWNrLCB0eXBlLCB1cGRhdGVJbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl9jYWxsYmFjayA9IGNhbGxiYWNrO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgPSB1cGRhdGVJbnRlcnZhbDtcbiAgICAgICAgLy8gY3JlYXRlIHRoZSBjbG9jayBzb3VyY2UgZm9yIHRoZSBmaXJzdCB0aW1lXG4gICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIGEgd2ViIHdvcmtlclxuICAgICAqL1xuICAgIF9jcmVhdGVXb3JrZXIoKSB7XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbXG4gICAgICAgICAgICAvKiBqYXZhc2NyaXB0ICovIGBcblx0XHRcdC8vIHRoZSBpbml0aWFsIHRpbWVvdXQgdGltZVxuXHRcdFx0bGV0IHRpbWVvdXRUaW1lID0gICR7KHRoaXMuX3VwZGF0ZUludGVydmFsICogMTAwMCkudG9GaXhlZCgxKX07XG5cdFx0XHQvLyBvbm1lc3NhZ2UgY2FsbGJhY2tcblx0XHRcdHNlbGYub25tZXNzYWdlID0gZnVuY3Rpb24obXNnKXtcblx0XHRcdFx0dGltZW91dFRpbWUgPSBwYXJzZUludChtc2cuZGF0YSk7XG5cdFx0XHR9O1xuXHRcdFx0Ly8gdGhlIHRpY2sgZnVuY3Rpb24gd2hpY2ggcG9zdHMgYSBtZXNzYWdlXG5cdFx0XHQvLyBhbmQgc2NoZWR1bGVzIGEgbmV3IHRpY2tcblx0XHRcdGZ1bmN0aW9uIHRpY2soKXtcblx0XHRcdFx0c2V0VGltZW91dCh0aWNrLCB0aW1lb3V0VGltZSk7XG5cdFx0XHRcdHNlbGYucG9zdE1lc3NhZ2UoJ3RpY2snKTtcblx0XHRcdH1cblx0XHRcdC8vIGNhbGwgdGljayBpbml0aWFsbHlcblx0XHRcdHRpY2soKTtcblx0XHRcdGBcbiAgICAgICAgXSwgeyB0eXBlOiBcInRleHQvamF2YXNjcmlwdFwiIH0pO1xuICAgICAgICBjb25zdCBibG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgY29uc3Qgd29ya2VyID0gbmV3IFdvcmtlcihibG9iVXJsKTtcbiAgICAgICAgd29ya2VyLm9ubWVzc2FnZSA9IHRoaXMuX2NhbGxiYWNrLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuX3dvcmtlciA9IHdvcmtlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgdGltZW91dCBsb29wXG4gICAgICovXG4gICAgX2NyZWF0ZVRpbWVvdXQoKSB7XG4gICAgICAgIHRoaXMuX3RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRpbWVvdXQoKTtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrKCk7XG4gICAgICAgIH0sIHRoaXMuX3VwZGF0ZUludGVydmFsICogMTAwMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB0aGUgY2xvY2sgc291cmNlLlxuICAgICAqL1xuICAgIF9jcmVhdGVDbG9jaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwid29ya2VyXCIpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlV29ya2VyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIC8vIHdvcmtlcnMgbm90IHN1cHBvcnRlZCwgZmFsbGJhY2sgdG8gdGltZW91dFxuICAgICAgICAgICAgICAgIHRoaXMuX3R5cGUgPSBcInRpbWVvdXRcIjtcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVDbG9jaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3R5cGUgPT09IFwidGltZW91dFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVUaW1lb3V0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAgdGhlIGN1cnJlbnQgY2xvY2sgc291cmNlXG4gICAgICovXG4gICAgX2Rpc3Bvc2VDbG9jaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVvdXQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl93b3JrZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtlci50ZXJtaW5hdGUoKTtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtlci5vbm1lc3NhZ2UgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByYXRlIGluIHNlY29uZHMgdGhlIHRpY2tlciB3aWxsIHVwZGF0ZVxuICAgICAqL1xuICAgIGdldCB1cGRhdGVJbnRlcnZhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VwZGF0ZUludGVydmFsO1xuICAgIH1cbiAgICBzZXQgdXBkYXRlSW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgPSBNYXRoLm1heChpbnRlcnZhbCwgMTI4IC8gNDQxMDApO1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLnBvc3RNZXNzYWdlKE1hdGgubWF4KGludGVydmFsICogMTAwMCwgMSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSB0aWNrZXIsIGVpdGhlciBhIHdvcmtlciBvciBhIHRpbWVvdXRcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZUNsb2NrKCk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9jcmVhdGVDbG9jaygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VDbG9jaygpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tlci5qcy5tYXAiLCJpbXBvcnQgeyBpc0FueUF1ZGlvQ29udGV4dCwgaXNBbnlBdWRpb05vZGUsIGlzQW55QXVkaW9QYXJhbSwgaXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0LCB9IGZyb20gXCJzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFwiO1xuLyoqXG4gKiBUZXN0IGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhbiBpbnN0YW5jZW9mIEF1ZGlvUGFyYW1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9QYXJhbShhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlBdWRpb1BhcmFtKGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9Ob2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0F1ZGlvTm9kZShhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlBdWRpb05vZGUoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGluc3RhbmNlb2YgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPZmZsaW5lQXVkaW9Db250ZXh0KGFyZykge1xuICAgIHJldHVybiBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0F1ZGlvQ29udGV4dChhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlBdWRpb0NvbnRleHQoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGluc3RhbmNlb2YgYW4gQXVkaW9CdWZmZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9CdWZmZXIoYXJnKSB7XG4gICAgcmV0dXJuIGFyZyBpbnN0YW5jZW9mIEF1ZGlvQnVmZmVyO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWR2YW5jZWRUeXBlQ2hlY2suanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb0J1ZmZlciwgaXNBdWRpb05vZGUsIGlzQXVkaW9QYXJhbSB9IGZyb20gXCIuL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1VuZGVmIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG4vKipcbiAqIFNvbWUgb2JqZWN0cyBzaG91bGQgbm90IGJlIG1lcmdlZFxuICovXG5mdW5jdGlvbiBub0NvcHkoa2V5LCBhcmcpIHtcbiAgICByZXR1cm4ga2V5ID09PSBcInZhbHVlXCIgfHwgaXNBdWRpb1BhcmFtKGFyZykgfHwgaXNBdWRpb05vZGUoYXJnKSB8fCBpc0F1ZGlvQnVmZmVyKGFyZyk7XG59XG5leHBvcnQgZnVuY3Rpb24gZGVlcE1lcmdlKHRhcmdldCwgLi4uc291cmNlcykge1xuICAgIGlmICghc291cmNlcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlcy5zaGlmdCgpO1xuICAgIGlmIChpc09iamVjdCh0YXJnZXQpICYmIGlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICBpZiAobm9Db3B5KGtleSwgc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KHNvdXJjZVtrZXldKSkge1xuICAgICAgICAgICAgICAgIGlmICghdGFyZ2V0W2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHt9IH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWVwTWVyZ2UodGFyZ2V0W2tleV0sIHNvdXJjZVtrZXldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odGFyZ2V0LCB7IFtrZXldOiBzb3VyY2Vba2V5XSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIGRlZXBNZXJnZSh0YXJnZXQsIC4uLnNvdXJjZXMpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHR3byBhcnJheXMgaGF2ZSB0aGUgc2FtZSB2YWx1ZSBmb3IgZWFjaCBvZiB0aGUgZWxlbWVudHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbHMoYXJyYXlBLCBhcnJheUIpIHtcbiAgICByZXR1cm4gYXJyYXlBLmxlbmd0aCA9PT0gYXJyYXlCLmxlbmd0aCAmJiBhcnJheUEuZXZlcnkoKGVsZW1lbnQsIGluZGV4KSA9PiBhcnJheUJbaW5kZXhdID09PSBlbGVtZW50KTtcbn1cbi8qKlxuICogQ29udmVydCBhbiBhcmdzIGFycmF5IGludG8gYW4gb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gb3B0aW9uc0Zyb21Bcmd1bWVudHMoZGVmYXVsdHMsIGFyZ3NBcnJheSwga2V5cyA9IFtdLCBvYmpLZXkpIHtcbiAgICBjb25zdCBvcHRzID0ge307XG4gICAgY29uc3QgYXJncyA9IEFycmF5LmZyb20oYXJnc0FycmF5KTtcbiAgICAvLyBpZiB0aGUgZmlyc3QgYXJndW1lbnQgaXMgYW4gb2JqZWN0IGFuZCBoYXMgYW4gb2JqZWN0IGtleVxuICAgIGlmIChpc09iamVjdChhcmdzWzBdKSAmJiBvYmpLZXkgJiYgIVJlZmxlY3QuaGFzKGFyZ3NbMF0sIG9iaktleSkpIHtcbiAgICAgICAgLy8gaWYgaXQncyBub3QgcGFydCBvZiB0aGUgZGVmYXVsdHNcbiAgICAgICAgY29uc3QgcGFydE9mRGVmYXVsdHMgPSBPYmplY3Qua2V5cyhhcmdzWzBdKS5zb21lKGtleSA9PiBSZWZsZWN0LmhhcyhkZWZhdWx0cywga2V5KSk7XG4gICAgICAgIGlmICghcGFydE9mRGVmYXVsdHMpIHtcbiAgICAgICAgICAgIC8vIG1lcmdlIHRoYXQga2V5XG4gICAgICAgICAgICBkZWVwTWVyZ2Uob3B0cywgeyBbb2JqS2V5XTogYXJnc1swXSB9KTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgb2JqIGtleSBmcm9tIHRoZSBrZXlzXG4gICAgICAgICAgICBrZXlzLnNwbGljZShrZXlzLmluZGV4T2Yob2JqS2V5KSwgMSk7XG4gICAgICAgICAgICAvLyBzaGlmdCB0aGUgZmlyc3QgYXJndW1lbnQgb2ZmXG4gICAgICAgICAgICBhcmdzLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIGlzT2JqZWN0KGFyZ3NbMF0pKSB7XG4gICAgICAgIGRlZXBNZXJnZShvcHRzLCBhcmdzWzBdKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChhcmdzW2ldKSkge1xuICAgICAgICAgICAgICAgIG9wdHNba2V5c1tpXV0gPSBhcmdzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZWVwTWVyZ2UoZGVmYXVsdHMsIG9wdHMpO1xufVxuLyoqXG4gKiBSZXR1cm4gdGhpcyBpbnN0YW5jZXMgZGVmYXVsdCB2YWx1ZXMgYnkgY2FsbGluZyBDb25zdHJ1Y3Rvci5nZXREZWZhdWx0cygpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZShpbnN0YW5jZSkge1xuICAgIHJldHVybiBpbnN0YW5jZS5jb25zdHJ1Y3Rvci5nZXREZWZhdWx0cygpO1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmYWxsYmFjayBpZiB0aGUgZ2l2ZW4gb2JqZWN0IGlzIHVuZGVmaW5lZC5cbiAqIFRha2UgYW4gYXJyYXkgb2YgYXJndW1lbnRzIGFuZCByZXR1cm4gYSBmb3JtYXR0ZWQgb3B0aW9ucyBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QXJnKGdpdmVuLCBmYWxsYmFjaykge1xuICAgIGlmIChpc1VuZGVmKGdpdmVuKSkge1xuICAgICAgICByZXR1cm4gZmFsbGJhY2s7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gZ2l2ZW47XG4gICAgfVxufVxuLyoqXG4gKiBSZW1vdmUgYWxsIG9mIHRoZSBwcm9wZXJ0aWVzIGJlbG9uZ2luZyB0byBvbWl0IGZyb20gb2JqLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb21pdEZyb21PYmplY3Qob2JqLCBvbWl0KSB7XG4gICAgb21pdC5mb3JFYWNoKHByb3AgPT4ge1xuICAgICAgICBpZiAoUmVmbGVjdC5oYXMob2JqLCBwcm9wKSkge1xuICAgICAgICAgICAgZGVsZXRlIG9ialtwcm9wXTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvYmo7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWZhdWx0cy5qcy5tYXAiLCIvKipcbiAqIFRvbmUuanNcbiAqIEBhdXRob3IgWW90YW0gTWFublxuICogQGxpY2Vuc2UgaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVCBNSVQgTGljZW5zZVxuICogQGNvcHlyaWdodCAyMDE0LTIwMTkgWW90YW0gTWFublxuICovXG5pbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4uL3ZlcnNpb25cIjtcbmltcG9ydCB7IHRoZVdpbmRvdyB9IGZyb20gXCIuL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEBjbGFzcyAgVG9uZSBpcyB0aGUgYmFzZSBjbGFzcyBvZiBhbGwgb3RoZXIgY2xhc3Nlcy5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRERUJVR0dJTkdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXQgdGhpcyBkZWJ1ZyBmbGFnIHRvIGxvZyBhbGwgZXZlbnRzIHRoYXQgaGFwcGVuIGluIHRoaXMgY2xhc3MuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmRlYnVnID0gZmFsc2U7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdERJU1BPU0lOR1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgaW5zdGFuY2Ugd2FzIGRpc3Bvc2VkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl93YXNEaXNwb3NlZCA9IGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFsbCBvZiB0aGUgZGVmYXVsdCBvcHRpb25zIGJlbG9uZ2luZyB0byB0aGUgY2xhc3MuXG4gICAgICovXG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFByaW50cyB0aGUgb3V0cHV0cyB0byB0aGUgY29uc29sZSBsb2cgZm9yIGRlYnVnZ2luZyBwdXJwb3Nlcy5cbiAgICAgKiBQcmludHMgdGhlIGNvbnRlbnRzIG9ubHkgaWYgZWl0aGVyIHRoZSBvYmplY3QgaGFzIGEgcHJvcGVydHlcbiAgICAgKiBjYWxsZWQgYGRlYnVnYCBzZXQgdG8gdHJ1ZSwgb3IgYSB2YXJpYWJsZSBjYWxsZWQgVE9ORV9ERUJVR19DTEFTU1xuICAgICAqIGlzIHNldCB0byB0aGUgbmFtZSBvZiB0aGUgY2xhc3MuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCk7XG4gICAgICogLy8gcHJpbnRzIGFsbCBsb2dzIG9yaWdpbmF0aW5nIGZyb20gdGhpcyBvc2NpbGxhdG9yXG4gICAgICogb3NjLmRlYnVnID0gdHJ1ZTtcbiAgICAgKiAvLyBjYWxscyB0byBzdGFydC9zdG9wIHdpbGwgcHJpbnQgaW4gdGhlIGNvbnNvbGVcbiAgICAgKiBvc2Muc3RhcnQoKTtcbiAgICAgKi9cbiAgICBsb2coLi4uYXJncykge1xuICAgICAgICAvLyBpZiB0aGUgb2JqZWN0IGlzIGVpdGhlciBzZXQgdG8gZGVidWcgPSB0cnVlXG4gICAgICAgIC8vIG9yIGlmIHRoZXJlIGlzIGEgc3RyaW5nIG9uIHRoZSBUb25lLmdsb2JhbC53aXRoIHRoZSBjbGFzcyBuYW1lXG4gICAgICAgIGlmICh0aGlzLmRlYnVnIHx8ICh0aGVXaW5kb3cgJiYgdGhpcy50b1N0cmluZygpID09PSB0aGVXaW5kb3cuVE9ORV9ERUJVR19DTEFTUykpIHtcbiAgICAgICAgICAgIGxvZyh0aGlzLCAuLi5hcmdzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBkaXNjb25uZWN0IGFuZCBkaXNwb3NlLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMuX3dhc0Rpc3Bvc2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluZGljYXRlcyBpZiB0aGUgaW5zdGFuY2Ugd2FzIGRpc3Bvc2VkLiAnRGlzcG9zaW5nJyBhblxuICAgICAqIGluc3RhbmNlIG1lYW5zIHRoYXQgYWxsIG9mIHRoZSBXZWIgQXVkaW8gbm9kZXMgdGhhdCB3ZXJlXG4gICAgICogY3JlYXRlZCBmb3IgdGhlIGluc3RhbmNlIGFyZSBkaXNjb25uZWN0ZWQgYW5kIGZyZWVkIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24uXG4gICAgICovXG4gICAgZ2V0IGRpc3Bvc2VkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fd2FzRGlzcG9zZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGNsYXNzIHRvIGEgc3RyaW5nXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCk7XG4gICAgICogY29uc29sZS5sb2cob3NjLnRvU3RyaW5nKCkpO1xuICAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lO1xuICAgIH1cbn1cbi8qKlxuICogVGhlIHZlcnNpb24gbnVtYmVyIHNlbXZlclxuICovXG5Ub25lLnZlcnNpb24gPSB2ZXJzaW9uO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZS5qcy5tYXAiLCIvKipcbiAqIFRoZSB0aHJlc2hvbGQgZm9yIGNvcnJlY3RuZXNzIGZvciBvcGVyYXRvcnMuIExlc3MgdGhhbiBvbmUgc2FtcGxlIGV2ZW5cbiAqIGF0IHZlcnkgaGlnaCBzYW1wbGluZyByYXRlcyAoZS5nLiBgMWUtNiA8IDEgLyAxOTIwMDBgKS5cbiAqL1xuY29uc3QgRVBTSUxPTiA9IDFlLTY7XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBncmVhdGVyIHRoYW4gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gR1QoYSwgYikge1xuICAgIHJldHVybiBhID4gYiArIEVQU0lMT047XG59XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gR1RFKGEsIGIpIHtcbiAgICByZXR1cm4gR1QoYSwgYikgfHwgRVEoYSwgYik7XG59XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBsZXNzIHRoYW4gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gTFQoYSwgYikge1xuICAgIHJldHVybiBhICsgRVBTSUxPTiA8IGI7XG59XG4vKipcbiAqIFRlc3QgaWYgQSBpcyBsZXNzIHRoYW4gQlxuICovXG5leHBvcnQgZnVuY3Rpb24gRVEoYSwgYikge1xuICAgIHJldHVybiBNYXRoLmFicyhhIC0gYikgPCBFUFNJTE9OO1xufVxuLyoqXG4gKiBDbGFtcCB0aGUgdmFsdWUgd2l0aGluIHRoZSBnaXZlbiByYW5nZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xhbXAodmFsdWUsIG1pbiwgbWF4KSB7XG4gICAgcmV0dXJuIE1hdGgubWF4KE1hdGgubWluKHZhbHVlLCBtYXgpLCBtaW4pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWF0aC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4vRGVmYXVsdHNcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuL0RlYnVnXCI7XG5pbXBvcnQgeyBFUSwgR1QsIEdURSwgTFQgfSBmcm9tIFwiLi9NYXRoXCI7XG4vKipcbiAqIEEgVGltZWxpbmUgY2xhc3MgZm9yIHNjaGVkdWxpbmcgYW5kIG1haW50YWluaW5nIHN0YXRlXG4gKiBhbG9uZyBhIHRpbWVsaW5lLiBBbGwgZXZlbnRzIG11c3QgaGF2ZSBhIFwidGltZVwiIHByb3BlcnR5LlxuICogSW50ZXJuYWxseSwgZXZlbnRzIGFyZSBzdG9yZWQgaW4gdGltZSBvcmRlciBmb3IgZmFzdFxuICogcmV0cmlldmFsLlxuICovXG5leHBvcnQgY2xhc3MgVGltZWxpbmUgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lbGluZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFycmF5IG9mIHNjaGVkdWxlZCB0aW1lbGluZSBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaW1lbGluZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1lbW9yeVwiXSk7XG4gICAgICAgIHRoaXMubWVtb3J5ID0gb3B0aW9ucy5tZW1vcnk7XG4gICAgICAgIHRoaXMuaW5jcmVhc2luZyA9IG9wdGlvbnMuaW5jcmVhc2luZztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWVtb3J5OiBJbmZpbml0eSxcbiAgICAgICAgICAgIGluY3JlYXNpbmc6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnNlcnQgYW4gZXZlbnQgb2JqZWN0IG9udG8gdGhlIHRpbWVsaW5lLiBFdmVudHMgbXVzdCBoYXZlIGEgXCJ0aW1lXCIgYXR0cmlidXRlLlxuICAgICAqIEBwYXJhbSBldmVudCAgVGhlIGV2ZW50IG9iamVjdCB0byBpbnNlcnQgaW50byB0aGUgdGltZWxpbmUuXG4gICAgICovXG4gICAgYWRkKGV2ZW50KSB7XG4gICAgICAgIC8vIHRoZSBldmVudCBuZWVkcyB0byBoYXZlIGEgdGltZSBhdHRyaWJ1dGVcbiAgICAgICAgYXNzZXJ0KFJlZmxlY3QuaGFzKGV2ZW50LCBcInRpbWVcIiksIFwiVGltZWxpbmU6IGV2ZW50cyBtdXN0IGhhdmUgYSB0aW1lIGF0dHJpYnV0ZVwiKTtcbiAgICAgICAgZXZlbnQudGltZSA9IGV2ZW50LnRpbWUudmFsdWVPZigpO1xuICAgICAgICBpZiAodGhpcy5pbmNyZWFzaW5nICYmIHRoaXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBsYXN0VmFsdWUgPSB0aGlzLl90aW1lbGluZVt0aGlzLmxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgYXNzZXJ0KEdURShldmVudC50aW1lLCBsYXN0VmFsdWUudGltZSksIFwiVGhlIHRpbWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGxhc3Qgc2NoZWR1bGVkIHRpbWVcIik7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5wdXNoKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUuc3BsaWNlKGluZGV4ICsgMSwgMCwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHRoZSBsZW5ndGggaXMgbW9yZSB0aGFuIHRoZSBtZW1vcnksIHJlbW92ZSB0aGUgcHJldmlvdXMgb25lc1xuICAgICAgICBpZiAodGhpcy5sZW5ndGggPiB0aGlzLm1lbW9yeSkge1xuICAgICAgICAgICAgY29uc3QgZGlmZiA9IHRoaXMubGVuZ3RoIC0gdGhpcy5tZW1vcnk7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoMCwgZGlmZik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBldmVudCBmcm9tIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBldmVudCAgVGhlIGV2ZW50IG9iamVjdCB0byByZW1vdmUgZnJvbSB0aGUgbGlzdC5cbiAgICAgKiBAcmV0dXJucyB7VGltZWxpbmV9IHRoaXNcbiAgICAgKi9cbiAgICByZW1vdmUoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl90aW1lbGluZS5pbmRleE9mKGV2ZW50KTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBuZWFyZXN0IGV2ZW50IHdob3NlIHRpbWUgaXMgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0KHRpbWUsIHBhcmFtID0gXCJ0aW1lXCIpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSwgcGFyYW0pO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgd2l0aG91dCByZW1vdmluZyBpdFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBmaXJzdCBldmVudCBvYmplY3RcbiAgICAgKi9cbiAgICBwZWVrKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbMF07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZmlyc3QgZXZlbnQgaW4gdGhlIHRpbWVsaW5lIGFuZCByZW1vdmUgaXRcbiAgICAgKi9cbiAgICBzaGlmdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lLnNoaWZ0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZXZlbnQgd2hpY2ggaXMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0QWZ0ZXIodGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lLCBwYXJhbSk7XG4gICAgICAgIGlmIChpbmRleCArIDEgPCB0aGlzLl90aW1lbGluZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleCArIDFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBldmVudCBiZWZvcmUgdGhlIGV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0QmVmb3JlKHRpbWUpIHtcbiAgICAgICAgY29uc3QgbGVuID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgICAgICAvLyBpZiBpdCdzIGFmdGVyIHRoZSBsYXN0IGl0ZW0sIHJldHVybiB0aGUgbGFzdCBpdGVtXG4gICAgICAgIGlmIChsZW4gPiAwICYmIHRoaXMuX3RpbWVsaW5lW2xlbiAtIDFdLnRpbWUgPCB0aW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbbGVuIC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmIChpbmRleCAtIDEgPj0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgZXZlbnRzIGF0IGFuZCBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5fc2VhcmNoKGFmdGVyKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2luZGV4XS50aW1lLCBhZnRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBmaXJzdCBpdGVtIHdpdGggdGhhdCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBpbmRleDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChFUSh0aGlzLl90aW1lbGluZVtpXS50aW1lLCBhZnRlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IHRoaXMuX3RpbWVsaW5lLnNsaWNlKDAsIGluZGV4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoMCwgaW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3RpbWVsaW5lLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGl0ZW0ncyB0aW1lXG4gICAgICAgICAgICBpZiAoR1RFKHRoaXMuX3RpbWVsaW5lWzBdLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgYmVmb3JlIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gY2FuY2VsIGJlZm9yZS5cbiAgICAgKi9cbiAgICBjYW5jZWxCZWZvcmUodGltZSkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoaW5kZXggKyAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcHJldmlvdXMgZXZlbnQgaWYgdGhlcmUgaXMgb25lLiBudWxsIG90aGVyd2lzZVxuICAgICAqIEBwYXJhbSAgZXZlbnQgVGhlIGV2ZW50IHRvIGZpbmQgdGhlIHByZXZpb3VzIG9uZSBvZlxuICAgICAqIEByZXR1cm4gVGhlIGV2ZW50IHJpZ2h0IGJlZm9yZSB0aGUgZ2l2ZW4gZXZlbnRcbiAgICAgKi9cbiAgICBwcmV2aW91c0V2ZW50KGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdGltZWxpbmUuaW5kZXhPZihldmVudCk7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRG9lcyBhIGJpbmFyeSBzZWFyY2ggb24gdGhlIHRpbWVsaW5lIGFycmF5IGFuZCByZXR1cm5zIHRoZVxuICAgICAqIG5lYXJlc3QgZXZlbnQgaW5kZXggd2hvc2UgdGltZSBpcyBhZnRlciBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBJZiBhIHRpbWUgaXMgc2VhcmNoZWQgYmVmb3JlIHRoZSBmaXJzdCBpbmRleCBpbiB0aGUgdGltZWxpbmUsIC0xIGlzIHJldHVybmVkLlxuICAgICAqIElmIHRoZSB0aW1lIGlzIGFmdGVyIHRoZSBlbmQsIHRoZSBpbmRleCBvZiB0aGUgbGFzdCBpdGVtIGlzIHJldHVybmVkLlxuICAgICAqL1xuICAgIF9zZWFyY2godGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGJlZ2lubmluZyA9IDA7XG4gICAgICAgIGNvbnN0IGxlbiA9IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDtcbiAgICAgICAgbGV0IGVuZCA9IGxlbjtcbiAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV1bcGFyYW1dIDw9IHRpbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBsZW4gLSAxO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChiZWdpbm5pbmcgPCBlbmQpIHtcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgbWlkcG9pbnQgZm9yIHJvdWdobHkgZXF1YWwgcGFydGl0aW9uXG4gICAgICAgICAgICBsZXQgbWlkUG9pbnQgPSBNYXRoLmZsb29yKGJlZ2lubmluZyArIChlbmQgLSBiZWdpbm5pbmcpIC8gMik7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW21pZFBvaW50XTtcbiAgICAgICAgICAgIGNvbnN0IG5leHRFdmVudCA9IHRoaXMuX3RpbWVsaW5lW21pZFBvaW50ICsgMV07XG4gICAgICAgICAgICBpZiAoRVEoZXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgIC8vIGNob29zZSB0aGUgbGFzdCBvbmUgdGhhdCBoYXMgdGhlIHNhbWUgdGltZVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBtaWRQb2ludDsgaSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRlc3RFdmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoRVEodGVzdEV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1pZFBvaW50ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKExUKGV2ZW50W3BhcmFtXSwgdGltZSkgJiYgR1QobmV4dEV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWlkUG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChHVChldmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gc2VhcmNoIGxvd2VyXG4gICAgICAgICAgICAgICAgZW5kID0gbWlkUG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzZWFyY2ggdXBwZXJcbiAgICAgICAgICAgICAgICBiZWdpbm5pbmcgPSBtaWRQb2ludCArIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBpdGVyYXRvci4gQXBwbGllcyBleHRyYSBzYWZldHkgY2hlY2tzIGZvclxuICAgICAqIHJlbW92aW5nIGl0ZW1zIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIF9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kID0gMCwgdXBwZXJCb3VuZCA9IHRoaXMuX3RpbWVsaW5lLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuc2xpY2UobG93ZXJCb3VuZCwgdXBwZXJCb3VuZCArIDEpLmZvckVhY2goY2FsbGJhY2spO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXlcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCBvciBiZWZvcmUgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEJlZm9yZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmICh1cHBlckJvdW5kICE9PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgMCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQWZ0ZXIodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuICAgICAgICBjb25zdCBsb3dlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYmV0d2VlbiB0aGUgc3RhcnRUaW1lIGFuZCBlbmRUaW1lLlxuICAgICAqIFRoZSB0aW1lcmFuZ2UgaXMgaW5jbHVzaXZlIG9mIHRoZSBzdGFydFRpbWUsIGJ1dCBleGNsdXNpdmUgb2YgdGhlIGVuZFRpbWUuXG4gICAgICogcmFuZ2UgPSBbc3RhcnRUaW1lLCBlbmRUaW1lKS5cbiAgICAgKiBAcGFyYW0gIHN0YXJ0VGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBlbmRUaW1lIFRoZSBlbmQgb2YgdGhlIHRlc3QgaW50ZXJ2YWwuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2goc3RhcnRUaW1lKTtcbiAgICAgICAgbGV0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2goZW5kVGltZSk7XG4gICAgICAgIGlmIChsb3dlckJvdW5kICE9PSAtMSAmJiB1cHBlckJvdW5kICE9PSAtMSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW2xvd2VyQm91bmRdLnRpbWUgIT09IHN0YXJ0VGltZSkge1xuICAgICAgICAgICAgICAgIGxvd2VyQm91bmQgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGV4Y2x1c2l2ZSBvZiB0aGUgZW5kIHRpbWVcbiAgICAgICAgICAgIGlmICh0aGlzLl90aW1lbGluZVt1cHBlckJvdW5kXS50aW1lID09PSBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgdXBwZXJCb3VuZCAtPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobG93ZXJCb3VuZCA9PT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIDAsIHVwcGVyQm91bmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYXQgb3IgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuIFNpbWlsYXIgdG9cbiAgICAgKiBmb3JFYWNoQWZ0ZXIsIGJ1dCBpbmNsdWRlcyB0aGUgaXRlbShzKSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoRnJvbSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGxldCBsb3dlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICAvLyB3b3JrIGJhY2t3YXJkcyB1bnRpbCB0aGUgZXZlbnQgdGltZSBpcyBsZXNzIHRoYW4gdGltZVxuICAgICAgICB3aGlsZSAobG93ZXJCb3VuZCA+PSAwICYmIHRoaXMuX3RpbWVsaW5lW2xvd2VyQm91bmRdLnRpbWUgPj0gdGltZSkge1xuICAgICAgICAgICAgbG93ZXJCb3VuZC0tO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBdFRpbWUodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuICAgICAgICBjb25zdCB1cHBlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAodXBwZXJCb3VuZCAhPT0gLTEgJiYgRVEodGhpcy5fdGltZWxpbmVbdXBwZXJCb3VuZF0udGltZSwgdGltZSkpIHtcbiAgICAgICAgICAgIGxldCBsb3dlckJvdW5kID0gdXBwZXJCb3VuZDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSB1cHBlckJvdW5kOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChFUSh0aGlzLl90aW1lbGluZVtpXS50aW1lLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBsb3dlckJvdW5kID0gaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgIH0sIGxvd2VyQm91bmQsIHVwcGVyQm91bmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpbWVsaW5lLmpzLm1hcCIsIi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gSU5JVElBTElaSU5HIE5FVyBDT05URVhUXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogQXJyYXkgb2YgY2FsbGJhY2tzIHRvIGludm9rZSB3aGVuIGEgbmV3IGNvbnRleHQgaXMgY3JlYXRlZFxuICovXG5jb25zdCBub3RpZnlOZXdDb250ZXh0ID0gW107XG4vKipcbiAqIFVzZWQgaW50ZXJuYWxseSB0byBzZXR1cCBhIG5ldyBDb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkNvbnRleHRJbml0KGNiKSB7XG4gICAgbm90aWZ5TmV3Q29udGV4dC5wdXNoKGNiKTtcbn1cbi8qKlxuICogSW52b2tlIGFueSBjbGFzc2VzIHdoaWNoIG5lZWQgdG8gYWxzbyBiZSBpbml0aWFsaXplZCB3aGVuIGEgbmV3IGNvbnRleHQgaXMgY3JlYXRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXRpYWxpemVDb250ZXh0KGN0eCkge1xuICAgIC8vIGFkZCBhbnkgYWRkaXRpb25hbCBtb2R1bGVzXG4gICAgbm90aWZ5TmV3Q29udGV4dC5mb3JFYWNoKGNiID0+IGNiKGN0eCkpO1xufVxuLyoqXG4gKiBBcnJheSBvZiBjYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkXG4gKi9cbmNvbnN0IG5vdGlmeUNsb3NlQ29udGV4dCA9IFtdO1xuLyoqXG4gKiBVc2VkIGludGVybmFsbHkgdG8gdGVhciBkb3duIGEgQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gb25Db250ZXh0Q2xvc2UoY2IpIHtcbiAgICBub3RpZnlDbG9zZUNvbnRleHQucHVzaChjYik7XG59XG5leHBvcnQgZnVuY3Rpb24gY2xvc2VDb250ZXh0KGN0eCkge1xuICAgIC8vIGFkZCBhbnkgYWRkaXRpb25hbCBtb2R1bGVzXG4gICAgbm90aWZ5Q2xvc2VDb250ZXh0LmZvckVhY2goY2IgPT4gY2IoY3R4KSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db250ZXh0SW5pdGlhbGl6YXRpb24uanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc1VuZGVmIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG4vKipcbiAqIEVtaXR0ZXIgZ2l2ZXMgY2xhc3NlcyB3aGljaCBleHRlbmQgaXRcbiAqIHRoZSBhYmlsaXR5IHRvIGxpc3RlbiBmb3IgYW5kIGVtaXQgZXZlbnRzLlxuICogSW5zcGlyYXRpb24gYW5kIHJlZmVyZW5jZSBmcm9tIEplcm9tZSBFdGllbm5lJ3MgW01pY3JvRXZlbnRdKGh0dHBzOi8vZ2l0aHViLmNvbS9qZXJvbWVldGllbm5lL21pY3JvZXZlbnQuanMpLlxuICogTUlUIChjKSAyMDExIEplcm9tZSBFdGllbm5lLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIEVtaXR0ZXIgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFbWl0dGVyXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJpbmQgYSBjYWxsYmFjayB0byBhIHNwZWNpZmljIGV2ZW50LlxuICAgICAqIEBwYXJhbSAgZXZlbnQgICAgIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gZm9yLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZFxuICAgICAqL1xuICAgIG9uKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICAvLyBzcGxpdCB0aGUgZXZlbnRcbiAgICAgICAgY29uc3QgZXZlbnRzID0gZXZlbnQuc3BsaXQoL1xcVysvKTtcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHRoaXMuX2V2ZW50cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50TmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZlbnROYW1lXSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50TmFtZV0ucHVzaChjYWxsYmFjayk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGNhbGxiYWNrIHdoaWNoIGlzIG9ubHkgaW52b2tlZCBvbmNlXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gICAgICovXG4gICAgb25jZShldmVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgYm91bmRDYWxsYmFjayA9ICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICBjYWxsYmFjayguLi5hcmdzKTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgZXZlbnRcbiAgICAgICAgICAgIHRoaXMub2ZmKGV2ZW50LCBib3VuZENhbGxiYWNrKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vbihldmVudCwgYm91bmRDYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgICAgIFRoZSBldmVudCB0byBzdG9wIGxpc3RlbmluZyB0by5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgd2hpY2ggd2FzIGJvdW5kIHRvIHRoZSBldmVudCB3aXRoIEVtaXR0ZXIub24uXG4gICAgICogICAgICAgICAgICAgICAgICAgSWYgbm8gY2FsbGJhY2sgaXMgZ2l2ZW4sIGFsbCBjYWxsYmFja3MgZXZlbnRzIGFyZSByZW1vdmVkLlxuICAgICAqL1xuICAgIG9mZihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gZXZlbnQuc3BsaXQoL1xcVysvKTtcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHRoaXMuX2V2ZW50cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzVW5kZWYoY2FsbGJhY2spKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudF0gPSBbXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBldmVudExpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudExpc3RbaV0gPT09IGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRMaXN0LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgYWxsIG9mIHRoZSBjYWxsYmFja3MgYm91bmQgdG8gdGhlIGV2ZW50XG4gICAgICogd2l0aCBhbnkgYXJndW1lbnRzIHBhc3NlZCBpbi5cbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQuXG4gICAgICogQHBhcmFtIGFyZ3MgVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBmdW5jdGlvbnMgbGlzdGVuaW5nLlxuICAgICAqL1xuICAgIGVtaXQoZXZlbnQsIC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudExpc3QgPSB0aGlzLl9ldmVudHNbZXZlbnRdLnNsaWNlKDApO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBldmVudExpc3QubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRMaXN0W2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIEVtaXR0ZXIgZnVuY3Rpb25zIChvbi9vZmYvZW1pdCkgdG8gdGhlIG9iamVjdFxuICAgICAqL1xuICAgIHN0YXRpYyBtaXhpbihjb25zdHIpIHtcbiAgICAgICAgLy8gaW5zdGFuY2UuX2V2ZW50cyA9IHt9O1xuICAgICAgICBbXCJvblwiLCBcIm9uY2VcIiwgXCJvZmZcIiwgXCJlbWl0XCJdLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm9wZXJ0eSA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoRW1pdHRlci5wcm90b3R5cGUsIG5hbWUpO1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnN0ci5wcm90b3R5cGUsIG5hbWUsIHByb3BlcnR5KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVtaXR0ZXIuanMubWFwIiwiaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi91dGlsL0VtaXR0ZXJcIjtcbmV4cG9ydCBjbGFzcyBCYXNlQ29udGV4dCBleHRlbmRzIEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IGZhbHNlO1xuICAgIH1cbiAgICAvKlxuICAgICAqIFRoaXMgaXMgYSBwbGFjZWhvbGRlciBzbyB0aGF0IEpTT04uc3RyaW5naWZ5IGRvZXMgbm90IHRocm93IGFuIGVycm9yXG4gICAgICogVGhpcyBtYXRjaGVzIHdoYXQgSlNPTi5zdHJpbmdpZnkoYXVkaW9Db250ZXh0KSByZXR1cm5zIG9uIGEgbmF0aXZlXG4gICAgICogYXVkaW9Db250ZXh0IGluc3RhbmNlLlxuICAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJhc2VDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVGlja2VyIH0gZnJvbSBcIi4uL2Nsb2NrL1RpY2tlclwiO1xuaW1wb3J0IHsgaXNBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc1N0cmluZyB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Db250ZXh0LCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlLCB9IGZyb20gXCIuL0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgY2xvc2VDb250ZXh0LCBpbml0aWFsaXplQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuaW1wb3J0IHsgQmFzZUNvbnRleHQgfSBmcm9tIFwiLi9CYXNlQ29udGV4dFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgQ29udGV4dCBleHRlbmRzIEJhc2VDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb250ZXh0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBvYmplY3QgY29udGFpbmluZyBhbGwgb2YgdGhlIGNvbnN0YW50cyBBdWRpb0J1ZmZlclNvdXJjZU5vZGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb25zdGFudHMgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIHNldFRpbWVvdXQgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dHMgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lb3V0IGlkIGNvdW50ZXJcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVvdXRJZHMgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSBpbmRpY2F0b3IgaWYgdGhlIGNvbnRleHQgaGFzIGJlZW4gaW5pdGlhbGl6ZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGNvbnRleHQgaXMgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCBvciBhbiBBdWRpb0NvbnRleHRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gQVVESU8gV09SS0xFVFxuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNYXBzIGEgbW9kdWxlIG5hbWUgdG8gcHJvbWlzZSBvZiB0aGUgYWRkTW9kdWxlIG1ldGhvZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDb250ZXh0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1xuICAgICAgICAgICAgXCJjb250ZXh0XCIsXG4gICAgICAgIF0pO1xuICAgICAgICBpZiAob3B0aW9ucy5jb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY29udGV4dCA9IGNyZWF0ZUF1ZGlvQ29udGV4dCh7XG4gICAgICAgICAgICAgICAgbGF0ZW5jeUhpbnQ6IG9wdGlvbnMubGF0ZW5jeUhpbnQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90aWNrZXIgPSBuZXcgVGlja2VyKHRoaXMuZW1pdC5iaW5kKHRoaXMsIFwidGlja1wiKSwgb3B0aW9ucy5jbG9ja1NvdXJjZSwgb3B0aW9ucy51cGRhdGVJbnRlcnZhbCk7XG4gICAgICAgIHRoaXMub24oXCJ0aWNrXCIsIHRoaXMuX3RpbWVvdXRMb29wLmJpbmQodGhpcykpO1xuICAgICAgICAvLyBmd2QgZXZlbnRzIGZyb20gdGhlIGNvbnRleHRcbiAgICAgICAgdGhpcy5fY29udGV4dC5vbnN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhdGVjaGFuZ2VcIiwgdGhpcy5zdGF0ZSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX3NldExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpO1xuICAgICAgICB0aGlzLmxvb2tBaGVhZCA9IG9wdGlvbnMubG9va0FoZWFkO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjbG9ja1NvdXJjZTogXCJ3b3JrZXJcIixcbiAgICAgICAgICAgIGxhdGVuY3lIaW50OiBcImludGVyYWN0aXZlXCIsXG4gICAgICAgICAgICBsb29rQWhlYWQ6IDAuMSxcbiAgICAgICAgICAgIHVwZGF0ZUludGVydmFsOiAwLjA1LFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5pc2ggc2V0dGluZyB1cCB0aGUgY29udGV4dC4gKipZb3UgdXN1YWxseSBkbyBub3QgbmVlZCB0byBkbyB0aGlzIG1hbnVhbGx5LioqXG4gICAgICovXG4gICAgaW5pdGlhbGl6ZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9pbml0aWFsaXplZCkge1xuICAgICAgICAgICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICAgICAgICAgIGluaXRpYWxpemVDb250ZXh0KHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEJBU0UgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBbmFseXNlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlT3NjaWxsYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXJTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIH1cbiAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsTWVyZ2VyKG51bWJlck9mSW5wdXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIobnVtYmVyT2ZJbnB1dHMpO1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsU3BsaXR0ZXIobnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMpO1xuICAgIH1cbiAgICBjcmVhdGVDb25zdGFudFNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ29uc3RhbnRTb3VyY2UoKTtcbiAgICB9XG4gICAgY3JlYXRlQ29udm9sdmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZURlbGF5KG1heERlbGF5VGltZSk7XG4gICAgfVxuICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgfVxuICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICB9XG4gICAgY3JlYXRlSUlSRmlsdGVyKGZlZWRGb3J3YXJkLCBmZWVkYmFjaykge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihmZWVkRm9yd2FyZCwgZmVlZGJhY2spO1xuICAgIH1cbiAgICBjcmVhdGVQYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgIH1cbiAgICBjcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlKHJlYWwsIGltYWcsIGNvbnN0cmFpbnRzKTtcbiAgICB9XG4gICAgY3JlYXRlU3RlcmVvUGFubmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShlbGVtZW50KSB7XG4gICAgICAgIGFzc2VydChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSwgXCJOb3QgYXZhaWxhYmxlIGlmIE9mZmxpbmVBdWRpb0NvbnRleHRcIik7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICByZXR1cm4gY29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UoZWxlbWVudCk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKSB7XG4gICAgICAgIGFzc2VydChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSwgXCJOb3QgYXZhaWxhYmxlIGlmIE9mZmxpbmVBdWRpb0NvbnRleHRcIik7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICByZXR1cm4gY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCk7XG4gICAgfVxuICAgIGRlY29kZUF1ZGlvRGF0YShhdWRpb0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgQXVkaW9Db250ZXh0LlxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgQXVkaW9Db250ZXh0LlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgQXVkaW9Db250ZXh0LlxuICAgICAqL1xuICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdGVuZXJcbiAgICAgKi9cbiAgICBnZXQgbGlzdGVuZXIoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbGlzdGVuZXI7XG4gICAgfVxuICAgIHNldCBsaXN0ZW5lcihsKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5faW5pdGlhbGl6ZWQsIFwiVGhlIGxpc3RlbmVyIGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl9saXN0ZW5lciA9IGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZXJlIGlzIG9ubHkgb25lIFRyYW5zcG9ydCBwZXIgQ29udGV4dC4gSXQgaXMgY3JlYXRlZCBvbiBpbml0aWFsaXphdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgdHJhbnNwb3J0KCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RyYW5zcG9ydDtcbiAgICB9XG4gICAgc2V0IHRyYW5zcG9ydCh0KSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5faW5pdGlhbGl6ZWQsIFwiVGhlIHRyYW5zcG9ydCBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fdHJhbnNwb3J0ID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhpcyBpcyB0aGUgRHJhdyBvYmplY3QgZm9yIHRoZSBjb250ZXh0IHdoaWNoIGlzIHVzZWZ1bCBmb3Igc3luY2hyb25pemluZyB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUb25lLmpzIGNsb2NrLlxuICAgICAqL1xuICAgIGdldCBkcmF3KCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RyYXc7XG4gICAgfVxuICAgIHNldCBkcmF3KGQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJEcmF3IGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl9kcmF3ID0gZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWZlcmVuY2UgdG8gdGhlIENvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqL1xuICAgIGdldCBkZXN0aW5hdGlvbigpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXN0aW5hdGlvbjtcbiAgICB9XG4gICAgc2V0IGRlc3RpbmF0aW9uKGQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgZGVzdGluYXRpb24gY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2Rlc3RpbmF0aW9uID0gZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFuIGF1ZGlvIHdvcmtsZXQgbm9kZSBmcm9tIGEgbmFtZSBhbmQgb3B0aW9ucy4gVGhlIG1vZHVsZVxuICAgICAqIG11c3QgZmlyc3QgYmUgbG9hZGVkIHVzaW5nIFtbYWRkQXVkaW9Xb3JrbGV0TW9kdWxlXV0uXG4gICAgICovXG4gICAgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShuYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKHRoaXMucmF3Q29udGV4dCwgbmFtZSwgb3B0aW9ucyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgbW9kdWxlXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBtb2R1bGVcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlXG4gICAgICovXG4gICAgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKHVybCwgbmFtZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZCh0aGlzLnJhd0NvbnRleHQuYXVkaW9Xb3JrbGV0KSwgXCJBdWRpb1dvcmtsZXROb2RlIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgc2VjdXJlIGNvbnRleHQgKGh0dHBzIG9yIGxvY2FsaG9zdClcIik7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3dvcmtsZXRNb2R1bGVzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXRNb2R1bGVzLnNldChuYW1lLCB0aGlzLnJhd0NvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZSh1cmwpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHlpZWxkIHRoaXMuX3dvcmtsZXRNb2R1bGVzLmdldChuYW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gYWxsIG9mIHRoZSB3b3JrbGV0cyBoYXZlIGJlZW4gbG9hZGVkIG9uIHRoaXMgY29udGV4dFxuICAgICAqL1xuICAgIHdvcmtsZXRzQXJlUmVhZHkoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMuZm9yRWFjaCgocHJvbWlzZSkgPT4gcHJvbWlzZXMucHVzaChwcm9taXNlKSk7XG4gICAgICAgICAgICB5aWVsZCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFRJQ0tFUlxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogSG93IG9mdGVuIHRoZSBpbnRlcnZhbCBjYWxsYmFjayBpcyBpbnZva2VkLlxuICAgICAqIFRoaXMgbnVtYmVyIGNvcnJlc3BvbmRzIHRvIGhvdyByZXNwb25zaXZlIHRoZSBzY2hlZHVsaW5nXG4gICAgICogY2FuIGJlLiBjb250ZXh0LnVwZGF0ZUludGVydmFsICsgY29udGV4dC5sb29rQWhlYWQgZ2l2ZXMgeW91IHRoZVxuICAgICAqIHRvdGFsIGxhdGVuY3kgYmV0d2VlbiBzY2hlZHVsaW5nIGFuIGV2ZW50IGFuZCBoZWFyaW5nIGl0LlxuICAgICAqL1xuICAgIGdldCB1cGRhdGVJbnRlcnZhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tlci51cGRhdGVJbnRlcnZhbDtcbiAgICB9XG4gICAgc2V0IHVwZGF0ZUludGVydmFsKGludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX3RpY2tlci51cGRhdGVJbnRlcnZhbCA9IGludGVydmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGF0IHRoZSBzb3VyY2Ugb2YgdGhlIGNsb2NrIGlzLCBlaXRoZXIgXCJ3b3JrZXJcIiAoZGVmYXVsdCksXG4gICAgICogXCJ0aW1lb3V0XCIsIG9yIFwib2ZmbGluZVwiIChub25lKS5cbiAgICAgKi9cbiAgICBnZXQgY2xvY2tTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IGNsb2NrU291cmNlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdGlja2VyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiBwbGF5YmFjaywgd2hpY2ggYWZmZWN0cyB0cmFkZW9mZnMgYmV0d2VlbiBhdWRpb1xuICAgICAqIG91dHB1dCBsYXRlbmN5IGFuZCByZXNwb25zaXZlbmVzcy5cbiAgICAgKiBJbiBhZGRpdGlvbiB0byBzZXR0aW5nIHRoZSB2YWx1ZSBpbiBzZWNvbmRzLCB0aGUgbGF0ZW5jeUhpbnQgYWxzb1xuICAgICAqIGFjY2VwdHMgdGhlIHN0cmluZ3MgXCJpbnRlcmFjdGl2ZVwiIChwcmlvcml0aXplcyBsb3cgbGF0ZW5jeSksXG4gICAgICogXCJwbGF5YmFja1wiIChwcmlvcml0aXplcyBzdXN0YWluZWQgcGxheWJhY2spLCBcImJhbGFuY2VkXCIgKGJhbGFuY2VzXG4gICAgICogbGF0ZW5jeSBhbmQgcGVyZm9ybWFuY2UpLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gcHJpb3JpdGl6ZSBzdXN0YWluZWQgcGxheWJhY2tcbiAgICAgKiBjb25zdCBjb250ZXh0ID0gbmV3IFRvbmUuQ29udGV4dCh7IGxhdGVuY3lIaW50OiBcInBsYXliYWNrXCIgfSk7XG4gICAgICogLy8gc2V0IHRoaXMgY29udGV4dCBhcyB0aGUgZ2xvYmFsIENvbnRleHRcbiAgICAgKiBUb25lLnNldENvbnRleHQoY29udGV4dCk7XG4gICAgICogLy8gdGhlIGdsb2JhbCBjb250ZXh0IGlzIGdldHRhYmxlIHdpdGggVG9uZS5nZXRDb250ZXh0KClcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLmdldENvbnRleHQoKS5sYXRlbmN5SGludCk7XG4gICAgICovXG4gICAgZ2V0IGxhdGVuY3lIaW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGF0ZW5jeUhpbnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgbG9va0FoZWFkIGFuZCB1cGRhdGVJbnRlcnZhbCBiYXNlZCBvbiB0aGUgbGF0ZW5jeUhpbnRcbiAgICAgKi9cbiAgICBfc2V0TGF0ZW5jeUhpbnQoaGludCkge1xuICAgICAgICBsZXQgbG9va0FoZWFkVmFsdWUgPSAwO1xuICAgICAgICB0aGlzLl9sYXRlbmN5SGludCA9IGhpbnQ7XG4gICAgICAgIGlmIChpc1N0cmluZyhoaW50KSkge1xuICAgICAgICAgICAgc3dpdGNoIChoaW50KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcImludGVyYWN0aXZlXCI6XG4gICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZFZhbHVlID0gMC4xO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwicGxheWJhY2tcIjpcbiAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkVmFsdWUgPSAwLjU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJiYWxhbmNlZFwiOlxuICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWRWYWx1ZSA9IDAuMjU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gbG9va0FoZWFkVmFsdWU7XG4gICAgICAgIHRoaXMudXBkYXRlSW50ZXJ2YWwgPSBsb29rQWhlYWRWYWx1ZSAvIDI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB1bndyYXBwZWQgQXVkaW9Db250ZXh0IG9yIE9mZmxpbmVBdWRpb0NvbnRleHRcbiAgICAgKi9cbiAgICBnZXQgcmF3Q29udGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBwbHVzIGEgc2hvcnQgW1tsb29rQWhlYWRdXS5cbiAgICAgKi9cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmN1cnJlbnRUaW1lICsgdGhpcy5sb29rQWhlYWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSB3aXRob3V0IHRoZSBbW2xvb2tBaGVhZF1dLlxuICAgICAqIEluIG1vc3QgY2FzZXMgaXQgaXMgYmV0dGVyIHRvIHVzZSBbW25vd11dIGluc3RlYWQgb2YgW1tpbW1lZGlhdGVdXSBzaW5jZVxuICAgICAqIHdpdGggW1tub3ddXSB0aGUgW1tsb29rQWhlYWRdXSBpcyBhcHBsaWVkIGVxdWFsbHkgdG8gX2FsbF8gY29tcG9uZW50cyBpbmNsdWRpbmcgaW50ZXJuYWwgY29tcG9uZW50cyxcbiAgICAgKiB0byBtYWtpbmcgc3VyZSB0aGF0IGV2ZXJ5dGhpbmcgaXMgc2NoZWR1bGVkIGluIHN5bmMuIE1peGluZyBbW25vd11dIGFuZCBbW2ltbWVkaWF0ZV1dXG4gICAgICogY2FuIGNhdXNlIHNvbWUgdGltaW5nIGlzc3Vlcy4gSWYgbm8gbG9va0FoZWFkIGlzIGRlc2lyZWQsIHlvdSBjYW4gc2V0IHRoZSBbW2xvb2tBaGVhZF1dIHRvIGAwYC5cbiAgICAgKi9cbiAgICBpbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydHMgdGhlIGF1ZGlvIGNvbnRleHQgZnJvbSBhIHN1c3BlbmRlZCBzdGF0ZS4gVGhpcyBpcyByZXF1aXJlZFxuICAgICAqIHRvIGluaXRpYWxseSBzdGFydCB0aGUgQXVkaW9Db250ZXh0LiBTZWUgW1tUb25lLnN0YXJ0XV1cbiAgICAgKi9cbiAgICByZXN1bWUoKSB7XG4gICAgICAgIGlmIChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQucmVzdW1lKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIGNvbnRleHQuIE9uY2UgY2xvc2VkLCB0aGUgY29udGV4dCBjYW4gbm8gbG9uZ2VyIGJlIHVzZWQgYW5kXG4gICAgICogYW55IEF1ZGlvTm9kZXMgY3JlYXRlZCBmcm9tIHRoZSBjb250ZXh0IHdpbGwgYmUgc2lsZW50LlxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgaWYgKGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgeWllbGQgdGhpcy5fY29udGV4dC5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAgICAgY2xvc2VDb250ZXh0KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKipJbnRlcm5hbCoqIEdlbmVyYXRlIGEgbG9vcGVkIGJ1ZmZlciBhdCBzb21lIGNvbnN0YW50IHZhbHVlLlxuICAgICAqL1xuICAgIGdldENvbnN0YW50KHZhbCkge1xuICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRzLmhhcyh2YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29uc3RhbnRzLmdldCh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMTI4LCB0aGlzLl9jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3QgYXJyID0gYnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBhcnJbaV0gPSB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb25zdGFudCA9IHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgICAgICBjb25zdGFudC5jaGFubmVsQ291bnQgPSAxO1xuICAgICAgICAgICAgY29uc3RhbnQuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgICAgIGNvbnN0YW50LmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0YW50Lmxvb3AgPSB0cnVlO1xuICAgICAgICAgICAgY29uc3RhbnQuc3RhcnQoMCk7XG4gICAgICAgICAgICB0aGlzLl9jb25zdGFudHMuc2V0KHZhbCwgY29uc3RhbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGNvbnN0YW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLiBBbHNvIGNsb3NlcyB0aGUgYXVkaW8gY29udGV4dC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpY2tlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRzLmRpc3Bvc2UoKTtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5fY29uc3RhbnRzKS5tYXAoKHZhbCkgPT4gdGhpcy5fY29uc3RhbnRzW3ZhbF0uZGlzY29ubmVjdCgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVElNRU9VVFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRoZSBwcml2YXRlIGxvb3Agd2hpY2gga2VlcHMgdHJhY2sgb2YgdGhlIGNvbnRleHQgc2NoZWR1bGVkIHRpbWVvdXRzXG4gICAgICogSXMgaW52b2tlZCBmcm9tIHRoZSBjbG9jayBzb3VyY2VcbiAgICAgKi9cbiAgICBfdGltZW91dExvb3AoKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGxldCBmaXJzdEV2ZW50ID0gdGhpcy5fdGltZW91dHMucGVlaygpO1xuICAgICAgICB3aGlsZSAodGhpcy5fdGltZW91dHMubGVuZ3RoICYmIGZpcnN0RXZlbnQgJiYgZmlyc3RFdmVudC50aW1lIDw9IG5vdykge1xuICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgZmlyc3RFdmVudC5jYWxsYmFjaygpO1xuICAgICAgICAgICAgLy8gc2hpZnQgdGhlIGZpcnN0IGV2ZW50IG9mZlxuICAgICAgICAgICAgdGhpcy5fdGltZW91dHMuc2hpZnQoKTtcbiAgICAgICAgICAgIC8vIGdldCB0aGUgbmV4dCBvbmVcbiAgICAgICAgICAgIGZpcnN0RXZlbnQgPSB0aGlzLl90aW1lb3V0cy5wZWVrKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBzZXRUaW1lb3V0IHdoaWNoIGlzIGd1YXJhbnRlZWQgYnkgdGhlIGNsb2NrIHNvdXJjZS5cbiAgICAgKiBBbHNvIHJ1bnMgaW4gdGhlIG9mZmxpbmUgY29udGV4dC5cbiAgICAgKiBAcGFyYW0gIGZuICAgICAgIFRoZSBjYWxsYmFjayB0byBpbnZva2VcbiAgICAgKiBAcGFyYW0gIHRpbWVvdXQgIFRoZSB0aW1lb3V0IGluIHNlY29uZHNcbiAgICAgKiBAcmV0dXJucyBJRCB0byB1c2Ugd2hlbiBpbnZva2luZyBDb250ZXh0LmNsZWFyVGltZW91dFxuICAgICAqL1xuICAgIHNldFRpbWVvdXQoZm4sIHRpbWVvdXQpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dElkcysrO1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl90aW1lb3V0cy5hZGQoe1xuICAgICAgICAgICAgY2FsbGJhY2s6IGZuLFxuICAgICAgICAgICAgaWQ6IHRoaXMuX3RpbWVvdXRJZHMsXG4gICAgICAgICAgICB0aW1lOiBub3cgKyB0aW1lb3V0LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVvdXRJZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFycyBhIHByZXZpb3VzbHkgc2NoZWR1bGVkIHRpbWVvdXQgd2l0aCBUb25lLmNvbnRleHQuc2V0VGltZW91dFxuICAgICAqIEBwYXJhbSAgaWQgIFRoZSBJRCByZXR1cm5lZCBmcm9tIHNldFRpbWVvdXRcbiAgICAgKi9cbiAgICBjbGVhclRpbWVvdXQoaWQpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dHMuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5pZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5yZW1vdmUoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBmdW5jdGlvbiBzY2hlZHVsZWQgYnkgW1tzZXRJbnRlcnZhbF1dXG4gICAgICovXG4gICAgY2xlYXJJbnRlcnZhbChpZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jbGVhclRpbWVvdXQoaWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgcmVwZWF0aW5nIGV2ZW50IHRvIHRoZSBjb250ZXh0J3MgY2FsbGJhY2sgY2xvY2tcbiAgICAgKi9cbiAgICBzZXRJbnRlcnZhbChmbiwgaW50ZXJ2YWwpIHtcbiAgICAgICAgY29uc3QgaWQgPSArK3RoaXMuX3RpbWVvdXRJZHM7XG4gICAgICAgIGNvbnN0IGludGVydmFsRm4gPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgdGhpcy5fdGltZW91dHMuYWRkKHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgICAgIGZuKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgZXZlbnQgdG8gcmVwZWF0IGl0XG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsRm4oKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICAgIHRpbWU6IG5vdyArIGludGVydmFsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIGtpY2sgaXQgb2ZmXG4gICAgICAgIGludGVydmFsRm4oKTtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBCYXNlQ29udGV4dCB9IGZyb20gXCIuL0Jhc2VDb250ZXh0XCI7XG5leHBvcnQgY2xhc3MgRHVtbXlDb250ZXh0IGV4dGVuZHMgQmFzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmxvb2tBaGVhZCA9IDA7XG4gICAgICAgIHRoaXMubGF0ZW5jeUhpbnQgPSAwO1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IGZhbHNlO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEJBU0UgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBbmFseXNlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVPc2NpbGxhdG9yKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyKF9udW1iZXJPZkNoYW5uZWxzLCBfbGVuZ3RoLCBfc2FtcGxlUmF0ZSkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxNZXJnZXIoX251bWJlck9mSW5wdXRzKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKF9udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDb25zdGFudFNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlRGVsYXkoX21heERlbGF5VGltZSkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVHYWluKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUlJUkZpbHRlcihfZmVlZEZvcndhcmQsIF9mZWVkYmFjaykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVBhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVQZXJpb2RpY1dhdmUoX3JlYWwsIF9pbWFnLCBfY29uc3RyYWludHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVTdGVyZW9QYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShfc3RyZWFtKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKF9lbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBkZWNvZGVBdWRpb0RhdGEoX2F1ZGlvRGF0YSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUT05FIEFVRElPIENPTlRFWFQgTUVUSE9EU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShfbmFtZSwgX29wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgcmF3Q29udGV4dCgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUoX3VybCwgX25hbWUpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlc3VtZSgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBzZXRUaW1lb3V0KF9mbiwgX3RpbWVvdXQpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNsZWFyVGltZW91dChfaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldEludGVydmFsKF9mbiwgX2ludGVydmFsKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjbGVhckludGVydmFsKF9pZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0Q29uc3RhbnQoX3ZhbCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgdHJhbnNwb3J0KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBkcmF3KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHNldCBkcmF3KF9kKSB7IH1cbiAgICBnZXQgZGVzdGluYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgc2V0IGRlc3RpbmF0aW9uKF9kKSB7IH1cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUR1bW15Q29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBpc0FycmF5IH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG4vKipcbiAqIE1ha2UgdGhlIHByb3BlcnR5IG5vdCB3cml0YWJsZSB1c2luZyBgZGVmaW5lUHJvcGVydHlgLiBJbnRlcm5hbCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRPbmx5KHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICBpZiAoaXNBcnJheShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvcGVydHkuZm9yRWFjaChzdHIgPT4gcmVhZE9ubHkodGFyZ2V0LCBzdHIpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7XG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2UgYW4gYXR0cmlidXRlIHdyaXRlYWJsZS4gSW50ZXJuYWwgdXNlIG9ubHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cml0YWJsZSh0YXJnZXQsIHByb3BlcnR5KSB7XG4gICAgaWYgKGlzQXJyYXkocHJvcGVydHkpKSB7XG4gICAgICAgIHByb3BlcnR5LmZvckVhY2goc3RyID0+IHdyaXRhYmxlKHRhcmdldCwgc3RyKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwge1xuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmV4cG9ydCBjb25zdCBub09wID0gKCkgPT4ge1xuICAgIC8vIG5vIG9wZXJhdGlvbiBoZXJlIVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUludGVyZmFjZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNOdW1iZXIsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBBdWRpb0J1ZmZlciBsb2FkaW5nIGFuZCBzdG9yYWdlLiBUb25lQXVkaW9CdWZmZXIgaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IGFsbFxuICogY2xhc3NlcyB0aGF0IG1ha2UgcmVxdWVzdHMgZm9yIGF1ZGlvIGZpbGVzIHN1Y2ggYXMgVG9uZS5QbGF5ZXIsXG4gKiBUb25lLlNhbXBsZXIgYW5kIFRvbmUuQ29udm9sdmVyLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGJ1ZmZlciA9IG5ldyBUb25lLlRvbmVBdWRpb0J1ZmZlcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMS5tcDNcIiwgKCkgPT4ge1xuICogXHRjb25zb2xlLmxvZyhcImxvYWRlZFwiKTtcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb0J1ZmZlciBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb0J1ZmZlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25sb2FkID0gbm9PcDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVBdWRpb0J1ZmZlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiLCBcIm9uZXJyb3JcIl0pO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSBvcHRpb25zLnJldmVyc2U7XG4gICAgICAgIHRoaXMub25sb2FkID0gb3B0aW9ucy5vbmxvYWQ7XG4gICAgICAgIGlmIChvcHRpb25zLnVybCAmJiBpc0F1ZGlvQnVmZmVyKG9wdGlvbnMudXJsKSB8fCBvcHRpb25zLnVybCBpbnN0YW5jZW9mIFRvbmVBdWRpb0J1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5zZXQob3B0aW9ucy51cmwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKG9wdGlvbnMudXJsKSkge1xuICAgICAgICAgICAgLy8gaW5pdGlhdGUgdGhlIGRvd25sb2FkXG4gICAgICAgICAgICB0aGlzLmxvYWQob3B0aW9ucy51cmwpLmNhdGNoKG9wdGlvbnMub25lcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIHJldmVyc2U6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2FtcGxlIHJhdGUgb2YgdGhlIEF1ZGlvQnVmZmVyXG4gICAgICovXG4gICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRDb250ZXh0KCkuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXNzIGluIGFuIEF1ZGlvQnVmZmVyIG9yIFRvbmVBdWRpb0J1ZmZlciB0byBzZXQgdGhlIHZhbHVlIG9mIHRoaXMgYnVmZmVyLlxuICAgICAqL1xuICAgIHNldChidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlciBpbnN0YW5jZW9mIFRvbmVBdWRpb0J1ZmZlcikge1xuICAgICAgICAgICAgLy8gaWYgaXQncyBsb2FkZWQsIHNldCBpdFxuICAgICAgICAgICAgaWYgKGJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXIuZ2V0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2Ugd2hlbiBpdCdzIGxvYWRlZCwgaW52b2tlIGl0J3MgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICBidWZmZXIub25sb2FkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldChidWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ubG9hZCh0aGlzKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJldmVyc2UgaXQgaW5pdGlhbGx5XG4gICAgICAgIGlmICh0aGlzLl9yZXZlcnNlZCkge1xuICAgICAgICAgICAgdGhpcy5fcmV2ZXJzZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gYnVmZmVyIHN0b3JlZCBpbiB0aGUgb2JqZWN0LlxuICAgICAqL1xuICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFrZXMgYW4gZmV0Y2ggcmVxdWVzdCBmb3IgdGhlIHNlbGVjdGVkIHVybCB0aGVuIGRlY29kZXMgdGhlIGZpbGUgYXMgYW4gYXVkaW8gYnVmZmVyLlxuICAgICAqIEludm9rZXMgdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGF1ZGlvIGJ1ZmZlciBsb2Fkcy5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIGJ1ZmZlciB0byBsb2FkLiBmaWxldHlwZSBzdXBwb3J0IGRlcGVuZHMgb24gdGhlIGJyb3dzZXIuXG4gICAgICogQHJldHVybnMgQSBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdGhpcyBUb25lQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgZG9uZUxvYWRpbmcgPSBUb25lQXVkaW9CdWZmZXIubG9hZCh1cmwpLnRoZW4oYXVkaW9CdWZmZXIgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0KGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAvLyBpbnZva2UgdGhlIG9ubG9hZCBtZXRob2RcbiAgICAgICAgICAgICAgICB0aGlzLm9ubG9hZCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5wdXNoKGRvbmVMb2FkaW5nKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgeWllbGQgZG9uZUxvYWRpbmc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIGRvd25sb2FkZWQgZmlsZVxuICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5pbmRleE9mKGRvbmVMb2FkaW5nKTtcbiAgICAgICAgICAgICAgICBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGF1ZGlvIGJ1ZmZlciBmcm9tIHRoZSBhcnJheS5cbiAgICAgKiBUbyBjcmVhdGUgYSBtdWx0aWNoYW5uZWwgQXVkaW9CdWZmZXIsIHBhc3MgaW4gYSBtdWx0aWRpbWVuc2lvbmFsIGFycmF5LlxuICAgICAqIEBwYXJhbSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbCB0aGUgYXVkaW8gYnVmZmVyXG4gICAgICovXG4gICAgZnJvbUFycmF5KGFycmF5KSB7XG4gICAgICAgIGNvbnN0IGlzTXVsdGlkaW1lbnNpb25hbCA9IGlzQXJyYXkoYXJyYXkpICYmIGFycmF5WzBdLmxlbmd0aCA+IDA7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxzID0gaXNNdWx0aWRpbWVuc2lvbmFsID8gYXJyYXkubGVuZ3RoIDogMTtcbiAgICAgICAgY29uc3QgbGVuID0gaXNNdWx0aWRpbWVuc2lvbmFsID8gYXJyYXlbMF0ubGVuZ3RoIDogYXJyYXkubGVuZ3RoO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gZ2V0Q29udGV4dCgpO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBjb250ZXh0LmNyZWF0ZUJ1ZmZlcihjaGFubmVscywgbGVuLCBjb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBtdWx0aUNoYW5uZWxBcnJheSA9ICFpc011bHRpZGltZW5zaW9uYWwgJiYgY2hhbm5lbHMgPT09IDEgP1xuICAgICAgICAgICAgW2FycmF5XSA6IGFycmF5O1xuICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNoYW5uZWxzOyBjKyspIHtcbiAgICAgICAgICAgIGJ1ZmZlci5jb3B5VG9DaGFubmVsKG11bHRpQ2hhbm5lbEFycmF5W2NdLCBjKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXI7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdW1zIG11bHRpcGxlIGNoYW5uZWxzIGludG8gMSBjaGFubmVsXG4gICAgICogQHBhcmFtIGNoYW5OdW0gT3B0aW9uYWxseSBvbmx5IGNvcHkgYSBzaW5nbGUgY2hhbm5lbCBmcm9tIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICB0b01vbm8oY2hhbk51bSkge1xuICAgICAgICBpZiAoaXNOdW1iZXIoY2hhbk51bSkpIHtcbiAgICAgICAgICAgIHRoaXMuZnJvbUFycmF5KHRoaXMudG9BcnJheShjaGFuTnVtKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgb3V0cHV0QXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMubGVuZ3RoKTtcbiAgICAgICAgICAgIGNvbnN0IG51bUNoYW5uZWxzID0gdGhpcy5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBudW1DaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbEFycmF5ID0gdGhpcy50b0FycmF5KGNoYW5uZWwpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbEFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dEFycmF5W2ldICs9IGNoYW5uZWxBcnJheVtpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBkaXZpZGUgYnkgdGhlIG51bWJlciBvZiBjaGFubmVsc1xuICAgICAgICAgICAgb3V0cHV0QXJyYXkgPSBvdXRwdXRBcnJheS5tYXAoc2FtcGxlID0+IHNhbXBsZSAvIG51bUNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuZnJvbUFycmF5KG91dHB1dEFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBidWZmZXIgYXMgYW4gYXJyYXkuIFNpbmdsZSBjaGFubmVsIGJ1ZmZlcnMgd2lsbCByZXR1cm4gYSAxLWRpbWVuc2lvbmFsXG4gICAgICogRmxvYXQzMkFycmF5LCBhbmQgbXVsdGljaGFubmVsIGJ1ZmZlcnMgd2lsbCByZXR1cm4gbXVsdGlkaW1lbnNpb25hbCBhcnJheXMuXG4gICAgICogQHBhcmFtIGNoYW5uZWwgT3B0aW9uYWxseSBvbmx5IGNvcHkgYSBzaW5nbGUgY2hhbm5lbCBmcm9tIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICB0b0FycmF5KGNoYW5uZWwpIHtcbiAgICAgICAgaWYgKGlzTnVtYmVyKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRDaGFubmVsRGF0YShjaGFubmVsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLm51bWJlck9mQ2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvQXJyYXkoMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByZXQgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgdGhpcy5udW1iZXJPZkNoYW5uZWxzOyBjKyspIHtcbiAgICAgICAgICAgICAgICByZXRbY10gPSB0aGlzLmdldENoYW5uZWxEYXRhKGMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBGbG9hdDMyQXJyYXkgcmVwcmVzZW50aW5nIHRoZSBQQ00gYXVkaW8gZGF0YSBmb3IgdGhlIHNwZWNpZmljIGNoYW5uZWwuXG4gICAgICogQHBhcmFtICBjaGFubmVsICBUaGUgY2hhbm5lbCBudW1iZXIgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgYXVkaW8gYXMgYSBUeXBlZEFycmF5XG4gICAgICovXG4gICAgZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBGbG9hdDMyQXJyYXkoMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3V0IGEgc3Vic2VjdGlvbiBvZiB0aGUgYXJyYXkgYW5kIHJldHVybiBhIGJ1ZmZlciBvZiB0aGVcbiAgICAgKiBzdWJzZWN0aW9uLiBEb2VzIG5vdCBtb2RpZnkgdGhlIG9yaWdpbmFsIGJ1ZmZlclxuICAgICAqIEBwYXJhbSBzdGFydCBUaGUgdGltZSB0byBzdGFydCB0aGUgc2xpY2VcbiAgICAgKiBAcGFyYW0gZW5kIFRoZSBlbmQgdGltZSB0byBzbGljZS4gSWYgbm9uZSBpcyBnaXZlbiB3aWxsIGRlZmF1bHQgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyXG4gICAgICovXG4gICAgc2xpY2Uoc3RhcnQsIGVuZCA9IHRoaXMuZHVyYXRpb24pIHtcbiAgICAgICAgY29uc3Qgc3RhcnRTYW1wbGVzID0gTWF0aC5mbG9vcihzdGFydCAqIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IGVuZFNhbXBsZXMgPSBNYXRoLmZsb29yKGVuZCAqIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGFzc2VydChzdGFydFNhbXBsZXMgPCBlbmRTYW1wbGVzLCBcIlRoZSBzdGFydCB0aW1lIG11c3QgYmUgbGVzcyB0aGFuIHRoZSBlbmQgdGltZVwiKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gZW5kU2FtcGxlcyAtIHN0YXJ0U2FtcGxlcztcbiAgICAgICAgY29uc3QgcmV0QnVmZmVyID0gZ2V0Q29udGV4dCgpLmNyZWF0ZUJ1ZmZlcih0aGlzLm51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgZm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGNoYW5uZWwrKykge1xuICAgICAgICAgICAgcmV0QnVmZmVyLmNvcHlUb0NoYW5uZWwodGhpcy5nZXRDaGFubmVsRGF0YShjaGFubmVsKS5zdWJhcnJheShzdGFydFNhbXBsZXMsIGVuZFNhbXBsZXMpLCBjaGFubmVsKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFRvbmVBdWRpb0J1ZmZlcihyZXRCdWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgX3JldmVyc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLmxvYWRlZCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGkrKykge1xuICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q2hhbm5lbERhdGEoaSkucmV2ZXJzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIGlzIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5sZW5ndGggPiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gb2YgdGhlIGJ1ZmZlciBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIGdldCBkdXJhdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5kdXJhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsZW5ndGggb2YgdGhlIGJ1ZmZlciBpbiBzYW1wbGVzXG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGRpc2NyZXRlIGF1ZGlvIGNoYW5uZWxzLiBSZXR1cm5zIDAgaWYgbm8gYnVmZmVyIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBnZXQgbnVtYmVyT2ZDaGFubmVscygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV2ZXJzZSB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGdldCByZXZlcnNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmV2ZXJzZWQ7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICBpZiAodGhpcy5fcmV2ZXJzZWQgIT09IHJldikge1xuICAgICAgICAgICAgdGhpcy5fcmV2ZXJzZWQgPSByZXY7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgVG9uZUF1ZGlvQnVmZmVyIGZyb20gdGhlIGFycmF5LiBUbyBjcmVhdGUgYSBtdWx0aWNoYW5uZWwgQXVkaW9CdWZmZXIsXG4gICAgICogcGFzcyBpbiBhIG11bHRpZGltZW5zaW9uYWwgYXJyYXkuXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBmaWxsIHRoZSBhdWRpbyBidWZmZXJcbiAgICAgKiBAcmV0dXJuIEEgVG9uZUF1ZGlvQnVmZmVyIGNyZWF0ZWQgZnJvbSB0aGUgYXJyYXlcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbUFycmF5KGFycmF5KSB7XG4gICAgICAgIHJldHVybiAobmV3IFRvbmVBdWRpb0J1ZmZlcigpKS5mcm9tQXJyYXkoYXJyYXkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgVG9uZUF1ZGlvQnVmZmVyIGZyb20gYSBVUkwsIHJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHRvIGEgVG9uZUF1ZGlvQnVmZmVyXG4gICAgICogQHBhcmFtICB1cmwgVGhlIHVybCB0byBsb2FkLlxuICAgICAqIEByZXR1cm4gQSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHRvIGEgVG9uZUF1ZGlvQnVmZmVyXG4gICAgICovXG4gICAgc3RhdGljIGZyb21VcmwodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWRzIGEgdXJsIHVzaW5nIGZldGNoIGFuZCByZXR1cm5zIHRoZSBBdWRpb0J1ZmZlci5cbiAgICAgKi9cbiAgICBzdGF0aWMgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIC8vIHRlc3QgaWYgdGhlIHVybCBjb250YWlucyBtdWx0aXBsZSBleHRlbnNpb25zXG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gdXJsLm1hdGNoKC9cXFsoW15cXF1cXFtdK1xcfC4rKVxcXSQvKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IG1hdGNoZXNbMV0uc3BsaXQoXCJ8XCIpO1xuICAgICAgICAgICAgICAgIGxldCBleHRlbnNpb24gPSBleHRlbnNpb25zWzBdO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZXh0IG9mIGV4dGVuc2lvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFRvbmVBdWRpb0J1ZmZlci5zdXBwb3J0c1R5cGUoZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uID0gZXh0O1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdXJsID0gdXJsLnJlcGxhY2UobWF0Y2hlc1swXSwgZXh0ZW5zaW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGVyZSBpcyBhIHNsYXNoIGJldHdlZW4gdGhlIGJhc2VVcmwgYW5kIHRoZSB1cmxcbiAgICAgICAgICAgIGNvbnN0IGJhc2VVcmwgPSBUb25lQXVkaW9CdWZmZXIuYmFzZVVybCA9PT0gXCJcIiB8fCBUb25lQXVkaW9CdWZmZXIuYmFzZVVybC5lbmRzV2l0aChcIi9cIikgPyBUb25lQXVkaW9CdWZmZXIuYmFzZVVybCA6IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsICsgXCIvXCI7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IHlpZWxkIGZldGNoKGJhc2VVcmwgKyB1cmwpO1xuICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgY291bGQgbm90IGxvYWQgdXJsOiAke3VybH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0geWllbGQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0geWllbGQgZ2V0Q29udGV4dCgpLmRlY29kZUF1ZGlvRGF0YShhcnJheUJ1ZmZlcik7XG4gICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDaGVja3MgYSB1cmwncyBleHRlbnNpb24gdG8gc2VlIGlmIHRoZSBjdXJyZW50IGJyb3dzZXIgY2FuIHBsYXkgdGhhdCBmaWxlIHR5cGUuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsL2V4dGVuc2lvbiB0byB0ZXN0XG4gICAgICogQHJldHVybiBJZiB0aGUgZmlsZSBleHRlbnNpb24gY2FuIGJlIHBsYXllZFxuICAgICAqIEBzdGF0aWNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVG9uZUF1ZGlvQnVmZmVyLnN1cHBvcnRzVHlwZShcIndhdlwiKTsgLy8gcmV0dXJucyB0cnVlXG4gICAgICogVG9uZS5Ub25lQXVkaW9CdWZmZXIuc3VwcG9ydHNUeXBlKFwicGF0aC90by9maWxlLndhdlwiKTsgLy8gcmV0dXJucyB0cnVlXG4gICAgICovXG4gICAgc3RhdGljIHN1cHBvcnRzVHlwZSh1cmwpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9ucyA9IHVybC5zcGxpdChcIi5cIik7XG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbZXh0ZW5zaW9ucy5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYXVkaW9cIikuY2FuUGxheVR5cGUoXCJhdWRpby9cIiArIGV4dGVuc2lvbik7XG4gICAgICAgIHJldHVybiByZXNwb25zZSAhPT0gXCJcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIGJ1ZmZlcnMgaGF2ZSBsb2FkZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgLy8gdGhpcyBtYWtlcyBzdXJlIHRoYXQgdGhlIGZ1bmN0aW9uIGlzIGFsd2F5cyBhc3luY1xuICAgICAgICAgICAgeWllbGQgUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgICB3aGlsZSAoVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFNUQVRJQyBNRVRIT0RTXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogQSBwYXRoIHdoaWNoIGlzIHByZWZpeGVkIGJlZm9yZSBldmVyeSB1cmwuXG4gKi9cblRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsID0gXCJcIjtcbi8qKlxuICogQWxsIG9mIHRoZSBkb3dubG9hZHNcbiAqL1xuVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2FkcyA9IFtdO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvQnVmZmVyLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRcIjtcbmltcG9ydCB7IGlzT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHRcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogLy8gZ2VuZXJhdGUgYSBzaW5nbGUgY2hhbm5lbCwgMC41IHNlY29uZCBidWZmZXJcbiAqIGNvbnN0IGNvbnRleHQgPSBuZXcgVG9uZS5PZmZsaW5lQ29udGV4dCgxLCAwLjUsIDQ0MTAwKTtcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoeyBjb250ZXh0IH0pO1xuICogY29udGV4dC5yZW5kZXIoKS50aGVuKGJ1ZmZlciA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzLCBidWZmZXIuZHVyYXRpb24pO1xuICogfSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBPZmZsaW5lQ29udGV4dCBleHRlbmRzIENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcih7XG4gICAgICAgICAgICBjbG9ja1NvdXJjZTogXCJvZmZsaW5lXCIsXG4gICAgICAgICAgICBjb250ZXh0OiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICAgICAgYXJndW1lbnRzWzBdIDogY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSAqIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzJdKSxcbiAgICAgICAgICAgIGxvb2tBaGVhZDogMCxcbiAgICAgICAgICAgIHVwZGF0ZUludGVydmFsOiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICAgICAgMTI4IC8gYXJndW1lbnRzWzBdLnNhbXBsZVJhdGUgOiAxMjggLyBhcmd1bWVudHNbMl0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9mZmxpbmVDb250ZXh0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBhcnRpZmljaWFsIGNsb2NrIHNvdXJjZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY3VycmVudFRpbWUgPSAwO1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IHRydWU7XG4gICAgICAgIHRoaXMuX2R1cmF0aW9uID0gaXNPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSkgP1xuICAgICAgICAgICAgYXJndW1lbnRzWzBdLmxlbmd0aCAvIGFyZ3VtZW50c1swXS5zYW1wbGVSYXRlIDogYXJndW1lbnRzWzFdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPdmVycmlkZSB0aGUgbm93IG1ldGhvZCB0byBwb2ludCB0byB0aGUgaW50ZXJuYWwgY2xvY2sgdGltZVxuICAgICAqL1xuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTYW1lIGFzIHRoaXMubm93KClcbiAgICAgKi9cbiAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIGp1c3QgdGhlIGNsb2NrIHBvcnRpb24gb2YgdGhlIGF1ZGlvIGNvbnRleHQuXG4gICAgICovXG4gICAgX3JlbmRlckNsb2NrKGFzeW5jaHJvbm91cykge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gMDtcbiAgICAgICAgICAgIHdoaWxlICh0aGlzLl9kdXJhdGlvbiAtIHRoaXMuX2N1cnJlbnRUaW1lID49IDApIHtcbiAgICAgICAgICAgICAgICAvLyBpbnZva2UgYWxsIHRoZSBjYWxsYmFja3Mgb24gdGhhdCB0aW1lXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwidGlja1wiKTtcbiAgICAgICAgICAgICAgICAvLyBpbmNyZW1lbnQgdGhlIGNsb2NrIGluIGJsb2NrLXNpemVkIGNodW5rc1xuICAgICAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRUaW1lICs9IDEyOCAvIHRoaXMuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAvLyB5aWVsZCBvbmNlIGEgc2Vjb25kIG9mIGF1ZGlvXG4gICAgICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgICAgICBjb25zdCB5aWVsZEV2ZXJ5ID0gTWF0aC5mbG9vcih0aGlzLnNhbXBsZVJhdGUgLyAxMjgpO1xuICAgICAgICAgICAgICAgIGlmIChhc3luY2hyb25vdXMgJiYgaW5kZXggJSB5aWVsZEV2ZXJ5ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHlpZWxkIG5ldyBQcm9taXNlKGRvbmUgPT4gc2V0VGltZW91dChkb25lLCAxKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIHRoZSBvdXRwdXQgb2YgdGhlIE9mZmxpbmVDb250ZXh0XG4gICAgICogQHBhcmFtIGFzeW5jaHJvbm91cyBJZiB0aGUgY2xvY2sgc2hvdWxkIGJlIHJlbmRlcmVkIGFzeW5jaHJvbm91c2x5LCB3aGljaCB3aWxsIG5vdCBibG9jayB0aGUgbWFpbiB0aHJlYWQsIGJ1dCBiZSBzbGlnaHRseSBzbG93ZXIuXG4gICAgICovXG4gICAgcmVuZGVyKGFzeW5jaHJvbm91cyA9IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHlpZWxkIHRoaXMud29ya2xldHNBcmVSZWFkeSgpO1xuICAgICAgICAgICAgeWllbGQgdGhpcy5fcmVuZGVyQ2xvY2soYXN5bmNocm9ub3VzKTtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIHRoaXMuX2NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKGJ1ZmZlcik7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgY29udGV4dFxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T2ZmbGluZUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gXCIuLi92ZXJzaW9uXCI7XG5pbXBvcnQgeyBoYXNBdWRpb0NvbnRleHQsIHRoZVdpbmRvdyB9IGZyb20gXCIuL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4vY29udGV4dC9Db250ZXh0XCI7XG5pbXBvcnQgeyBEdW1teUNvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L0R1bW15Q29udGV4dFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBpc0F1ZGlvQ29udGV4dCwgaXNPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuLyoqXG4gKiBUaGlzIGR1bW15IGNvbnRleHQgaXMgdXNlZCB0byBhdm9pZCB0aHJvd2luZyBpbW1lZGlhdGUgZXJyb3JzIHdoZW4gaW1wb3J0aW5nIGluIE5vZGUuanNcbiAqL1xuY29uc3QgZHVtbXlDb250ZXh0ID0gbmV3IER1bW15Q29udGV4dCgpO1xuLyoqXG4gKiBUaGUgZ2xvYmFsIGF1ZGlvIGNvbnRleHQgd2hpY2ggaXMgZ2V0YWJsZSBhbmQgYXNzaWduYWJsZSB0aHJvdWdoXG4gKiBnZXRDb250ZXh0IGFuZCBzZXRDb250ZXh0XG4gKi9cbmxldCBnbG9iYWxDb250ZXh0ID0gZHVtbXlDb250ZXh0O1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBkZWZhdWx0IHN5c3RlbS13aWRlIFtbQ29udGV4dF1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHtcbiAgICBpZiAoZ2xvYmFsQ29udGV4dCA9PT0gZHVtbXlDb250ZXh0ICYmIGhhc0F1ZGlvQ29udGV4dCkge1xuICAgICAgICBzZXRDb250ZXh0KG5ldyBDb250ZXh0KCkpO1xuICAgIH1cbiAgICByZXR1cm4gZ2xvYmFsQ29udGV4dDtcbn1cbi8qKlxuICogU2V0IHRoZSBkZWZhdWx0IGF1ZGlvIGNvbnRleHRcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRDb250ZXh0KGNvbnRleHQpIHtcbiAgICBpZiAoaXNBdWRpb0NvbnRleHQoY29udGV4dCkpIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IG5ldyBDb250ZXh0KGNvbnRleHQpO1xuICAgIH1cbiAgICBlbHNlIGlmIChpc09mZmxpbmVBdWRpb0NvbnRleHQoY29udGV4dCkpIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dChjb250ZXh0KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGdsb2JhbENvbnRleHQgPSBjb250ZXh0O1xuICAgIH1cbn1cbi8qKlxuICogTW9zdCBicm93c2VycyB3aWxsIG5vdCBwbGF5IF9hbnlfIGF1ZGlvIHVudGlsIGEgdXNlclxuICogY2xpY2tzIHNvbWV0aGluZyAobGlrZSBhIHBsYXkgYnV0dG9uKS4gSW52b2tlIHRoaXMgbWV0aG9kXG4gKiBvbiBhIGNsaWNrIG9yIGtleXByZXNzIGV2ZW50IGhhbmRsZXIgdG8gc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQuXG4gKiBNb3JlIGFib3V0IHRoZSBBdXRvcGxheSBwb2xpY3lcbiAqIFtoZXJlXShodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS93ZWIvdXBkYXRlcy8yMDE3LzA5L2F1dG9wbGF5LXBvbGljeS1jaGFuZ2VzI3dlYmF1ZGlvKVxuICogQGV4YW1wbGVcbiAqIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJidXR0b25cIikuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIGFzeW5jICgpID0+IHtcbiAqIFx0YXdhaXQgVG9uZS5zdGFydCgpO1xuICogXHRjb25zb2xlLmxvZyhcImNvbnRleHQgc3RhcnRlZFwiKTtcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgIHJldHVybiBnbG9iYWxDb250ZXh0LnJlc3VtZSgpO1xufVxuLyoqXG4gKiBMb2cgVG9uZS5qcyArIHZlcnNpb24gaW4gdGhlIGNvbnNvbGUuXG4gKi9cbmlmICh0aGVXaW5kb3cgJiYgIXRoZVdpbmRvdy5UT05FX1NJTEVOQ0VfTE9HR0lORykge1xuICAgIGxldCBwcmVmaXggPSBcInZcIjtcbiAgICBpZiAodmVyc2lvbiA9PT0gXCJkZXZcIikge1xuICAgICAgICBwcmVmaXggPSBcIlwiO1xuICAgIH1cbiAgICBjb25zdCBwcmludFN0cmluZyA9IGAgKiBUb25lLmpzICR7cHJlZml4fSR7dmVyc2lvbn0gKiBgO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgY29uc29sZS5sb2coYCVjJHtwcmludFN0cmluZ31gLCBcImJhY2tncm91bmQ6ICMwMDA7IGNvbG9yOiAjZmZmXCIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2xvYmFsLmpzLm1hcCIsIi8qKlxuICogRXF1YWwgcG93ZXIgZ2FpbiBzY2FsZS4gR29vZCBmb3IgY3Jvc3MtZmFkaW5nLlxuICogQHBhcmFtICBwZXJjZW50ICgwLTEpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbFBvd2VyU2NhbGUocGVyY2VudCkge1xuICAgIGNvbnN0IHBpRmFjdG9yID0gMC41ICogTWF0aC5QSTtcbiAgICByZXR1cm4gTWF0aC5zaW4ocGVyY2VudCAqIHBpRmFjdG9yKTtcbn1cbi8qKlxuICogQ29udmVydCBkZWNpYmVscyBpbnRvIGdhaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkYlRvR2FpbihkYikge1xuICAgIHJldHVybiBNYXRoLnBvdygxMCwgZGIgLyAyMCk7XG59XG4vKipcbiAqIENvbnZlcnQgZ2FpbiB0byBkZWNpYmVscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdhaW5Ub0RiKGdhaW4pIHtcbiAgICByZXR1cm4gMjAgKiAoTWF0aC5sb2coZ2FpbikgLyBNYXRoLkxOMTApO1xufVxuLyoqXG4gKiBDb252ZXJ0IGFuIGludGVydmFsIChpbiBzZW1pdG9uZXMpIHRvIGEgZnJlcXVlbmN5IHJhdGlvLlxuICogQHBhcmFtIGludGVydmFsIHRoZSBudW1iZXIgb2Ygc2VtaXRvbmVzIGFib3ZlIHRoZSBiYXNlIG5vdGVcbiAqIEBleGFtcGxlXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygwKTsgLy8gMVxuICogVG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oMTIpOyAvLyAyXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygtMTIpOyAvLyAwLjVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCkge1xuICAgIHJldHVybiBNYXRoLnBvdygyLCAoaW50ZXJ2YWwgLyAxMikpO1xufVxuLyoqXG4gKiBUaGUgR2xvYmFsIFtjb25jZXJ0IHR1bmluZyBwaXRjaF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29uY2VydF9waXRjaCkgd2hpY2ggaXMgdXNlZFxuICogdG8gZ2VuZXJhdGUgYWxsIHRoZSBvdGhlciBwaXRjaCB2YWx1ZXMgZnJvbSBub3Rlcy4gQTQncyB2YWx1ZXMgaW4gSGVydHouXG4gKi9cbmxldCBBNCA9IDQ0MDtcbmV4cG9ydCBmdW5jdGlvbiBnZXRBNCgpIHtcbiAgICByZXR1cm4gQTQ7XG59XG5leHBvcnQgZnVuY3Rpb24gc2V0QTQoZnJlcSkge1xuICAgIEE0ID0gZnJlcTtcbn1cbi8qKlxuICogQ29udmVydCBhIGZyZXF1ZW5jeSB2YWx1ZSB0byBhIE1JREkgbm90ZS5cbiAqIEBwYXJhbSBmcmVxdWVuY3kgVGhlIHZhbHVlIHRvIGZyZXF1ZW5jeSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQGV4YW1wbGVcbiAqIFRvbmUuZnRvbSg0NDApOyAvLyByZXR1cm5zIDY5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdG9tKGZyZXF1ZW5jeSkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKGZ0b21mKGZyZXF1ZW5jeSkpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgZnJlcXVlbmN5IHRvIGEgZmxvYXRpbmcgcG9pbnQgbWlkaSB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZnRvbWYoZnJlcXVlbmN5KSB7XG4gICAgcmV0dXJuIDY5ICsgMTIgKiBNYXRoLmxvZzIoZnJlcXVlbmN5IC8gQTQpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgTUlESSBub3RlIHRvIGZyZXF1ZW5jeSB2YWx1ZS5cbiAqIEBwYXJhbSAgbWlkaSBUaGUgbWlkaSBudW1iZXIgdG8gY29udmVydC5cbiAqIEByZXR1cm4gVGhlIGNvcnJlc3BvbmRpbmcgZnJlcXVlbmN5IHZhbHVlXG4gKiBAZXhhbXBsZVxuICogVG9uZS5tdG9mKDY5KTsgLy8gNDQwXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtdG9mKG1pZGkpIHtcbiAgICByZXR1cm4gQTQgKiBNYXRoLnBvdygyLCAobWlkaSAtIDY5KSAvIDEyKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnZlcnNpb25zLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNTdHJpbmcsIGlzVW5kZWYgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVGltZUJhc2UgaXMgYSBmbGV4aWJsZSBlbmNvZGluZyBvZiB0aW1lIHdoaWNoIGNhbiBiZSBldmFsdWF0ZWQgdG8gYW5kIGZyb20gYSBzdHJpbmcuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lQmFzZUNsYXNzIGV4dGVuZHMgVG9uZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgYXNzb2NpYXRlZCB3aXRoIHRoZSB0aW1lIHZhbHVlLiBVc2VkIHRvIGNvbXB1dGVcbiAgICAgKiBUcmFuc3BvcnQgYW5kIGNvbnRleHQtcmVsYXRpdmUgdGltaW5nLlxuICAgICAqIEBwYXJhbSAgdmFsdWUgIFRoZSB0aW1lIHZhbHVlIGFzIGEgbnVtYmVyLCBzdHJpbmcgb3Igb2JqZWN0XG4gICAgICogQHBhcmFtICB1bml0cyAgVW5pdCB2YWx1ZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCB2YWx1ZSwgdW5pdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkZWZhdWx0IHVuaXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwic1wiO1xuICAgICAgICB0aGlzLl92YWwgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgdGhpcy5fZXhwcmVzc2lvbnMgPSB0aGlzLl9nZXRFeHByZXNzaW9ucygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbGwgb2YgdGhlIHRpbWUgZW5jb2RpbmcgZXhwcmVzc2lvbnNcbiAgICAgKi9cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBoejoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3lUb1VuaXRzKHBhcnNlRmxvYXQodmFsdWUpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyloeiQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tzVG9Vbml0cyhwYXJzZUludCh2YWx1ZSwgMTApKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKylpJC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG06IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlSW50KHZhbHVlLCAxMCkgKiB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKW0kL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbjoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlLCBkb3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NhbGFyID0gZG90ID09PSBcIi5cIiA/IDEuNSA6IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmIChudW1lcmljVmFsdWUgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHModGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpKSAqIHNjYWxhcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMoNCAvIG51bWVyaWNWYWx1ZSkgKiBzY2FsYXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyluKFxcLj8pJC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG51bWJlcjoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9leHByZXNzaW9uc1t0aGlzLmRlZmF1bHRVbml0c10ubWV0aG9kLmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KSQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHM6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2Vjb25kc1RvVW5pdHMocGFyc2VGbG9hdCh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KXMkLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzYW1wbGVzOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KHZhbHVlLCAxMCkgLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKylzYW1wbGVzJC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdDoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMoOCAvIChNYXRoLmZsb29yKG51bWVyaWNWYWx1ZSkgKiAzKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspdCQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cjoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKG0sIHEsIHMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG0gJiYgbSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkgKiBwYXJzZUZsb2F0KG0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocSAmJiBxICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzICYmIHMgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChzKSAvIDQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyk6KFxcZCsoPzpcXC5cXGQrKT8pOj8oXFxkKyg/OlxcLlxcZCspPyk/JC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFZBTFVFIE9GXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogRXZhbHVhdGUgdGhlIHRpbWUgdmFsdWUuIFJldHVybnMgdGhlIHRpbWUgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICB2YWx1ZU9mKCkge1xuICAgICAgICBpZiAodGhpcy5fdmFsIGluc3RhbmNlb2YgVGltZUJhc2VDbGFzcykge1xuICAgICAgICAgICAgdGhpcy5mcm9tVHlwZSh0aGlzLl92YWwpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1VuZGVmKHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub0FyZygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRoaXMuX3ZhbCkgJiYgaXNVbmRlZih0aGlzLl91bml0cykpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdW5pdHMgaW4gdGhpcy5fZXhwcmVzc2lvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZXhwcmVzc2lvbnNbdW5pdHNdLnJlZ2V4cC50ZXN0KHRoaXMuX3ZhbC50cmltKCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3VuaXRzID0gdW5pdHM7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc09iamVjdCh0aGlzLl92YWwpKSB7XG4gICAgICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICAgICAgZm9yIChjb25zdCB0eXBlTmFtZSBpbiB0aGlzLl92YWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX3ZhbFt0eXBlTmFtZV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1YW50aXR5ID0gdGhpcy5fdmFsW3R5cGVOYW1lXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lID0gKG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgdHlwZU5hbWUpKS52YWx1ZU9mKCkgKiBxdWFudGl0eTtcbiAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGltZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdG90YWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl91bml0cykpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4cHIgPSB0aGlzLl9leHByZXNzaW9uc1t0aGlzLl91bml0c107XG4gICAgICAgICAgICBjb25zdCBtYXRjaGluZyA9IHRoaXMuX3ZhbC50b1N0cmluZygpLnRyaW0oKS5tYXRjaChleHByLnJlZ2V4cCk7XG4gICAgICAgICAgICBpZiAobWF0Y2hpbmcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwci5tZXRob2QuYXBwbHkodGhpcywgbWF0Y2hpbmcuc2xpY2UoMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4cHIubWV0aG9kLmNhbGwodGhpcywgdGhpcy5fdmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1N0cmluZyh0aGlzLl92YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyc2VGbG9hdCh0aGlzLl92YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFVOSVQgQ09OVkVSU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGZyZXF1ZW5jeSBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBmcmVxO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9iZWF0c1RvVW5pdHMoYmVhdHMpIHtcbiAgICAgICAgcmV0dXJuICg2MCAvIHRoaXMuX2dldEJwbSgpKSAqIGJlYXRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBzZWNvbmRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuICAgICAqL1xuICAgIF90aWNrc1RvVW5pdHModGlja3MpIHtcbiAgICAgICAgcmV0dXJuICh0aWNrcyAqICh0aGlzLl9iZWF0c1RvVW5pdHMoMSkpIC8gdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaXRoIG5vIGFyZ3VtZW50cywgcmV0dXJuICdub3cnXG4gICAgICovXG4gICAgX25vQXJnKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbm93KCk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VEVNUE8gQ09OVkVSU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGJwbVxuICAgICAqL1xuICAgIF9nZXRCcG0oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmJwbS52YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lU2lnbmF0dXJlXG4gICAgICovXG4gICAgX2dldFRpbWVTaWduYXR1cmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpbWVTaWduYXR1cmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgUFBRIG9yIDE5MiBpZiBUcmFuc3BvcnQgaXMgbm90IGF2YWlsYWJsZVxuICAgICAqL1xuICAgIF9nZXRQUFEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LlBQUTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRDT05WRVJTSU9OIElOVEVSRkFDRVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIENvZXJjZSBhIHRpbWUgdHlwZSBpbnRvIHRoaXMgdW5pdHMgdHlwZS5cbiAgICAgKiBAcGFyYW0gdHlwZSBBbnkgdGltZSB0eXBlIHVuaXRzXG4gICAgICovXG4gICAgZnJvbVR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl91bml0cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgc3dpdGNoICh0aGlzLmRlZmF1bHRVbml0cykge1xuICAgICAgICAgICAgY2FzZSBcInNcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImlcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvVGlja3MoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJoelwiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9GcmVxdWVuY3koKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJtaWRpXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b01pZGkoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBpbiBoZXJ0elxuICAgICAqL1xuICAgIHRvRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gMSAvIHRoaXMudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBzYW1wbGVzXG4gICAgICovXG4gICAgdG9TYW1wbGVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHMoKSAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzLlxuICAgICAqL1xuICAgIHRvTWlsbGlzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHMoKSAqIDEwMDA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZUJhc2UuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGZ0b20gfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgVGltZUJhc2VDbGFzcyB9IGZyb20gXCIuL1RpbWVCYXNlXCI7XG4vKipcbiAqIFRpbWVDbGFzcyBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBhbmQgZGVjb2RpbmcgVGltZSB2YWx1ZXMuXG4gKiBUaW1lQ2xhc3MgY2FuIGJlIHBhc3NlZCBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQHBhcmFtICB2YWwgICAgVGhlIHRpbWUgdmFsdWUuXG4gKiBAcGFyYW0gIHVuaXRzICBUaGUgdW5pdHMgb2YgdGhlIHZhbHVlLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHRpbWUgPSBUb25lLlRpbWUoXCI0blwiKTsgLy8gYSBxdWFydGVyIG5vdGVcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lQ2xhc3MgZXh0ZW5kcyBUaW1lQmFzZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lQ2xhc3NcIjtcbiAgICB9XG4gICAgX2dldEV4cHJlc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihzdXBlci5fZ2V0RXhwcmVzc2lvbnMoKSwge1xuICAgICAgICAgICAgbm93OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAoY2FwdHVyZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbm93KCkgKyBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmNvbnRleHQsIGNhcHR1cmUpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL15cXCsoLispLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBxdWFudGl6ZToge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKGNhcHR1cmUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRUbyA9IG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBjYXB0dXJlKS52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zZWNvbmRzVG9Vbml0cyh0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm5leHRTdWJkaXZpc2lvbihxdWFudFRvKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eQCguKykvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFF1YW50aXplIHRoZSB0aW1lIGJ5IHRoZSBnaXZlbiBzdWJkaXZpc2lvbi4gT3B0aW9uYWxseSBhZGQgYVxuICAgICAqIHBlcmNlbnRhZ2Ugd2hpY2ggd2lsbCBtb3ZlIHRoZSB0aW1lIHZhbHVlIHRvd2FyZHMgdGhlIGlkZWFsXG4gICAgICogcXVhbnRpemVkIHZhbHVlIGJ5IHRoYXQgcGVyY2VudGFnZS5cbiAgICAgKiBAcGFyYW0gIHN1YmRpdiAgICBUaGUgc3ViZGl2aXNpb24gdG8gcXVhbnRpemUgdG9cbiAgICAgKiBAcGFyYW0gIHBlcmNlbnQgIE1vdmUgdGhlIHRpbWUgdmFsdWUgdG93YXJkcyB0aGUgcXVhbnRpemVkIHZhbHVlIGJ5IGEgcGVyY2VudGFnZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVGltZSgyMSkucXVhbnRpemUoMik7IC8vIHJldHVybnMgMjJcbiAgICAgKiBUb25lLlRpbWUoMC42KS5xdWFudGl6ZShcIjRuXCIsIDAuNSk7IC8vIHJldHVybnMgMC41NVxuICAgICAqL1xuICAgIHF1YW50aXplKHN1YmRpdiwgcGVyY2VudCA9IDEpIHtcbiAgICAgICAgY29uc3Qgc3ViZGl2aXNpb24gPSBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmNvbnRleHQsIHN1YmRpdikudmFsdWVPZigpO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmFsdWVPZigpO1xuICAgICAgICBjb25zdCBtdWx0aXBsZSA9IE1hdGgucm91bmQodmFsdWUgLyBzdWJkaXZpc2lvbik7XG4gICAgICAgIGNvbnN0IGlkZWFsID0gbXVsdGlwbGUgKiBzdWJkaXZpc2lvbjtcbiAgICAgICAgY29uc3QgZGlmZiA9IGlkZWFsIC0gdmFsdWU7XG4gICAgICAgIHJldHVybiB2YWx1ZSArIGRpZmYgKiBwZXJjZW50O1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBUaW1lIHRvIE5vdGF0aW9uLiBUaGUgbm90YXRpb24gdmFsdWVzIGFyZSB3aWxsIGJlIHRoZVxuICAgICAqIGNsb3Nlc3QgcmVwcmVzZW50YXRpb24gYmV0d2VlbiAxbSB0byAxMjh0aCBub3RlLlxuICAgICAqIEByZXR1cm4ge05vdGF0aW9ufVxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gaWYgdGhlIFRyYW5zcG9ydCBpcyBhdCAxMjBicG06XG4gICAgICogVG9uZS5UaW1lKDIpLnRvTm90YXRpb24oKTsgLy8gcmV0dXJucyBcIjFtXCJcbiAgICAgKi9cbiAgICB0b05vdGF0aW9uKCkge1xuICAgICAgICBjb25zdCB0aW1lID0gdGhpcy50b1NlY29uZHMoKTtcbiAgICAgICAgY29uc3QgdGVzdE5vdGF0aW9ucyA9IFtcIjFtXCJdO1xuICAgICAgICBmb3IgKGxldCBwb3dlciA9IDE7IHBvd2VyIDwgOTsgcG93ZXIrKykge1xuICAgICAgICAgICAgY29uc3Qgc3ViZGl2ID0gTWF0aC5wb3coMiwgcG93ZXIpO1xuICAgICAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKHN1YmRpdiArIFwibi5cIik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJuXCIpO1xuICAgICAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKHN1YmRpdiArIFwidFwiKTtcbiAgICAgICAgfVxuICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goXCIwXCIpO1xuICAgICAgICAvLyBmaW5kIHRoZSBjbG9zZXRzIG5vdGF0aW9uIHJlcHJlc2VudGF0aW9uXG4gICAgICAgIGxldCBjbG9zZXN0ID0gdGVzdE5vdGF0aW9uc1swXTtcbiAgICAgICAgbGV0IGNsb3Nlc3RTZWNvbmRzID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRlc3ROb3RhdGlvbnNbMF0pLnRvU2Vjb25kcygpO1xuICAgICAgICB0ZXN0Tm90YXRpb25zLmZvckVhY2gobm90YXRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm90YXRpb25TZWNvbmRzID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGF0aW9uKS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhub3RhdGlvblNlY29uZHMgLSB0aW1lKSA8IE1hdGguYWJzKGNsb3Nlc3RTZWNvbmRzIC0gdGltZSkpIHtcbiAgICAgICAgICAgICAgICBjbG9zZXN0ID0gbm90YXRpb247XG4gICAgICAgICAgICAgICAgY2xvc2VzdFNlY29uZHMgPSBub3RhdGlvblNlY29uZHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2xvc2VzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGVuY29kZWQgYXMgQmFyczpCZWF0czpTaXh0ZWVudGhzLlxuICAgICAqL1xuICAgIHRvQmFyc0JlYXRzU2l4dGVlbnRocygpIHtcbiAgICAgICAgY29uc3QgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG4gICAgICAgIGxldCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHF1YXJ0ZXJzID0gcGFyc2VGbG9hdChxdWFydGVycy50b0ZpeGVkKDQpKTtcbiAgICAgICAgY29uc3QgbWVhc3VyZXMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzIC8gdGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpKTtcbiAgICAgICAgbGV0IHNpeHRlZW50aHMgPSAocXVhcnRlcnMgJSAxKSAqIDQ7XG4gICAgICAgIHF1YXJ0ZXJzID0gTWF0aC5mbG9vcihxdWFydGVycykgJSB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCk7XG4gICAgICAgIGNvbnN0IHNpeHRlZW50aFN0cmluZyA9IHNpeHRlZW50aHMudG9TdHJpbmcoKTtcbiAgICAgICAgaWYgKHNpeHRlZW50aFN0cmluZy5sZW5ndGggPiAzKSB7XG4gICAgICAgICAgICAvLyB0aGUgYWRkaXRpb25hbCBwYXJzZUZsb2F0IHJlbW92ZXMgaW5zaWduaWZpY2FudCB0cmFpbGluZyB6ZXJvZXNcbiAgICAgICAgICAgIHNpeHRlZW50aHMgPSBwYXJzZUZsb2F0KHBhcnNlRmxvYXQoc2l4dGVlbnRoU3RyaW5nKS50b0ZpeGVkKDMpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9ncmVzcyA9IFttZWFzdXJlcywgcXVhcnRlcnMsIHNpeHRlZW50aHNdO1xuICAgICAgICByZXR1cm4gcHJvZ3Jlc3Muam9pbihcIjpcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiB0aWNrcy5cbiAgICAgKi9cbiAgICB0b1RpY2tzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgY29uc3QgcXVhcnRlcnMgPSB0aGlzLnZhbHVlT2YoKSAvIHF1YXJ0ZXJUaW1lO1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChxdWFydGVycyAqIHRoaXMuX2dldFBQUSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgYXMgYSBtaWRpIG5vdGUuXG4gICAgICovXG4gICAgdG9NaWRpKCkge1xuICAgICAgICByZXR1cm4gZnRvbSh0aGlzLnRvRnJlcXVlbmN5KCkpO1xuICAgIH1cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0Lm5vdygpO1xuICAgIH1cbn1cbi8qKlxuICogQ3JlYXRlIGEgVGltZUNsYXNzIGZyb20gYSB0aW1lIHN0cmluZyBvciBudW1iZXIuIFRoZSB0aW1lIGlzIGNvbXB1dGVkIGFnYWluc3QgdGhlXG4gKiBnbG9iYWwgVG9uZS5Db250ZXh0LiBUbyB1c2UgYSBzcGVjaWZpYyBjb250ZXh0LCB1c2UgW1tUaW1lQ2xhc3NdXVxuICogQHBhcmFtIHZhbHVlIEEgdmFsdWUgd2hpY2ggcmVwcmVzZW50cyB0aW1lXG4gKiBAcGFyYW0gdW5pdHMgVGhlIHZhbHVlJ3MgdW5pdHMgaWYgdGhleSBjYW4ndCBiZSBpbmZlcnJlZCBieSB0aGUgdmFsdWUuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHRpbWUgPSBUb25lLlRpbWUoXCI0blwiKS50b1NlY29uZHMoKTtcbiAqIGNvbnNvbGUubG9nKHRpbWUpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IG5vdGUgPSBUb25lLlRpbWUoMSkudG9Ob3RhdGlvbigpO1xuICogY29uc29sZS5sb2cobm90ZSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3QgZnJlcSA9IFRvbmUuVGltZSgwLjUpLnRvRnJlcXVlbmN5KCk7XG4gKiBjb25zb2xlLmxvZyhmcmVxKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFRpbWUodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvLCBtdG9mIH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IGZ0b20sIGdldEE0LCBzZXRBNCB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi9UaW1lXCI7XG4vKipcbiAqIEZyZXF1ZW5jeSBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBGcmVxdWVuY3kgdmFsdWVzLlxuICogRXZlbnR1YWxseSBhbGwgdGltZSB2YWx1ZXMgYXJlIGV2YWx1YXRlZCB0byBoZXJ0eiB1c2luZyB0aGUgYHZhbHVlT2ZgIG1ldGhvZC5cbiAqIEBleGFtcGxlXG4gKiBUb25lLkZyZXF1ZW5jeShcIkMzXCIpOyAvLyAyNjFcbiAqIFRvbmUuRnJlcXVlbmN5KDM4LCBcIm1pZGlcIik7XG4gKiBUb25lLkZyZXF1ZW5jeShcIkMzXCIpLnRyYW5zcG9zZSg0KTtcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVxdWVuY3lDbGFzcyBleHRlbmRzIFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlcXVlbmN5XCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJoelwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgW2NvbmNlcnQgdHVuaW5nIHBpdGNoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25jZXJ0X3BpdGNoKSB3aGljaCBpcyB1c2VkXG4gICAgICogdG8gZ2VuZXJhdGUgYWxsIHRoZSBvdGhlciBwaXRjaCB2YWx1ZXMgZnJvbSBub3Rlcy4gQTQncyB2YWx1ZXMgaW4gSGVydHouXG4gICAgICovXG4gICAgc3RhdGljIGdldCBBNCgpIHtcbiAgICAgICAgcmV0dXJuIGdldEE0KCk7XG4gICAgfVxuICAgIHN0YXRpYyBzZXQgQTQoZnJlcSkge1xuICAgICAgICBzZXRBNChmcmVxKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRBVUdNRU5UIEJBU0UgRVhQUkVTU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdXBlci5fZ2V0RXhwcmVzc2lvbnMoKSwge1xuICAgICAgICAgICAgbWlkaToge1xuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspP21pZGkpLyxcbiAgICAgICAgICAgICAgICBtZXRob2QodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFVuaXRzID09PSBcIm1pZGlcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZyZXF1ZW5jeUNsYXNzLm10b2YodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBub3RlOiB7XG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihbYS1nXXsxfSg/OmJ8I3x4fGJiKT8pKC0/WzAtOV0rKS9pLFxuICAgICAgICAgICAgICAgIG1ldGhvZChwaXRjaCwgb2N0YXZlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gbm90ZVRvU2NhbGVJbmRleFtwaXRjaC50b0xvd2VyQ2FzZSgpXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm90ZU51bWJlciA9IGluZGV4ICsgKHBhcnNlSW50KG9jdGF2ZSwgMTApICsgMSkgKiAxMjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFVuaXRzID09PSBcIm1pZGlcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vdGVOdW1iZXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnJlcXVlbmN5Q2xhc3MubXRvZihub3RlTnVtYmVyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHI6IHtcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pOihcXGQrKD86XFwuXFxkKyk/KTo/KFxcZCsoPzpcXC5cXGQrKT8pPy8sXG4gICAgICAgICAgICAgICAgbWV0aG9kKG0sIHEsIHMpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG0gJiYgbSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICo9IHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkgKiBwYXJzZUZsb2F0KG0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocSAmJiBxICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzICYmIHMgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCAqPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChzKSAvIDQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0RVhQUkVTU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBUcmFuc3Bvc2VzIHRoZSBmcmVxdWVuY3kgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBzZW1pdG9uZXMuXG4gICAgICogQHJldHVybiAgQSBuZXcgdHJhbnNwb3NlZCBmcmVxdWVuY3lcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KFwiQTRcIikudHJhbnNwb3NlKDMpOyAvLyBcIkM1XCJcbiAgICAgKi9cbiAgICB0cmFuc3Bvc2UoaW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMudmFsdWVPZigpICogaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRha2VzIGFuIGFycmF5IG9mIHNlbWl0b25lIGludGVydmFscyBhbmQgcmV0dXJuc1xuICAgICAqIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzIHRyYW5zcG9zZWQgYnkgdGhvc2UgaW50ZXJ2YWxzLlxuICAgICAqIEByZXR1cm4gIFJldHVybnMgYW4gYXJyYXkgb2YgRnJlcXVlbmNpZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KFwiQTRcIikuaGFybW9uaXplKFswLCAzLCA3XSk7IC8vIFtcIkE0XCIsIFwiQzVcIiwgXCJFNVwiXVxuICAgICAqL1xuICAgIGhhcm1vbml6ZShpbnRlcnZhbHMpIHtcbiAgICAgICAgcmV0dXJuIGludGVydmFscy5tYXAoaW50ZXJ2YWwgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHJhbnNwb3NlKGludGVydmFsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VU5JVCBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJDNFwiKS50b01pZGkoKTsgLy8gNjBcbiAgICAgKi9cbiAgICB0b01pZGkoKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHRoaXMudmFsdWVPZigpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGluIFNjaWVudGlmaWMgUGl0Y2ggTm90YXRpb25cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KDY5LCBcIm1pZGlcIikudG9Ob3RlKCk7IC8vIFwiQTRcIlxuICAgICAqL1xuICAgIHRvTm90ZSgpIHtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3koKTtcbiAgICAgICAgY29uc3QgbG9nID0gTWF0aC5sb2cyKGZyZXEgLyBGcmVxdWVuY3lDbGFzcy5BNCk7XG4gICAgICAgIGxldCBub3RlTnVtYmVyID0gTWF0aC5yb3VuZCgxMiAqIGxvZykgKyA1NztcbiAgICAgICAgY29uc3Qgb2N0YXZlID0gTWF0aC5mbG9vcihub3RlTnVtYmVyIC8gMTIpO1xuICAgICAgICBpZiAob2N0YXZlIDwgMCkge1xuICAgICAgICAgICAgbm90ZU51bWJlciArPSAtMTIgKiBvY3RhdmU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgbm90ZU5hbWUgPSBzY2FsZUluZGV4VG9Ob3RlW25vdGVOdW1iZXIgJSAxMl07XG4gICAgICAgIHJldHVybiBub3RlTmFtZSArIG9jdGF2ZS50b1N0cmluZygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIHRvU2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBzdXBlci50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBkdXJhdGlvbiBvZiBvbmUgY3ljbGUgaW4gdGlja3NcbiAgICAgKi9cbiAgICB0b1RpY2tzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgY29uc3QgcXVhcnRlcnMgPSB0aGlzLnZhbHVlT2YoKSAvIHF1YXJ0ZXJUaW1lO1xuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihxdWFydGVycyAqIHRoaXMuX2dldFBQUSgpKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRVTklUIENPTlZFUlNJT05TIEhFTFBFUlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBXaXRoIG5vIGFyZ3VtZW50cywgcmV0dXJuIDBcbiAgICAgKi9cbiAgICBfbm9BcmcoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGZyZXF1ZW5jeSBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpIHtcbiAgICAgICAgcmV0dXJuIGZyZXE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gMSAvICgodGlja3MgKiA2MCkgLyAodGhpcy5fZ2V0QnBtKCkgKiB0aGlzLl9nZXRQUFEoKSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9iZWF0c1RvVW5pdHMoYmVhdHMpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBzdXBlci5fYmVhdHNUb1VuaXRzKGJlYXRzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gMSAvIHNlY29uZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBNSURJIG5vdGUgdG8gZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqIEBwYXJhbSAgbWlkaSBUaGUgbWlkaSBudW1iZXIgdG8gY29udmVydC5cbiAgICAgKiBAcmV0dXJuIFRoZSBjb3JyZXNwb25kaW5nIGZyZXF1ZW5jeSB2YWx1ZVxuICAgICAqL1xuICAgIHN0YXRpYyBtdG9mKG1pZGkpIHtcbiAgICAgICAgcmV0dXJuIG10b2YobWlkaSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgYSBmcmVxdWVuY3kgdmFsdWUgdG8gYSBNSURJIG5vdGUuXG4gICAgICogQHBhcmFtIGZyZXF1ZW5jeSBUaGUgdmFsdWUgdG8gZnJlcXVlbmN5IHZhbHVlIHRvIGNvbnZlcnQuXG4gICAgICovXG4gICAgc3RhdGljIGZ0b20oZnJlcXVlbmN5KSB7XG4gICAgICAgIHJldHVybiBmdG9tKGZyZXF1ZW5jeSk7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdEZSRVFVRU5DWSBDT05WRVJTSU9OU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIE5vdGUgdG8gc2NhbGUgaW5kZXguXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IG5vdGVUb1NjYWxlSW5kZXggPSB7XG4gICAgY2JiOiAtMiwgY2I6IC0xLCBjOiAwLCBcImMjXCI6IDEsIGN4OiAyLFxuICAgIGRiYjogMCwgZGI6IDEsIGQ6IDIsIFwiZCNcIjogMywgZHg6IDQsXG4gICAgZWJiOiAyLCBlYjogMywgZTogNCwgXCJlI1wiOiA1LCBleDogNixcbiAgICBmYmI6IDMsIGZiOiA0LCBmOiA1LCBcImYjXCI6IDYsIGZ4OiA3LFxuICAgIGdiYjogNSwgZ2I6IDYsIGc6IDcsIFwiZyNcIjogOCwgZ3g6IDksXG4gICAgYWJiOiA3LCBhYjogOCwgYTogOSwgXCJhI1wiOiAxMCwgYXg6IDExLFxuICAgIGJiYjogOSwgYmI6IDEwLCBiOiAxMSwgXCJiI1wiOiAxMiwgYng6IDEzLFxufTtcbi8qKlxuICogc2NhbGUgaW5kZXggdG8gbm90ZSAoc2hhcnBzKVxuICogQGhpZGRlblxuICovXG5jb25zdCBzY2FsZUluZGV4VG9Ob3RlID0gW1wiQ1wiLCBcIkMjXCIsIFwiRFwiLCBcIkQjXCIsIFwiRVwiLCBcIkZcIiwgXCJGI1wiLCBcIkdcIiwgXCJHI1wiLCBcIkFcIiwgXCJBI1wiLCBcIkJcIl07XG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIGEgRnJlcXVlbmN5Q2xhc3Mgb2JqZWN0LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtaWRpID0gVG9uZS5GcmVxdWVuY3koXCJDM1wiKS50b01pZGkoKTtcbiAqIGNvbnNvbGUubG9nKG1pZGkpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IGhlcnR6ID0gVG9uZS5GcmVxdWVuY3koMzgsIFwibWlkaVwiKS50b0ZyZXF1ZW5jeSgpO1xuICogY29uc29sZS5sb2coaGVydHopO1xuICovXG5leHBvcnQgZnVuY3Rpb24gRnJlcXVlbmN5KHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgRnJlcXVlbmN5Q2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlcXVlbmN5LmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi9UaW1lXCI7XG4vKipcbiAqIFRyYW5zcG9ydFRpbWUgaXMgYSB0aGUgdGltZSBhbG9uZyB0aGUgVHJhbnNwb3J0J3NcbiAqIHRpbWVsaW5lLiBJdCBpcyBzaW1pbGFyIHRvIFRvbmUuVGltZSwgYnV0IGluc3RlYWQgb2YgZXZhbHVhdGluZ1xuICogYWdhaW5zdCB0aGUgQXVkaW9Db250ZXh0J3MgY2xvY2ssIGl0IGlzIGV2YWx1YXRlZCBhZ2FpbnN0XG4gKiB0aGUgVHJhbnNwb3J0J3MgcG9zaXRpb24uIFNlZSBbVHJhbnNwb3J0VGltZSB3aWtpXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRUaW1lQ2xhc3MgZXh0ZW5kcyBUaW1lQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRyYW5zcG9ydFRpbWVcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgaW4gd2hpY2hldmVyIGNvbnRleHQgaXMgcmVsZXZhbnRcbiAgICAgKi9cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzO1xuICAgIH1cbn1cbi8qKlxuICogVHJhbnNwb3J0VGltZSBpcyBhIHRoZSB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQnc1xuICogdGltZWxpbmUuIEl0IGlzIHNpbWlsYXIgdG8gW1tUaW1lXV0sIGJ1dCBpbnN0ZWFkIG9mIGV2YWx1YXRpbmdcbiAqIGFnYWluc3QgdGhlIEF1ZGlvQ29udGV4dCdzIGNsb2NrLCBpdCBpcyBldmFsdWF0ZWQgYWdhaW5zdFxuICogdGhlIFRyYW5zcG9ydCdzIHBvc2l0aW9uLiBTZWUgW1RyYW5zcG9ydFRpbWUgd2lraV0oaHR0cHM6Ly9naXRodWIuY29tL1RvbmVqcy9Ub25lLmpzL3dpa2kvVHJhbnNwb3J0VGltZSkuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgZnVuY3Rpb24gVHJhbnNwb3J0VGltZSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmFuc3BvcnRUaW1lLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4uL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UaW1lXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZSwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNCb29sZWFuLCBpc0RlZmluZWQsIGlzTnVtYmVyLCBpc1N0cmluZywgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBUaGUgQmFzZSBjbGFzcyBmb3IgYWxsIG5vZGVzIHRoYXQgaGF2ZSBhbiBBdWRpb0NvbnRleHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lV2l0aENvbnRleHQgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNvbnRleHRcIl0pO1xuICAgICAgICBpZiAodGhpcy5kZWZhdWx0Q29udGV4dCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gdGhpcy5kZWZhdWx0Q29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IG9wdGlvbnMuY29udGV4dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRDb250ZXh0KCksXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSBDb250ZXh0IGNsb2NrIHBsdXMgdGhlIGxvb2tBaGVhZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgKiBcdGNvbnNvbGUubG9nKFRvbmUubm93KCkpO1xuICAgICAqIH0sIDEwMCk7XG4gICAgICovXG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lICsgdGhpcy5jb250ZXh0Lmxvb2tBaGVhZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIENvbnRleHQgY2xvY2sgd2l0aG91dCBhbnkgbG9va0FoZWFkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2coVG9uZS5pbW1lZGlhdGUoKSk7XG4gICAgICogfSwgMTAwKTtcbiAgICAgKi9cbiAgICBpbW1lZGlhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIG9mIG9uZSBzYW1wbGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLlRyYW5zcG9ydC5zYW1wbGVUaW1lKTtcbiAgICAgKi9cbiAgICBnZXQgc2FtcGxlVGltZSgpIHtcbiAgICAgICAgcmV0dXJuIDEgLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBzZWNvbmRzIG9mIDEgcHJvY2Vzc2luZyBibG9jayAoMTI4IHNhbXBsZXMpXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLkRlc3RpbmF0aW9uLmJsb2NrVGltZSk7XG4gICAgICovXG4gICAgZ2V0IGJsb2NrVGltZSgpIHtcbiAgICAgICAgcmV0dXJuIDEyOCAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbmNvbWluZyB0aW1lIHRvIHNlY29uZHMuXG4gICAgICogVGhpcyBpcyBjYWxjdWxhdGVkIGFnYWluc3QgdGhlIGN1cnJlbnQgW1tUb25lLlRyYW5zcG9ydF1dIGJwbVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZ2FpbiA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhnYWluLnRvU2Vjb25kcyhcIjRuXCIpKSwgMTAwKTtcbiAgICAgKiAvLyByYW1wIHRoZSB0ZW1wbyB0byA2MCBicG0gb3ZlciAzMCBzZWNvbmRzXG4gICAgICogVG9uZS5nZXRUcmFuc3BvcnQoKS5icG0ucmFtcFRvKDYwLCAzMCk7XG4gICAgICovXG4gICAgdG9TZWNvbmRzKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgaW5wdXQgdG8gYSBmcmVxdWVuY3kgbnVtYmVyXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIGNvbnNvbGUubG9nKGdhaW4udG9GcmVxdWVuY3koXCI0blwiKSk7XG4gICAgICovXG4gICAgdG9GcmVxdWVuY3koZnJlcSkge1xuICAgICAgICByZXR1cm4gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgZnJlcSkudG9GcmVxdWVuY3koKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgaW5wdXQgdGltZSBpbnRvIHRpY2tzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIGNvbnNvbGUubG9nKGdhaW4udG9UaWNrcyhcIjRuXCIpKTtcbiAgICAgKi9cbiAgICB0b1RpY2tzKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1RpY2tzKCk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0R0VUL1NFVFxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEdldCBhIHN1YnNldCBvZiB0aGUgcHJvcGVydGllcyB3aGljaCBhcmUgaW4gdGhlIHBhcnRpYWwgcHJvcHNcbiAgICAgKi9cbiAgICBfZ2V0UGFydGlhbFByb3BlcnRpZXMocHJvcHMpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZ2V0KCk7XG4gICAgICAgIC8vIHJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gdGhlIHByb3AgdGhhdCBhcmUgbm90IGluIHRoZSBwYXJ0aWFsXG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNVbmRlZihwcm9wc1tuYW1lXSkpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgb3B0aW9uc1tuYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG9iamVjdCdzIGF0dHJpYnV0ZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCk7XG4gICAgICogY29uc29sZS5sb2cob3NjLmdldCgpKTtcbiAgICAgKi9cbiAgICBnZXQoKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0gZ2V0RGVmYXVsdHNGcm9tSW5zdGFuY2UodGhpcyk7XG4gICAgICAgIE9iamVjdC5rZXlzKGRlZmF1bHRzKS5mb3JFYWNoKGF0dHJpYnV0ZSA9PiB7XG4gICAgICAgICAgICBpZiAoUmVmbGVjdC5oYXModGhpcywgYXR0cmlidXRlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1lbWJlciA9IHRoaXNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKG1lbWJlcikgJiYgaXNEZWZpbmVkKG1lbWJlci52YWx1ZSkgJiYgaXNEZWZpbmVkKG1lbWJlci5zZXRWYWx1ZUF0VGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlci52YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAobWVtYmVyIGluc3RhbmNlb2YgVG9uZVdpdGhDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzW2F0dHJpYnV0ZV0gPSBtZW1iZXIuX2dldFBhcnRpYWxQcm9wZXJ0aWVzKGRlZmF1bHRzW2F0dHJpYnV0ZV0pO1xuICAgICAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgbWFrZSBzdXJlIGl0J3MgYSBzZXJpYWxpemFibGUgdHlwZVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChpc0FycmF5KG1lbWJlcikgfHwgaXNOdW1iZXIobWVtYmVyKSB8fCBpc1N0cmluZyhtZW1iZXIpIHx8IGlzQm9vbGVhbihtZW1iZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzW2F0dHJpYnV0ZV0gPSBtZW1iZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgYWxsIHVuZGVmaW5lZCBhbmQgdW5zZXJpYWxpemFibGUgYXR0cmlidXRlc1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgZGVmYXVsdHNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZGVmYXVsdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBtdWx0aXBsZSBwcm9wZXJ0aWVzIGF0IG9uY2Ugd2l0aCBhbiBvYmplY3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc2V0IHZhbHVlcyB1c2luZyBhbiBvYmplY3RcbiAgICAgKiBmaWx0ZXIuc2V0KHtcbiAgICAgKiBcdGZyZXF1ZW5jeTogXCJDNlwiLFxuICAgICAqIFx0dHlwZTogXCJoaWdocGFzc1wiXG4gICAgICogfSk7XG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvQW5hbG9nc3ludGhfb2N0YXZlc19oaWdobWlkLm1wM1wiKS5jb25uZWN0KGZpbHRlcik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0KHByb3BzKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHByb3BzKS5mb3JFYWNoKGF0dHJpYnV0ZSA9PiB7XG4gICAgICAgICAgICBpZiAoUmVmbGVjdC5oYXModGhpcywgYXR0cmlidXRlKSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzW2F0dHJpYnV0ZV0gJiYgaXNEZWZpbmVkKHRoaXNbYXR0cmlidXRlXS52YWx1ZSkgJiYgaXNEZWZpbmVkKHRoaXNbYXR0cmlidXRlXS5zZXRWYWx1ZUF0VGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc21hbGwgb3B0aW1pemF0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzW2F0dHJpYnV0ZV0udmFsdWUgIT09IHByb3BzW2F0dHJpYnV0ZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXS52YWx1ZSA9IHByb3BzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodGhpc1thdHRyaWJ1dGVdIGluc3RhbmNlb2YgVG9uZVdpdGhDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXS5zZXQocHJvcHNbYXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW2F0dHJpYnV0ZV0gPSBwcm9wc1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVXaXRoQ29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuL0RlYnVnXCI7XG4vKipcbiAqIEEgVGltZWxpbmUgU3RhdGUuIFByb3ZpZGVzIHRoZSBtZXRob2RzOiBgc2V0U3RhdGVBdFRpbWUoXCJzdGF0ZVwiLCB0aW1lKWAgYW5kIGBnZXRWYWx1ZUF0VGltZSh0aW1lKWBcbiAqIEBwYXJhbSBpbml0aWFsIFRoZSBpbml0aWFsIHN0YXRlIG9mIHRoZSBTdGF0ZVRpbWVsaW5lLiAgRGVmYXVsdHMgdG8gYHVuZGVmaW5lZGBcbiAqL1xuZXhwb3J0IGNsYXNzIFN0YXRlVGltZWxpbmUgZXh0ZW5kcyBUaW1lbGluZSB7XG4gICAgY29uc3RydWN0b3IoaW5pdGlhbCA9IFwic3RvcHBlZFwiKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3RhdGVUaW1lbGluZVwiO1xuICAgICAgICB0aGlzLl9pbml0aWFsID0gaW5pdGlhbDtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZUF0VGltZSh0aGlzLl9pbml0aWFsLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIHNjaGVkdWxlZCBiZWZvcmUgb3IgYXRcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm4gIFRoZSBuYW1lIG9mIHRoZSBzdGF0ZSBpbnB1dCBpbiBzZXRTdGF0ZUF0VGltZS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5nZXQodGltZSk7XG4gICAgICAgIGlmIChldmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LnN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRpYWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgc3RhdGUgdG8gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgc3RhdGUgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIHRvIHNldC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqIEBwYXJhbSBvcHRpb25zIEFueSBhZGRpdGlvbmFsIG9wdGlvbnMgdGhhdCBhcmUgbmVlZGVkIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBzZXRTdGF0ZUF0VGltZShzdGF0ZSwgdGltZSwgb3B0aW9ucykge1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwKTtcbiAgICAgICAgdGhpcy5hZGQoT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywge1xuICAgICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgICB0aW1lLFxuICAgICAgICB9KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGV2ZW50IGJlZm9yZSB0aGUgdGltZSB3aXRoIHRoZSBnaXZlbiBzdGF0ZVxuICAgICAqIEBwYXJhbSAgc3RhdGUgVGhlIHN0YXRlIHRvIGxvb2sgZm9yXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGNoZWNrIGJlZm9yZVxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aXRoIHRoZSBnaXZlbiBzdGF0ZSBiZWZvcmUgdGhlIHRpbWVcbiAgICAgKi9cbiAgICBnZXRMYXN0U3RhdGUoc3RhdGUsIHRpbWUpIHtcbiAgICAgICAgLy8gdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl90aW1lbGluZVtpXTtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gc3RhdGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBldmVudCBhZnRlciB0aGUgdGltZSB3aXRoIHRoZSBnaXZlbiBzdGF0ZVxuICAgICAqIEBwYXJhbSAgc3RhdGUgVGhlIHN0YXRlIHRvIGxvb2sgZm9yXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGNoZWNrIGZyb21cbiAgICAgKiBAcmV0dXJuICBUaGUgZXZlbnQgd2l0aCB0aGUgZ2l2ZW4gc3RhdGUgYWZ0ZXIgdGhlIHRpbWVcbiAgICAgKi9cbiAgICBnZXROZXh0U3RhdGUoc3RhdGUsIHRpbWUpIHtcbiAgICAgICAgLy8gdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gc3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0YXRlVGltZWxpbmUuanMubWFwIiwiaW1wb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiIH0gZnJvbSBcIi4uL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IGlzQXVkaW9QYXJhbSB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuL1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi4vdXRpbC9NYXRoXCI7XG5pbXBvcnQgeyBhc3NlcnQsIGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogUGFyYW0gd3JhcHMgdGhlIG5hdGl2ZSBXZWIgQXVkaW8ncyBBdWRpb1BhcmFtIHRvIHByb3ZpZGVcbiAqIGFkZGl0aW9uYWwgdW5pdCBjb252ZXJzaW9uIGZ1bmN0aW9uYWxpdHkuIEl0IGFsc29cbiAqIHNlcnZlcyBhcyBhIGJhc2UtY2xhc3MgZm9yIGNsYXNzZXMgd2hpY2ggaGF2ZSBhIHNpbmdsZSxcbiAqIGF1dG9tYXRhYmxlIHBhcmFtZXRlci5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBQYXJhbSBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFyYW1cIiwgXCJ1bml0c1wiLCBcImNvbnZlcnRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXJhbVwiO1xuICAgICAgICB0aGlzLm92ZXJyaWRkZW4gPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtaW5pbXVtIG91dHB1dCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbWluT3V0cHV0ID0gMWUtNztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFyYW1cIiwgXCJ1bml0c1wiLCBcImNvbnZlcnRcIl0pO1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKG9wdGlvbnMucGFyYW0pICYmXG4gICAgICAgICAgICAoaXNBdWRpb1BhcmFtKG9wdGlvbnMucGFyYW0pIHx8IG9wdGlvbnMucGFyYW0gaW5zdGFuY2VvZiBQYXJhbSksIFwicGFyYW0gbXVzdCBiZSBhbiBBdWRpb1BhcmFtXCIpO1xuICAgICAgICB3aGlsZSAoIWlzQXVkaW9QYXJhbShvcHRpb25zLnBhcmFtKSkge1xuICAgICAgICAgICAgb3B0aW9ucy5wYXJhbSA9IG9wdGlvbnMucGFyYW0uX3BhcmFtO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N3YXBwYWJsZSA9IGlzRGVmaW5lZChvcHRpb25zLnN3YXBwYWJsZSkgPyBvcHRpb25zLnN3YXBwYWJsZSA6IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5fc3dhcHBhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgIC8vIGluaXRpYWxpemVcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtID0gb3B0aW9ucy5wYXJhbTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbSA9IHRoaXMuaW5wdXQgPSBvcHRpb25zLnBhcmFtO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBUaW1lbGluZSgxMDAwKTtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlID0gdGhpcy5fcGFyYW0uZGVmYXVsdFZhbHVlO1xuICAgICAgICB0aGlzLnVuaXRzID0gb3B0aW9ucy51bml0cztcbiAgICAgICAgdGhpcy5jb252ZXJ0ID0gb3B0aW9ucy5jb252ZXJ0O1xuICAgICAgICB0aGlzLl9taW5WYWx1ZSA9IG9wdGlvbnMubWluVmFsdWU7XG4gICAgICAgIHRoaXMuX21heFZhbHVlID0gb3B0aW9ucy5tYXhWYWx1ZTtcbiAgICAgICAgLy8gaWYgdGhlIHZhbHVlIGlzIGRlZmluZWQsIHNldCBpdCBpbW1lZGlhdGVseVxuICAgICAgICBpZiAoaXNEZWZpbmVkKG9wdGlvbnMudmFsdWUpICYmIG9wdGlvbnMudmFsdWUgIT09IHRoaXMuX3RvVHlwZSh0aGlzLl9pbml0aWFsVmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMudmFsdWUsIDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbnZlcnQ6IHRydWUsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVBdFRpbWUobm93KTtcbiAgICB9XG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMubm93KCkpO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICAvLyBpZiBpdCdzIG5vdCB0aGUgZGVmYXVsdCBtaW5WYWx1ZSwgcmV0dXJuIGl0XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fbWluVmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWluVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJ0aW1lXCIgfHwgdGhpcy51bml0cyA9PT0gXCJmcmVxdWVuY3lcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJub3JtYWxSYW5nZVwiIHx8IHRoaXMudW5pdHMgPT09IFwicG9zaXRpdmVcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJ0cmFuc3BvcnRUaW1lXCIgfHwgdGhpcy51bml0cyA9PT0gXCJ0aWNrc1wiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcImJwbVwiIHx8IHRoaXMudW5pdHMgPT09IFwiaGVydHpcIiB8fCB0aGlzLnVuaXRzID09PSBcInNhbXBsZXNcIikge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJhdWRpb1JhbmdlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAtSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWluVmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX21heFZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21heFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwibm9ybWFsUmFuZ2VcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJhdWRpb1JhbmdlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1heFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFR5cGUgZ3VhcmQgYmFzZWQgb24gdGhlIHVuaXQgbmFtZVxuICAgICAqL1xuICAgIF9pcyhhcmcsIHR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudW5pdHMgPT09IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1ha2Ugc3VyZSB0aGUgdmFsdWUgaXMgYWx3YXlzIGluIHRoZSBkZWZpbmVkIHJhbmdlXG4gICAgICovXG4gICAgX2Fzc2VydFJhbmdlKHZhbHVlKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5tYXhWYWx1ZSkgJiYgaXNEZWZpbmVkKHRoaXMubWluVmFsdWUpKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh2YWx1ZSwgdGhpcy5fZnJvbVR5cGUodGhpcy5taW5WYWx1ZSksIHRoaXMuX2Zyb21UeXBlKHRoaXMubWF4VmFsdWUpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGdpdmVuIHZhbHVlIGZyb20gdGhlIHR5cGUgc3BlY2lmaWVkIGJ5IFBhcmFtLnVuaXRzXG4gICAgICogaW50byB0aGUgZGVzdGluYXRpb24gdmFsdWUgKHN1Y2ggYXMgR2FpbiBvciBGcmVxdWVuY3kpLlxuICAgICAqL1xuICAgIF9mcm9tVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udmVydCAmJiAhdGhpcy5vdmVycmlkZGVuKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXModmFsLCBcInRpbWVcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b1NlY29uZHModmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2lzKHZhbCwgXCJkZWNpYmVsc1wiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkYlRvR2Fpbih2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXModmFsLCBcImZyZXF1ZW5jeVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvRnJlcXVlbmN5KHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMub3ZlcnJpZGRlbikge1xuICAgICAgICAgICAgLy8gaWYgaXQncyBvdmVycmlkZGVuLCBzaG91bGQgb25seSBzY2hlZHVsZSAwc1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIHBhcmFtZXRlcnMgdmFsdWUgaW50byB0aGUgdW5pdHMgc3BlY2lmaWVkIGJ5IFBhcmFtLnVuaXRzLlxuICAgICAqL1xuICAgIF90b1R5cGUodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnZlcnQgJiYgdGhpcy51bml0cyA9PT0gXCJkZWNpYmVsc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2FpblRvRGIodmFsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQUJTVFJBQ1QgUEFSQU0gSU5URVJGQUNFXG4gICAgLy8gYWxsIGRvY3MgYXJlIGdlbmVyYXRlZCBmcm9tIFBhcmFtSW50ZXJmYWNlLnRzXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gc2V0VmFsdWVBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJzZXRWYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogbnVtZXJpY1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBNYXRoLm1heCh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgMCk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgbGV0IHZhbHVlID0gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICAvLyBpZiBpdCB3YXMgc2V0IGJ5XG4gICAgICAgIGlmIChiZWZvcmUgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJlZm9yZS50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiICYmIChhZnRlciA9PT0gbnVsbCB8fCBhZnRlci50eXBlID09PSBcInNldFZhbHVlQXRUaW1lXCIpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2V2ZW50cy5nZXRCZWZvcmUoYmVmb3JlLnRpbWUpO1xuICAgICAgICAgICAgbGV0IHByZXZpb3VzVmFsO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNWYWwgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbCA9IHByZXZpb3VzLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGJlZm9yZS50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9leHBvbmVudGlhbEFwcHJvYWNoKGJlZm9yZS50aW1lLCBwcmV2aW91c1ZhbCwgYmVmb3JlLnZhbHVlLCBiZWZvcmUuY29uc3RhbnQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWZ0ZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmVmb3JlLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIiB8fCBhZnRlci50eXBlID09PSBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgbGV0IGJlZm9yZVZhbHVlID0gYmVmb3JlLnZhbHVlO1xuICAgICAgICAgICAgaWYgKGJlZm9yZS50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXMgPSB0aGlzLl9ldmVudHMuZ2V0QmVmb3JlKGJlZm9yZS50aW1lKTtcbiAgICAgICAgICAgICAgICBpZiAocHJldmlvdXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlVmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBiZWZvcmVWYWx1ZSA9IHByZXZpb3VzLnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2xpbmVhckludGVycG9sYXRlKGJlZm9yZS50aW1lLCBiZWZvcmVWYWx1ZSwgYWZ0ZXIudGltZSwgYWZ0ZXIudmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZVZhbHVlLCBhZnRlci50aW1lLCBhZnRlci52YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlID0gYmVmb3JlLnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodmFsdWUpO1xuICAgIH1cbiAgICBzZXRSYW1wUG9pbnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGxldCBjdXJyZW50VmFsID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgdGhpcy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fZnJvbVR5cGUoY3VycmVudFZhbCkgPT09IDApIHtcbiAgICAgICAgICAgIGN1cnJlbnRWYWwgPSB0aGlzLl90b1R5cGUodGhpcy5fbWluT3V0cHV0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKGN1cnJlbnRWYWwsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhlbmRUaW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gbGluZWFyUmFtcFRvVmFsdWVBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeShlbmRUaW1lKX1gKTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogbnVtZXJpY1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICBsZXQgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyB0aGUgdmFsdWUgY2FuJ3QgYmUgMFxuICAgICAgICBudW1lcmljVmFsdWUgPSBFUShudW1lcmljVmFsdWUsIDApID8gdGhpcy5fbWluT3V0cHV0IDogbnVtZXJpY1ZhbHVlO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhlbmRUaW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KGVuZFRpbWUpfWApO1xuICAgICAgICAvLyBzdG9yZSB0aGUgZXZlbnRcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIiwgdmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSArIHRoaXMudG9TZWNvbmRzKHJhbXBUaW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lLCByYW1wVGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJhbXBUaW1lID0gdGhpcy50b1NlY29uZHMocmFtcFRpbWUpO1xuICAgICAgICBjb25zdCB0aW1lQ29uc3RhbnQgPSBNYXRoLmxvZyhyYW1wVGltZSArIDEpIC8gTWF0aC5sb2coMjAwKTtcbiAgICAgICAgdGhpcy5zZXRUYXJnZXRBdFRpbWUodmFsdWUsIHRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIC8vIGF0IDkwJSBzdGFydCBhIGxpbmVhciByYW1wIHRvIHRoZSBmaW5hbCB2YWx1ZVxuICAgICAgICB0aGlzLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSArIHJhbXBUaW1lICogMC45KTtcbiAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSArIHJhbXBUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBUaGUgdmFsdWUgd2lsbCBuZXZlciBiZSBhYmxlIHRvIGFwcHJvYWNoIHdpdGhvdXQgdGltZUNvbnN0YW50ID4gMC5cbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKHRpbWVDb25zdGFudCkgJiYgdGltZUNvbnN0YW50ID4gMCwgXCJ0aW1lQ29uc3RhbnQgbXVzdCBiZSBhIG51bWJlciBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKG51bWVyaWNWYWx1ZSkgJiYgaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQocykgdG8gc2V0VGFyZ2V0QXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkoc3RhcnRUaW1lKX1gKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICBjb25zdGFudDogdGltZUNvbnN0YW50LFxuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRUYXJnZXRBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcInNldFRhcmdldEF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRUYXJnZXRBdFRpbWUobnVtZXJpY1ZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZyA9IDEpIHtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0aW5nVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZXNbMF0pICogc2NhbGluZztcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUoc3RhcnRpbmdWYWx1ZSksIHN0YXJ0VGltZSk7XG4gICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBkdXJhdGlvbiAvICh2YWx1ZXMubGVuZ3RoIC0gMSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZXNbaV0pICogc2NhbGluZztcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKG51bWVyaWNWYWx1ZSksIHN0YXJ0VGltZSArIGkgKiBzZWdUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudCB0byBjYW5jZWxTY2hlZHVsZWRWYWx1ZXM6ICR7SlNPTi5zdHJpbmdpZnkodGltZSl9YCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiY2FuY2VsU2NoZWR1bGVkVmFsdWVzXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHZhbHVlQXRUaW1lID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpKTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBzY2hlZHVsZSBldmVudHNcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50IHRvIGNhbmNlbEFuZEhvbGRBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodGltZSl9YCk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiY2FuY2VsQW5kSG9sZEF0VGltZVwiLCBjb21wdXRlZFRpbWUsIFwidmFsdWU9XCIgKyB2YWx1ZUF0VGltZSk7XG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIGV2ZW50IGF0IHRoZSBnaXZlbiBjb21wdXRlZFRpbWVcbiAgICAgICAgLy8gYW5kIHRoYXQgZXZlbiBpcyBub3QgYSBcInNldFwiXG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKGJlZm9yZSAmJiBFUShiZWZvcmUudGltZSwgY29tcHV0ZWRUaW1lKSkge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGV2ZXJ5dGhpbmcgYWZ0ZXJcbiAgICAgICAgICAgIGlmIChhZnRlcikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhhZnRlci50aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoY29tcHV0ZWRUaW1lICsgdGhpcy5zYW1wbGVUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhZnRlcikge1xuICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgLy8gY2FuY2VsIHRoZSBuZXh0IGV2ZW50KHMpXG4gICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHZhbHVlQXRUaW1lKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGFmdGVyLnR5cGUgPT09IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZSh2YWx1ZUF0VGltZSksIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZUF0VGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlQXRUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgcmFtcFRvKHZhbHVlLCByYW1wVGltZSA9IDAuMSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGlmICh0aGlzLnVuaXRzID09PSBcImZyZXF1ZW5jeVwiIHx8IHRoaXMudW5pdHMgPT09IFwiYnBtXCIgfHwgdGhpcy51bml0cyA9PT0gXCJkZWNpYmVsc1wiKSB7XG4gICAgICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXBwbHkgYWxsIG9mIHRoZSBwcmV2aW91c2x5IHNjaGVkdWxlZCBldmVudHMgdG8gdGhlIHBhc3NlZCBpbiBQYXJhbSBvciBBdWRpb1BhcmFtLlxuICAgICAqIFRoZSBhcHBsaWVkIHZhbHVlcyB3aWxsIHN0YXJ0IGF0IHRoZSBjb250ZXh0J3MgY3VycmVudCB0aW1lIGFuZCBzY2hlZHVsZVxuICAgICAqIGFsbCBvZiB0aGUgZXZlbnRzIHdoaWNoIGFyZSBzY2hlZHVsZWQgb24gdGhpcyBQYXJhbSBvbnRvIHRoZSBwYXNzZWQgaW4gcGFyYW0uXG4gICAgICovXG4gICAgYXBwbHkocGFyYW0pIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAvLyBzZXQgdGhlIHBhcmFtJ3MgdmFsdWUgYXQgdGhlIGN1cnJlbnQgdGltZSBhbmQgc2NoZWR1bGUgZXZlcnl0aGluZyBlbHNlXG4gICAgICAgIHBhcmFtLnNldFZhbHVlQXRUaW1lKHRoaXMuZ2V0VmFsdWVBdFRpbWUobm93KSwgbm93KTtcbiAgICAgICAgLy8gaWYgdGhlIHByZXZpb3VzIGV2ZW50IHdhcyBhIGN1cnZlLCB0aGVuIHNldCB0aGUgcmVzdCBvZiBpdFxuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChub3cpO1xuICAgICAgICBpZiAocHJldmlvdXNFdmVudCAmJiBwcmV2aW91c0V2ZW50LnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgIC8vIGFwcHJveCBpdCB1bnRpbCB0aGUgbmV4dCBldmVudCB3aXRoIGxpbmVhciByYW1wc1xuICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKHByZXZpb3VzRXZlbnQudGltZSk7XG4gICAgICAgICAgICAvLyBvciBmb3IgMiBzZWNvbmRzIGlmIHRoZXJlIGlzIG5vIGV2ZW50XG4gICAgICAgICAgICBjb25zdCBlbmRUaW1lID0gbmV4dEV2ZW50ID8gbmV4dEV2ZW50LnRpbWUgOiBub3cgKyAyO1xuICAgICAgICAgICAgY29uc3Qgc3ViZGl2aXNpb25zID0gKGVuZFRpbWUgLSBub3cpIC8gMTA7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gbm93OyBpIDwgZW5kVGltZTsgaSArPSBzdWJkaXZpc2lvbnMpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLmdldFZhbHVlQXRUaW1lKGkpLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaEFmdGVyKHRoaXMuY29udGV4dC5jdXJyZW50VGltZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwiY2FuY2VsU2NoZWR1bGVkVmFsdWVzXCIpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChldmVudC50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgcGFyYW0uc2V0VGFyZ2V0QXRUaW1lKGV2ZW50LnZhbHVlLCBldmVudC50aW1lLCBldmVudC5jb25zdGFudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJhbVtldmVudC50eXBlXShldmVudC52YWx1ZSwgZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVwbGFjZSB0aGUgUGFyYW0ncyBpbnRlcm5hbCBBdWRpb1BhcmFtLiBXaWxsIGFwcGx5IHNjaGVkdWxlZCBjdXJ2ZXNcbiAgICAgKiBvbnRvIHRoZSBwYXJhbWV0ZXIgYW5kIHJlcGxhY2UgdGhlIGNvbm5lY3Rpb25zLlxuICAgICAqL1xuICAgIHNldFBhcmFtKHBhcmFtKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zd2FwcGFibGUsIFwiVGhlIFBhcmFtIG11c3QgYmUgYXNzaWduZWQgYXMgJ3N3YXBwYWJsZScgaW4gdGhlIGNvbnN0cnVjdG9yXCIpO1xuICAgICAgICBjb25zdCBpbnB1dCA9IHRoaXMuaW5wdXQ7XG4gICAgICAgIGlucHV0LmRpc2Nvbm5lY3QodGhpcy5fcGFyYW0pO1xuICAgICAgICB0aGlzLmFwcGx5KHBhcmFtKTtcbiAgICAgICAgdGhpcy5fcGFyYW0gPSBwYXJhbTtcbiAgICAgICAgaW5wdXQuY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgZGVmYXVsdFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdG9UeXBlKHRoaXMuX3BhcmFtLmRlZmF1bHRWYWx1ZSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0QVVUT01BVElPTiBDVVJWRSBDQUxDVUxBVElPTlNcbiAgICAvLyBcdE1JVCBMaWNlbnNlLCBjb3B5cmlnaHQgKGMpIDIwMTQgSm9yZGFuIFNhbnRlbGxcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDYWxjdWxhdGVzIHRoZSB0aGUgdmFsdWUgYWxvbmcgdGhlIGN1cnZlIHByb2R1Y2VkIGJ5IHNldFRhcmdldEF0VGltZVxuICAgIF9leHBvbmVudGlhbEFwcHJvYWNoKHQwLCB2MCwgdjEsIHRpbWVDb25zdGFudCwgdCkge1xuICAgICAgICByZXR1cm4gdjEgKyAodjAgLSB2MSkgKiBNYXRoLmV4cCgtKHQgLSB0MCkgLyB0aW1lQ29uc3RhbnQpO1xuICAgIH1cbiAgICAvLyBDYWxjdWxhdGVzIHRoZSB0aGUgdmFsdWUgYWxvbmcgdGhlIGN1cnZlIHByb2R1Y2VkIGJ5IGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXG4gICAgX2xpbmVhckludGVycG9sYXRlKHQwLCB2MCwgdDEsIHYxLCB0KSB7XG4gICAgICAgIHJldHVybiB2MCArICh2MSAtIHYwKSAqICgodCAtIHQwKSAvICh0MSAtIHQwKSk7XG4gICAgfVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVxuICAgIF9leHBvbmVudGlhbEludGVycG9sYXRlKHQwLCB2MCwgdDEsIHYxLCB0KSB7XG4gICAgICAgIHJldHVybiB2MCAqIE1hdGgucG93KHYxIC8gdjAsICh0IC0gdDApIC8gKHQxIC0gdDApKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZSwgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4vVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQsIHdhcm4gfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBUb25lQXVkaW9Ob2RlIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBjbGFzc2VzIHdoaWNoIHByb2Nlc3MgYXVkaW8uXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9Ob2RlIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYW1lIG9mIHRoZSBjbGFzc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9Ob2RlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMaXN0IGFsbCBvZiB0aGUgbm9kZSB0aGF0IG11c3QgYmUgc2V0IHRvIG1hdGNoIHRoZSBDaGFubmVsUHJvcGVydGllc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGlucHV0cyBmZWVkaW5nIGludG8gdGhlIEF1ZGlvTm9kZS5cbiAgICAgKiBGb3Igc291cmNlIG5vZGVzLCB0aGlzIHdpbGwgYmUgMC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vZGUgPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2cobm9kZS5udW1iZXJPZklucHV0cyk7XG4gICAgICovXG4gICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb1BhcmFtKHRoaXMuaW5wdXQpIHx8IHRoaXMuaW5wdXQgaW5zdGFuY2VvZiBQYXJhbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG91dHB1dHMgb2YgdGhlIEF1ZGlvTm9kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vZGUgPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2cobm9kZS5udW1iZXJPZk91dHB1dHMpO1xuICAgICAqL1xuICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vdXRwdXQubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQVVESU8gUFJPUEVSVElFU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFVzZWQgdG8gZGVjaWRlIHdoaWNoIG5vZGVzIHRvIGdldC9zZXQgcHJvcGVydGllcyBvblxuICAgICAqL1xuICAgIF9pc0F1ZGlvTm9kZShub2RlKSB7XG4gICAgICAgIHJldHVybiBpc0RlZmluZWQobm9kZSkgJiYgKG5vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlIHx8IGlzQXVkaW9Ob2RlKG5vZGUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFsbCBvZiB0aGUgYXVkaW8gbm9kZXMgKGVpdGhlciBpbnRlcm5hbCBvciBpbnB1dC9vdXRwdXQpIHdoaWNoIHRvZ2V0aGVyXG4gICAgICogbWFrZSB1cCBob3cgdGhlIGNsYXNzIG5vZGUgcmVzcG9uZHMgdG8gY2hhbm5lbCBpbnB1dC9vdXRwdXRcbiAgICAgKi9cbiAgICBfZ2V0SW50ZXJuYWxOb2RlcygpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9pbnRlcm5hbENoYW5uZWxzLnNsaWNlKDApO1xuICAgICAgICBpZiAodGhpcy5faXNBdWRpb05vZGUodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgIG5vZGVMaXN0LnB1c2godGhpcy5pbnB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2lzQXVkaW9Ob2RlKHRoaXMub3V0cHV0KSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5wdXQgIT09IHRoaXMub3V0cHV0KSB7XG4gICAgICAgICAgICAgICAgbm9kZUxpc3QucHVzaCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5vZGVMaXN0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGF1ZGlvIG9wdGlvbnMgZm9yIHRoaXMgbm9kZSBzdWNoIGFzIGNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAqIGNoYW5uZWxDb3VudCwgZXRjLlxuICAgICAqIEBwYXJhbSBvcHRpb25zXG4gICAgICovXG4gICAgX3NldENoYW5uZWxQcm9wZXJ0aWVzKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9nZXRJbnRlcm5hbE5vZGVzKCk7XG4gICAgICAgIG5vZGVMaXN0LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxDb3VudCA9IG9wdGlvbnMuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgbm9kZS5jaGFubmVsQ291bnRNb2RlID0gb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgbm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCBhdWRpbyBvcHRpb25zIGZvciB0aGlzIG5vZGUgc3VjaCBhcyBjaGFubmVsSW50ZXJwcmV0YXRpb25cbiAgICAgKiBjaGFubmVsQ291bnQsIGV0Yy5cbiAgICAgKi9cbiAgICBfZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKSB7XG4gICAgICAgIGNvbnN0IG5vZGVMaXN0ID0gdGhpcy5fZ2V0SW50ZXJuYWxOb2RlcygpO1xuICAgICAgICBhc3NlcnQobm9kZUxpc3QubGVuZ3RoID4gMCwgXCJUb25lQXVkaW9Ob2RlIGRvZXMgbm90IGhhdmUgYW55IGludGVybmFsIG5vZGVzXCIpO1xuICAgICAgICAvLyB1c2UgdGhlIGZpcnN0IG5vZGUgdG8gZ2V0IHByb3BlcnRpZXNcbiAgICAgICAgLy8gdGhleSBzaG91bGQgYWxsIGJlIHRoZSBzYW1lXG4gICAgICAgIGNvbnN0IG5vZGUgPSBub2RlTGlzdFswXTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBub2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFubmVsQ291bnQgaXMgdGhlIG51bWJlciBvZiBjaGFubmVscyB1c2VkIHdoZW4gdXAtbWl4aW5nIGFuZCBkb3duLW1peGluZ1xuICAgICAqIGNvbm5lY3Rpb25zIHRvIGFueSBpbnB1dHMgdG8gdGhlIG5vZGUuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIDIgZXhjZXB0IGZvclxuICAgICAqIHNwZWNpZmljIG5vZGVzIHdoZXJlIGl0cyB2YWx1ZSBpcyBzcGVjaWFsbHkgZGV0ZXJtaW5lZC5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKS5jaGFubmVsQ291bnQ7XG4gICAgfVxuICAgIHNldCBjaGFubmVsQ291bnQoY2hhbm5lbENvdW50KSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKTtcbiAgICAgICAgLy8gbWVyZ2UgaXQgd2l0aCB0aGUgb3RoZXIgcHJvcGVydGllc1xuICAgICAgICB0aGlzLl9zZXRDaGFubmVsUHJvcGVydGllcyhPYmplY3QuYXNzaWduKHByb3BzLCB7IGNoYW5uZWxDb3VudCB9KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYW5uZWxDb3VudE1vZGUgZGV0ZXJtaW5lcyBob3cgY2hhbm5lbHMgd2lsbCBiZSBjb3VudGVkIHdoZW4gdXAtbWl4aW5nIGFuZFxuICAgICAqIGRvd24tbWl4aW5nIGNvbm5lY3Rpb25zIHRvIGFueSBpbnB1dHMgdG8gdGhlIG5vZGUuXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCJtYXhcIi4gVGhpcyBhdHRyaWJ1dGUgaGFzIG5vIGVmZmVjdCBmb3Igbm9kZXMgd2l0aCBubyBpbnB1dHMuXG4gICAgICogKiBcIm1heFwiIC0gY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzIGlzIHRoZSBtYXhpbXVtIG9mIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgb2YgYWxsIGNvbm5lY3Rpb25zIHRvIGFuIGlucHV0LiBJbiB0aGlzIG1vZGUgY2hhbm5lbENvdW50IGlzIGlnbm9yZWQuXG4gICAgICogKiBcImNsYW1wZWQtbWF4XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgZGV0ZXJtaW5lZCBhcyBmb3IgXCJtYXhcIiBhbmQgdGhlbiBjbGFtcGVkIHRvIGEgbWF4aW11bSB2YWx1ZSBvZiB0aGUgZ2l2ZW4gY2hhbm5lbENvdW50LlxuICAgICAqICogXCJleHBsaWNpdFwiIC0gY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzIGlzIHRoZSBleGFjdCB2YWx1ZSBhcyBzcGVjaWZpZWQgYnkgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkuY2hhbm5lbENvdW50TW9kZTtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxDb3VudE1vZGUoY2hhbm5lbENvdW50TW9kZSkge1xuICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCk7XG4gICAgICAgIC8vIG1lcmdlIGl0IHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5fc2V0Q2hhbm5lbFByb3BlcnRpZXMoT2JqZWN0LmFzc2lnbihwcm9wcywgeyBjaGFubmVsQ291bnRNb2RlIH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhbm5lbEludGVycHJldGF0aW9uIGRldGVybWluZXMgaG93IGluZGl2aWR1YWwgY2hhbm5lbHMgd2lsbCBiZSB0cmVhdGVkXG4gICAgICogd2hlbiB1cC1taXhpbmcgYW5kIGRvd24tbWl4aW5nIGNvbm5lY3Rpb25zIHRvIGFueSBpbnB1dHMgdG8gdGhlIG5vZGUuXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgXCJzcGVha2Vyc1wiLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbihjaGFubmVsSW50ZXJwcmV0YXRpb24pIHtcbiAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpO1xuICAgICAgICAvLyBtZXJnZSBpdCB3aXRoIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuX3NldENoYW5uZWxQcm9wZXJ0aWVzKE9iamVjdC5hc3NpZ24ocHJvcHMsIHsgY2hhbm5lbEludGVycHJldGF0aW9uIH0pKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQ09OTkVDVElPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBjb25uZWN0IHRoZSBvdXRwdXQgb2YgYSBUb25lQXVkaW9Ob2RlIHRvIGFuIEF1ZGlvUGFyYW0sIEF1ZGlvTm9kZSwgb3IgVG9uZUF1ZGlvTm9kZVxuICAgICAqIEBwYXJhbSBkZXN0aW5hdGlvbiBUaGUgb3V0cHV0IHRvIGNvbm5lY3QgdG9cbiAgICAgKiBAcGFyYW0gb3V0cHV0TnVtIFRoZSBvdXRwdXQgdG8gY29ubmVjdCBmcm9tXG4gICAgICogQHBhcmFtIGlucHV0TnVtIFRoZSBpbnB1dCB0byBjb25uZWN0IHRvXG4gICAgICovXG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGNvbm5lY3QodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgb3V0cHV0IHRvIHRoZSBjb250ZXh0J3MgZGVzdGluYXRpb24gbm9kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJDMlwiKS5zdGFydCgpO1xuICAgICAqIG9zYy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICovXG4gICAgdG9EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgdGhpcy5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBvdXRwdXQgdG8gdGhlIGNvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqIFNlZSBbW3RvRGVzdGluYXRpb25dXVxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgdG9NYXN0ZXIoKSB7XG4gICAgICAgIHdhcm4oXCJ0b01hc3RlcigpIGhhcyBiZWVuIHJlbmFtZWQgdG9EZXN0aW5hdGlvbigpXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGRpc2Nvbm5lY3QgdGhlIG91dHB1dFxuICAgICAqL1xuICAgIGRpc2Nvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bSA9IDAsIGlucHV0TnVtID0gMCkge1xuICAgICAgICBkaXNjb25uZWN0KHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgdG8gdGhlIHJlc3Qgb2YgdGhlIG5vZGVzIGluIHNlcmllcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9kcnVtLXNhbXBsZXMvaGFuZGRydW0tbG9vcC5tcDNcIik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogY29uc3QgZmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcig0KS5zdGFydCgpO1xuICAgICAqIGNvbnN0IGRpc3RvcnRpb24gPSBuZXcgVG9uZS5EaXN0b3J0aW9uKDAuNSk7XG4gICAgICogLy8gY29ubmVjdCB0aGUgcGxheWVyIHRvIHRoZSBmaWx0ZXIsIGRpc3RvcnRpb24gYW5kIHRoZW4gdG8gdGhlIG1hc3RlciBvdXRwdXRcbiAgICAgKiBwbGF5ZXIuY2hhaW4oZmlsdGVyLCBkaXN0b3J0aW9uLCBUb25lLkRlc3RpbmF0aW9uKTtcbiAgICAgKi9cbiAgICBjaGFpbiguLi5ub2Rlcykge1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMsIC4uLm5vZGVzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGlzIG5vZGUgdG8gdGhlIHJlc3Qgb2YgdGhlIG5vZGVzIGluIHBhcmFsbGVsLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9jb25nYS1yaHl0aG0ubXAzXCIpO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqIGNvbnN0IHBpdGNoU2hpZnQgPSBuZXcgVG9uZS5QaXRjaFNoaWZ0KDQpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoXCJHNVwiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gY29ubmVjdCBhIG5vZGUgdG8gdGhlIHBpdGNoIHNoaWZ0IGFuZCBmaWx0ZXIgaW4gcGFyYWxsZWxcbiAgICAgKiBwbGF5ZXIuZmFuKHBpdGNoU2hpZnQsIGZpbHRlcik7XG4gICAgICovXG4gICAgZmFuKC4uLm5vZGVzKSB7XG4gICAgICAgIG5vZGVzLmZvckVhY2gobm9kZSA9PiB0aGlzLmNvbm5lY3Qobm9kZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcG9zZSBhbmQgZGlzY29ubmVjdFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5wdXQgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZSh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5vdXRwdXQgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNBdWRpb05vZGUodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vdXRwdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBDT05ORUNUSU9OU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIGNvbm5lY3QgdG9nZXRoZXIgYWxsIG9mIHRoZSBhcmd1bWVudHMgaW4gc2VyaWVzXG4gKiBAcGFyYW0gbm9kZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RTZXJpZXMoLi4ubm9kZXMpIHtcbiAgICBjb25zdCBmaXJzdCA9IG5vZGVzLnNoaWZ0KCk7XG4gICAgbm9kZXMucmVkdWNlKChwcmV2LCBjdXJyZW50KSA9PiB7XG4gICAgICAgIGlmIChwcmV2IGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgcHJldi5jb25uZWN0KGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKHByZXYpKSB7XG4gICAgICAgICAgICBjb25uZWN0KHByZXYsIGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjdXJyZW50O1xuICAgIH0sIGZpcnN0KTtcbn1cbi8qKlxuICogQ29ubmVjdCB0d28gbm9kZXMgdG9nZXRoZXIgc28gdGhhdCBzaWduYWwgZmxvd3MgZnJvbSB0aGVcbiAqIGZpcnN0IG5vZGUgdG8gdGhlIHNlY29uZC4gT3B0aW9uYWxseSBzcGVjaWZ5IHRoZSBpbnB1dCBhbmQgb3V0cHV0IGNoYW5uZWxzLlxuICogQHBhcmFtIHNyY05vZGUgVGhlIHNvdXJjZSBub2RlXG4gKiBAcGFyYW0gZHN0Tm9kZSBUaGUgZGVzdGluYXRpb24gbm9kZVxuICogQHBhcmFtIG91dHB1dE51bWJlciBUaGUgb3V0cHV0IGNoYW5uZWwgb2YgdGhlIHNyY05vZGVcbiAqIEBwYXJhbSBpbnB1dE51bWJlciBUaGUgaW5wdXQgY2hhbm5lbCBvZiB0aGUgZHN0Tm9kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdChzcmNOb2RlLCBkc3ROb2RlLCBvdXRwdXROdW1iZXIgPSAwLCBpbnB1dE51bWJlciA9IDApIHtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKHNyY05vZGUpLCBcIkNhbm5vdCBjb25uZWN0IGZyb20gdW5kZWZpbmVkIG5vZGVcIik7XG4gICAgYXNzZXJ0KGlzRGVmaW5lZChkc3ROb2RlKSwgXCJDYW5ub3QgY29ubmVjdCB0byB1bmRlZmluZWQgbm9kZVwiKTtcbiAgICBpZiAoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgaXNBdWRpb05vZGUoZHN0Tm9kZSkpIHtcbiAgICAgICAgYXNzZXJ0KGRzdE5vZGUubnVtYmVyT2ZJbnB1dHMgPiAwLCBcIkNhbm5vdCBjb25uZWN0IHRvIG5vZGUgd2l0aCBubyBpbnB1dHNcIik7XG4gICAgfVxuICAgIGFzc2VydChzcmNOb2RlLm51bWJlck9mT3V0cHV0cyA+IDAsIFwiQ2Fubm90IGNvbm5lY3QgZnJvbSBub2RlIHdpdGggbm8gb3V0cHV0c1wiKTtcbiAgICAvLyByZXNvbHZlIHRoZSBpbnB1dCBvZiB0aGUgZHN0Tm9kZVxuICAgIHdoaWxlICgoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgZHN0Tm9kZSBpbnN0YW5jZW9mIFBhcmFtKSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKGRzdE5vZGUuaW5wdXQpKSB7XG4gICAgICAgICAgICBkc3ROb2RlID0gZHN0Tm9kZS5pbnB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoc3JjTm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChzcmNOb2RlLm91dHB1dCkpIHtcbiAgICAgICAgICAgIHNyY05vZGUgPSBzcmNOb2RlLm91dHB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBtYWtlIHRoZSBjb25uZWN0aW9uXG4gICAgaWYgKGlzQXVkaW9QYXJhbShkc3ROb2RlKSkge1xuICAgICAgICBzcmNOb2RlLmNvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNyY05vZGUuY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIsIGlucHV0TnVtYmVyKTtcbiAgICB9XG59XG4vKipcbiAqIERpc2Nvbm5lY3QgYSBub2RlIGZyb20gYWxsIG5vZGVzIG9yIG9wdGlvbmFsbHkgaW5jbHVkZSBhIGRlc3RpbmF0aW9uIG5vZGUgYW5kIGlucHV0L291dHB1dCBjaGFubmVscy5cbiAqIEBwYXJhbSBzcmNOb2RlIFRoZSBzb3VyY2Ugbm9kZVxuICogQHBhcmFtIGRzdE5vZGUgVGhlIGRlc3RpbmF0aW9uIG5vZGVcbiAqIEBwYXJhbSBvdXRwdXROdW1iZXIgVGhlIG91dHB1dCBjaGFubmVsIG9mIHRoZSBzcmNOb2RlXG4gKiBAcGFyYW0gaW5wdXROdW1iZXIgVGhlIGlucHV0IGNoYW5uZWwgb2YgdGhlIGRzdE5vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc2Nvbm5lY3Qoc3JjTm9kZSwgZHN0Tm9kZSwgb3V0cHV0TnVtYmVyID0gMCwgaW5wdXROdW1iZXIgPSAwKSB7XG4gICAgLy8gcmVzb2x2ZSB0aGUgZGVzdGluYXRpb24gbm9kZVxuICAgIGlmIChpc0RlZmluZWQoZHN0Tm9kZSkpIHtcbiAgICAgICAgd2hpbGUgKGRzdE5vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICBkc3ROb2RlID0gZHN0Tm9kZS5pbnB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyByZXNvbHZlIHRoZSBzcmMgbm9kZVxuICAgIHdoaWxlICghKGlzQXVkaW9Ob2RlKHNyY05vZGUpKSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHNyY05vZGUub3V0cHV0KSkge1xuICAgICAgICAgICAgc3JjTm9kZSA9IHNyY05vZGUub3V0cHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpc0F1ZGlvUGFyYW0oZHN0Tm9kZSkpIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlcik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKGRzdE5vZGUpKSB7XG4gICAgICAgIHNyY05vZGUuZGlzY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIsIGlucHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNyY05vZGUuZGlzY29ubmVjdCgpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb05vZGUuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIEEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgTmF0aXZlIFdlYiBBdWRpbyBHYWluTm9kZS5cbiAqIFRoZSBHYWluTm9kZSBpcyBhIGJhc2ljIGJ1aWxkaW5nIGJsb2NrIG9mIHRoZSBXZWIgQXVkaW9cbiAqIEFQSSBhbmQgaXMgdXNlZnVsIGZvciByb3V0aW5nIGF1ZGlvIGFuZCBhZGp1c3RpbmcgZ2FpbnMuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBnYWluTm9kZSA9IG5ldyBUb25lLkdhaW4oMCkudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDMwKS5jb25uZWN0KGdhaW5Ob2RlKS5zdGFydCgpO1xuICogXHRnYWluTm9kZS5nYWluLnJhbXBUbygxLCAwLjEpO1xuICogXHRnYWluTm9kZS5nYWluLnJhbXBUbygwLCAwLjQsIDAuMik7XG4gKiB9LCAwLjcsIDEpO1xuICovXG5leHBvcnQgY2xhc3MgR2FpbiBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhHYWluLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZ2FpblwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR2FpblwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHdyYXBwZWQgR2Fpbk5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nYWluTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIC8vIGlucHV0ID0gb3V0cHV0XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhaW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJnYWluXCIsIFwidW5pdHNcIl0pO1xuICAgICAgICB0aGlzLmdhaW4gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2dhaW5Ob2RlLmdhaW4sXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJnYWluXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIGdhaW46IDEsXG4gICAgICAgICAgICB1bml0czogXCJnYWluXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2Fpbi5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlLCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGZpcmUtYW5kLWZvcmdldCBub2Rlc1xuICovXG5leHBvcnQgY2xhc3MgT25lU2hvdFNvdXJjZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGFmdGVyIHRoZVxuICAgICAgICAgKiBzb3VyY2UgaXMgZG9uZSBwbGF5aW5nLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbmVuZGVkID0gbm9PcDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzdGFydCB0aW1lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzdG9wIHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaWQgb2YgdGhlIHRpbWVvdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVvdXQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwdWJsaWMgb3V0cHV0IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IGdhaW4gbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5vdXRwdXQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXQgdGhlIHBsYXliYWNrIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmdldFN0YXRlQXRUaW1lID0gZnVuY3Rpb24gKHRpbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXJ0VGltZSAhPT0gLTEgJiZcbiAgICAgICAgICAgICAgICBjb21wdXRlZFRpbWUgPj0gdGhpcy5fc3RhcnRUaW1lICYmXG4gICAgICAgICAgICAgICAgKHRoaXMuX3N0b3BUaW1lID09PSAtMSB8fCBjb21wdXRlZFRpbWUgPD0gdGhpcy5fc3RvcFRpbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3RhcnRlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3RvcHBlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICAgICAgdGhpcy5fY3VydmUgPSBvcHRpb25zLmN1cnZlO1xuICAgICAgICB0aGlzLm9uZW5kZWQgPSBvcHRpb25zLm9uZW5kZWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjdXJ2ZTogXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBvbmVuZGVkOiBub09wLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHNvdXJjZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRvIHN0YXJ0IHRoZSBzb3VyY2VcbiAgICAgKi9cbiAgICBfc3RhcnRHYWluKHRpbWUsIGdhaW4gPSAxKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgPT09IC0xLCBcIlNvdXJjZSBjYW5ub3QgYmUgc3RhcnRlZCBtb3JlIHRoYW4gb25jZVwiKTtcbiAgICAgICAgLy8gYXBwbHkgYSBmYWRlIGluIGVudmVsb3BlXG4gICAgICAgIGNvbnN0IGZhZGVJblRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLl9mYWRlSW4pO1xuICAgICAgICAvLyByZWNvcmQgdGhlIHN0YXJ0IHRpbWVcbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gdGltZSArIGZhZGVJblRpbWU7XG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IE1hdGgubWF4KHRoaXMuX3N0YXJ0VGltZSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIGVudmVsb3BlXG4gICAgICAgIGlmIChmYWRlSW5UaW1lID4gMCkge1xuICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoZ2FpbiwgdGltZSArIGZhZGVJblRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoZ2FpbiwgdGltZSwgZmFkZUluVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKGdhaW4sIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBzb3VyY2Ugbm9kZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRvIHN0b3AgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInN0b3BcIiwgdGltZSk7XG4gICAgICAgIHRoaXMuX3N0b3BHYWluKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRvIHN0b3AgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIF9zdG9wR2Fpbih0aW1lKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgIT09IC0xLCBcIidzdGFydCcgbXVzdCBiZSBjYWxsZWQgYmVmb3JlICdzdG9wJ1wiKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBwcmV2aW91cyBzdG9wXG4gICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuICAgICAgICAvLyB0aGUgZmFkZU91dCB0aW1lXG4gICAgICAgIGNvbnN0IGZhZGVPdXRUaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5fZmFkZU91dCk7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBzdG9wIGNhbGxiYWNrXG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gdGhpcy50b1NlY29uZHModGltZSkgKyBmYWRlT3V0VGltZTtcbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSBNYXRoLm1heCh0aGlzLl9zdG9wVGltZSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgaWYgKGZhZGVPdXRUaW1lID4gMCkge1xuICAgICAgICAgICAgLy8gc3RhcnQgdGhlIGZhZGUgb3V0IGN1cnZlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgICAgICBpZiAodGhpcy5fY3VydmUgPT09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmxpbmVhclJhbXBUbygwLCBmYWRlT3V0VGltZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnRhcmdldFJhbXBUbygwLCBmYWRlT3V0VGltZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBzdG9wIGFueSBvbmdvaW5nIHJhbXBzLCBhbmQgc2V0IHRoZSB2YWx1ZSB0byAwXG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXQgPSB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBhbGxvdyBhZGRpdGlvbmFsIHRpbWUgZm9yIHRoZSBleHBvbmVudGlhbCBjdXJ2ZSB0byBmdWxseSBkZWNheVxuICAgICAgICAgICAgY29uc3QgYWRkaXRpb25hbFRhaWwgPSB0aGlzLl9jdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiID8gZmFkZU91dFRpbWUgKiAyIDogMDtcbiAgICAgICAgICAgIHRoaXMuX3N0b3BTb3VyY2UodGhpcy5ub3coKSArIGFkZGl0aW9uYWxUYWlsKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQoKTtcbiAgICAgICAgfSwgdGhpcy5fc3RvcFRpbWUgLSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBvbmVuZGVkIGNhbGxiYWNrXG4gICAgICovXG4gICAgX29uZW5kZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLm9uZW5kZWQgIT09IG5vT3ApIHtcbiAgICAgICAgICAgIHRoaXMub25lbmRlZCh0aGlzKTtcbiAgICAgICAgICAgIC8vIG92ZXJ3cml0ZSBvbmVuZGVkIHRvIG1ha2Ugc3VyZSBpdCBvbmx5IGlzIGNhbGxlZCBvbmNlXG4gICAgICAgICAgICB0aGlzLm9uZW5kZWQgPSBub09wO1xuICAgICAgICAgICAgLy8gZGlzcG9zZSB3aGVuIGl0J3MgZW5kZWQgdG8gZnJlZSB1cCBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uIG9ubHkgaW4gdGhlIG9ubGluZSBjb250ZXh0XG4gICAgICAgICAgICBpZiAoIXRoaXMuY29udGV4dC5pc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkaXNwb3NlQ2FsbGJhY2sgPSAoKSA9PiB0aGlzLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cucmVxdWVzdElkbGVDYWxsYmFjayAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0SWRsZUNhbGxiYWNrKGRpc3Bvc2VDYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGRpc3Bvc2VDYWxsYmFjaywgMTAwMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhlIGN1cnJlbnQgdGltZVxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBhIHNjaGVkdWxlZCBzdG9wIGV2ZW50XG4gICAgICovXG4gICAgY2FuY2VsU3RvcCgpIHtcbiAgICAgICAgdGhpcy5sb2coXCJjYW5jZWxTdG9wXCIpO1xuICAgICAgICBhc3NlcnQodGhpcy5fc3RhcnRUaW1lICE9PSAtMSwgXCJTb3VyY2UgaXMgbm90IHN0YXJ0ZWRcIik7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgc3RvcCBlbnZlbG9wZVxuICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aGlzLl9zdGFydFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUpO1xuICAgICAgICB0aGlzLmNvbnRleHQuY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IC0xO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9uZVNob3RTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE9uZVNob3RTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL09uZVNob3RTb3VyY2VcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBmaXJlLWFuZC1mb3JnZXQgQ29uc3RhbnRTb3VyY2UuXG4gKiBBZGRzIHRoZSBhYmlsaXR5IHRvIHJlc2NoZWR1bGUgdGhlIHN0b3AgbWV0aG9kLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgVG9uZUNvbnN0YW50U291cmNlIGV4dGVuZHMgT25lU2hvdFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVDb25zdGFudFNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9mZnNldFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVDb25zdGFudFNvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNpZ25hbCBnZW5lcmF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHRoaXMuY29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUNvbnN0YW50U291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib2Zmc2V0XCJdKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9zb3VyY2UsIHRoaXMuX2dhaW5Ob2RlKTtcbiAgICAgICAgdGhpcy5vZmZzZXQgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3NvdXJjZS5vZmZzZXQsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9mZnNldCxcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIG9mZnNldDogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHNvdXJjZSBub2RlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdGFydChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3N0b3BTb3VyY2UodGltZSkge1xuICAgICAgICB0aGlzLl9zb3VyY2Uuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMub2Zmc2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUNvbnN0YW50U291cmNlLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUb25lQ29uc3RhbnRTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQ29uc3RhbnRTb3VyY2VcIjtcbi8qKlxuICogQSBzaWduYWwgaXMgYW4gYXVkaW8tcmF0ZSB2YWx1ZS4gVG9uZS5TaWduYWwgaXMgYSBjb3JlIGNvbXBvbmVudCBvZiB0aGUgbGlicmFyeS5cbiAqIFVubGlrZSBhIG51bWJlciwgU2lnbmFscyBjYW4gYmUgc2NoZWR1bGVkIHdpdGggc2FtcGxlLWxldmVsIGFjY3VyYWN5LiBUb25lLlNpZ25hbFxuICogaGFzIGFsbCBvZiB0aGUgbWV0aG9kcyBhdmFpbGFibGUgdG8gbmF0aXZlIFdlYiBBdWRpb1xuICogW0F1ZGlvUGFyYW1dKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWF1ZGlvcGFyYW0taW50ZXJmYWNlKVxuICogYXMgd2VsbCBhcyBhZGRpdGlvbmFsIGNvbnZlbmllbmNlcy4gUmVhZCBtb3JlIGFib3V0IHdvcmtpbmcgd2l0aCBzaWduYWxzXG4gKiBbaGVyZV0oaHR0cHM6Ly9naXRodWIuY29tL1RvbmVqcy9Ub25lLmpzL3dpa2kvU2lnbmFscykuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIGEgc2NoZWR1bGVhYmxlIHNpZ25hbCB3aGljaCBjYW4gYmUgY29ubmVjdGVkIHRvIGNvbnRyb2wgYW4gQXVkaW9QYXJhbSBvciBhbm90aGVyIFNpZ25hbFxuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKHtcbiAqIFx0dmFsdWU6IFwiQzRcIixcbiAqIFx0dW5pdHM6IFwiZnJlcXVlbmN5XCJcbiAqIH0pLmNvbm5lY3Qob3NjLmZyZXF1ZW5jeSk7XG4gKiAvLyB0aGUgc2NoZWR1bGVkIHJhbXAgY29udHJvbHMgdGhlIGNvbm5lY3RlZCBzaWduYWxcbiAqIHNpZ25hbC5yYW1wVG8oXCJDMlwiLCA0LCBcIiswLjVcIik7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWwgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNpZ25hbFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUgb3ZlcnJpZGRlbiBvbiBjb25uZWN0aW9uLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IHRydWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9jb25zdGFudFNvdXJjZSA9IG5ldyBUb25lQ29uc3RhbnRTb3VyY2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgb2Zmc2V0OiBvcHRpb25zLnZhbHVlLFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uuc3RhcnQoMCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9wYXJhbSA9IHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbnZlcnQ6IHRydWUsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIC8vIHN0YXJ0IGl0IG9ubHkgd2hlbiBjb25uZWN0ZWQgdG8gc29tZXRoaW5nXG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYXJhbS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEFCU1RSQUNUIFBBUkFNIElOVEVSRkFDRVxuICAgIC8vIGp1c3QgYSBwcm94eSBmb3IgdGhlIENvbnN0YW50U291cmNlTm9kZSdzIG9mZnNldCBBdWRpb1BhcmFtXG4gICAgLy8gYWxsIGRvY3MgYXJlIGdlbmVyYXRlZCBmcm9tIEFic3RyYWN0UGFyYW0udHNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgc2V0UmFtcFBvaW50KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0UmFtcFBvaW50KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUsIHJhbXBUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSwgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgcmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS52YWx1ZTtcbiAgICB9XG4gICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGdldCBjb252ZXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uY29udmVydDtcbiAgICB9XG4gICAgc2V0IGNvbnZlcnQoY29udmVydCkge1xuICAgICAgICB0aGlzLl9wYXJhbS5jb252ZXJ0ID0gY29udmVydDtcbiAgICB9XG4gICAgZ2V0IHVuaXRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udW5pdHM7XG4gICAgfVxuICAgIGdldCBvdmVycmlkZGVuKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ub3ZlcnJpZGRlbjtcbiAgICB9XG4gICAgc2V0IG92ZXJyaWRkZW4ob3ZlcnJpZGRlbikge1xuICAgICAgICB0aGlzLl9wYXJhbS5vdmVycmlkZGVuID0gb3ZlcnJpZGRlbjtcbiAgICB9XG4gICAgZ2V0IG1heFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWF4VmFsdWU7XG4gICAgfVxuICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1pblZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWUgW1tQYXJhbS5hcHBseV1dLlxuICAgICAqL1xuICAgIGFwcGx5KHBhcmFtKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmFwcGx5KHBhcmFtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBXaGVuIGNvbm5lY3RpbmcgZnJvbSBhIHNpZ25hbCwgaXQncyBuZWNlc3NhcnkgdG8gemVybyBvdXQgdGhlIG5vZGUgZGVzdGluYXRpb25cbiAqIG5vZGUgaWYgdGhhdCBub2RlIGlzIGFsc28gYSBzaWduYWwuIElmIHRoZSBkZXN0aW5hdGlvbiBpcyBub3QgMCwgdGhlbiB0aGUgdmFsdWVzXG4gKiB3aWxsIGJlIHN1bW1lZC4gVGhpcyBtZXRob2QgaW5zdXJlcyB0aGF0IHRoZSBvdXRwdXQgb2YgdGhlIGRlc3RpbmF0aW9uIHNpZ25hbCB3aWxsXG4gKiBiZSB0aGUgc2FtZSBhcyB0aGUgc291cmNlIHNpZ25hbCwgbWFraW5nIHRoZSBkZXN0aW5hdGlvbiBzaWduYWwgYSBwYXNzIHRocm91Z2ggbm9kZS5cbiAqIEBwYXJhbSBzaWduYWwgVGhlIG91dHB1dCBzaWduYWwgdG8gY29ubmVjdCBmcm9tXG4gKiBAcGFyYW0gZGVzdGluYXRpb24gdGhlIGRlc3RpbmF0aW9uIHRvIGNvbm5lY3QgdG9cbiAqIEBwYXJhbSBvdXRwdXROdW0gdGhlIG9wdGlvbmFsIG91dHB1dCBudW1iZXJcbiAqIEBwYXJhbSBpbnB1dE51bSB0aGUgaW5wdXQgbnVtYmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0U2lnbmFsKHNpZ25hbCwgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pIHtcbiAgICBpZiAoZGVzdGluYXRpb24gaW5zdGFuY2VvZiBQYXJhbSB8fCBpc0F1ZGlvUGFyYW0oZGVzdGluYXRpb24pIHx8XG4gICAgICAgIChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIFNpZ25hbCAmJiBkZXN0aW5hdGlvbi5vdmVycmlkZSkpIHtcbiAgICAgICAgLy8gY2FuY2VsIGNoYW5nZXNcbiAgICAgICAgZGVzdGluYXRpb24uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKDApO1xuICAgICAgICAvLyByZXNldCB0aGUgdmFsdWVcbiAgICAgICAgZGVzdGluYXRpb24uc2V0VmFsdWVBdFRpbWUoMCwgMCk7XG4gICAgICAgIC8vIG1hcmsgdGhlIHZhbHVlIGFzIG92ZXJyaWRkZW5cbiAgICAgICAgaWYgKGRlc3RpbmF0aW9uIGluc3RhbmNlb2YgU2lnbmFsKSB7XG4gICAgICAgICAgICBkZXN0aW5hdGlvbi5vdmVycmlkZGVuID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25uZWN0KHNpZ25hbCwgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2lnbmFsLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzVW5kZWYgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogQSBQYXJhbSBjbGFzcyBqdXN0IGZvciBjb21wdXRpbmcgdGlja3MuIFNpbWlsYXIgdG8gdGhlIFtbUGFyYW1dXSBjbGFzcyxcbiAqIGJ1dCBvZmZlcnMgY29udmVyc2lvbiB0byBCUE0gdmFsdWVzIGFzIHdlbGwgYXMgYWJpbGl0eSB0byBjb21wdXRlIHRpY2tcbiAqIGR1cmF0aW9uIGFuZCBlbGFwc2VkIHRpY2tzXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrUGFyYW0gZXh0ZW5kcyBQYXJhbSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tQYXJhbS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja1BhcmFtXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZWxpbmUgd2hpY2ggdHJhY2tzIGFsbCBvZiB0aGUgYXV0b21hdGlvbnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVGltZWxpbmUoSW5maW5pdHkpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGludGVybmFsIGhvbGRlciBmb3IgdGhlIG11bHRpcGxpZXIgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX211bHRpcGxpZXIgPSAxO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1BhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICAvLyBzZXQgdGhlIG11bHRpcGxpZXJcbiAgICAgICAgdGhpcy5fbXVsdGlwbGllciA9IG9wdGlvbnMubXVsdGlwbGllcjtcbiAgICAgICAgLy8gY2xlYXIgdGhlIHRpY2tzIGZyb20gdGhlIGJlZ2lubmluZ1xuICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKDApO1xuICAgICAgICAvLyBzZXQgYW4gaW5pdGlhbCBldmVudFxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpY2tzOiAwLFxuICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLl9mcm9tVHlwZShvcHRpb25zLnZhbHVlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oUGFyYW0uZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXVsdGlwbGllcjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgdGltZSwgY29uc3RhbnQpIHtcbiAgICAgICAgLy8gYXBwcm94aW1hdGUgaXQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHNcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludCh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgLy8gc3RhcnQgZnJvbSBwcmV2aW91c2x5IHNjaGVkdWxlZCB2YWx1ZVxuICAgICAgICBjb25zdCBwcmV2RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuICAgICAgICBjb25zdCBzZWdtZW50cyA9IE1hdGgucm91bmQoTWF0aC5tYXgoMSAvIGNvbnN0YW50LCAxKSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBjb25zdGFudCAqIGkgKyB0aW1lO1xuICAgICAgICAgICAgY29uc3QgcmFtcFZhbCA9IHRoaXMuX2V4cG9uZW50aWFsQXBwcm9hY2gocHJldkV2ZW50LnRpbWUsIHByZXZFdmVudC52YWx1ZSwgY29tcHV0ZWRWYWx1ZSwgY29uc3RhbnQsIHNlZ1RpbWUpO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUocmFtcFZhbCksIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgc3VwZXIuc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5wcmV2aW91c0V2ZW50KGV2ZW50KTtcbiAgICAgICAgY29uc3QgdGlja3NVbnRpbFRpbWUgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgZXZlbnQudGlja3MgPSBNYXRoLm1heCh0aWNrc1VudGlsVGltZSwgMCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgc3VwZXIubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5wcmV2aW91c0V2ZW50KGV2ZW50KTtcbiAgICAgICAgY29uc3QgdGlja3NVbnRpbFRpbWUgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgZXZlbnQudGlja3MgPSBNYXRoLm1heCh0aWNrc1VudGlsVGltZSwgMCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIC8vIGFwcm94aW1hdGUgaXQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHNcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFZhbCA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgLy8gc3RhcnQgZnJvbSBwcmV2aW91c2x5IHNjaGVkdWxlZCB2YWx1ZVxuICAgICAgICBjb25zdCBwcmV2RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuICAgICAgICAvLyBhcHByb3ggMTAgc2VnbWVudHMgcGVyIHNlY29uZFxuICAgICAgICBjb25zdCBzZWdtZW50cyA9IE1hdGgucm91bmQoTWF0aC5tYXgoKHRpbWUgLSBwcmV2RXZlbnQudGltZSkgKiAxMCwgMSkpO1xuICAgICAgICBjb25zdCBzZWdtZW50RHVyID0gKCh0aW1lIC0gcHJldkV2ZW50LnRpbWUpIC8gc2VnbWVudHMpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBzZWdtZW50czsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWdUaW1lID0gc2VnbWVudER1ciAqIGkgKyBwcmV2RXZlbnQudGltZTtcbiAgICAgICAgICAgIGNvbnN0IHJhbXBWYWwgPSB0aGlzLl9leHBvbmVudGlhbEludGVycG9sYXRlKHByZXZFdmVudC50aW1lLCBwcmV2RXZlbnQudmFsdWUsIHRpbWUsIGNvbXB1dGVkVmFsLCBzZWdUaW1lKTtcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHJhbXBWYWwpLCBzZWdUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGljayB2YWx1ZSBhdCB0aGUgdGltZS4gVGFrZXMgaW50byBhY2NvdW50XG4gICAgICogYW55IGF1dG9tYXRpb24gY3VydmVzIHNjaGVkdWxlZCBvbiB0aGUgc2lnbmFsLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgVGhlIHRpbWUgdG8gZ2V0IHRoZSB0aWNrIGNvdW50IGF0XG4gICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRpY2tzIHdoaWNoIGhhdmUgZWxhcHNlZCBhdCB0aGUgdGltZSBnaXZlbiBhbnkgYXV0b21hdGlvbnMuXG4gICAgICovXG4gICAgX2dldFRpY2tzVW50aWxFdmVudChldmVudCwgdGltZSkge1xuICAgICAgICBpZiAoZXZlbnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIGV2ZW50ID0ge1xuICAgICAgICAgICAgICAgIHRpY2tzOiAwLFxuICAgICAgICAgICAgICAgIHRpbWU6IDAsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1VuZGVmKGV2ZW50LnRpY2tzKSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5wcmV2aW91c0V2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIGV2ZW50LnRpY2tzID0gdGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KHByZXZpb3VzRXZlbnQsIGV2ZW50LnRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbDAgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGV2ZW50LnRpbWUpKTtcbiAgICAgICAgbGV0IHZhbDEgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpKTtcbiAgICAgICAgLy8gaWYgaXQncyByaWdodCBvbiB0aGUgbGluZSwgdGFrZSB0aGUgcHJldmlvdXMgdmFsdWVcbiAgICAgICAgY29uc3Qgb25UaGVMaW5lRXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KHRpbWUpO1xuICAgICAgICBpZiAob25UaGVMaW5lRXZlbnQgJiYgb25UaGVMaW5lRXZlbnQudGltZSA9PT0gdGltZSAmJiBvblRoZUxpbmVFdmVudC50eXBlID09PSBcInNldFZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgIHZhbDEgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUgLSB0aGlzLnNhbXBsZVRpbWUpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMC41ICogKHRpbWUgLSBldmVudC50aW1lKSAqICh2YWwwICsgdmFsMSkgKyBldmVudC50aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGljayB2YWx1ZSBhdCB0aGUgdGltZS4gVGFrZXMgaW50byBhY2NvdW50XG4gICAgICogYW55IGF1dG9tYXRpb24gY3VydmVzIHNjaGVkdWxlZCBvbiB0aGUgc2lnbmFsLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBnZXQgdGhlIHRpY2sgY291bnQgYXRcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3Mgd2hpY2ggaGF2ZSBlbGFwc2VkIGF0IHRoZSB0aW1lIGdpdmVuIGFueSBhdXRvbWF0aW9ucy5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIE1hdGgubWF4KHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChldmVudCwgY29tcHV0ZWRUaW1lKSwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZWxhcHNlZCB0aW1lIG9mIHRoZSBudW1iZXIgb2YgdGlja3MgZnJvbSB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSB0aWNrcyBUaGUgbnVtYmVyIG9mIHRpY2tzIHRvIGNhbGN1bGF0ZVxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBnZXQgdGhlIG5leHQgdGljayBmcm9tXG4gICAgICogQHJldHVybiBUaGUgZHVyYXRpb24gb2YgdGhlIG51bWJlciBvZiB0aWNrcyBmcm9tIHRoZSBnaXZlbiB0aW1lIGluIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaWNrID0gdGhpcy5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGltZU9mVGljayhjdXJyZW50VGljayArIHRpY2tzKSAtIGNvbXB1dGVkVGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2l2ZW4gYSB0aWNrLCByZXR1cm5zIHRoZSB0aW1lIHRoYXQgdGljayBvY2N1cnMgYXQuXG4gICAgICogQHJldHVybiBUaGUgdGltZSB0aGF0IHRoZSB0aWNrIG9jY3Vycy5cbiAgICAgKi9cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2spIHtcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldCh0aWNrLCBcInRpY2tzXCIpO1xuICAgICAgICBjb25zdCBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcih0aWNrLCBcInRpY2tzXCIpO1xuICAgICAgICBpZiAoYmVmb3JlICYmIGJlZm9yZS50aWNrcyA9PT0gdGljaykge1xuICAgICAgICAgICAgcmV0dXJuIGJlZm9yZS50aW1lO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJlZm9yZSAmJiBhZnRlciAmJlxuICAgICAgICAgICAgYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiICYmXG4gICAgICAgICAgICBiZWZvcmUudmFsdWUgIT09IGFmdGVyLnZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB2YWwwID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShiZWZvcmUudGltZSkpO1xuICAgICAgICAgICAgY29uc3QgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoYWZ0ZXIudGltZSkpO1xuICAgICAgICAgICAgY29uc3QgZGVsdGEgPSAodmFsMSAtIHZhbDApIC8gKGFmdGVyLnRpbWUgLSBiZWZvcmUudGltZSk7XG4gICAgICAgICAgICBjb25zdCBrID0gTWF0aC5zcXJ0KE1hdGgucG93KHZhbDAsIDIpIC0gMiAqIGRlbHRhICogKGJlZm9yZS50aWNrcyAtIHRpY2spKTtcbiAgICAgICAgICAgIGNvbnN0IHNvbDEgPSAoLXZhbDAgKyBrKSAvIGRlbHRhO1xuICAgICAgICAgICAgY29uc3Qgc29sMiA9ICgtdmFsMCAtIGspIC8gZGVsdGE7XG4gICAgICAgICAgICByZXR1cm4gKHNvbDEgPiAwID8gc29sMSA6IHNvbDIpICsgYmVmb3JlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlKSB7XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJlZm9yZS50aW1lICsgKHRpY2sgLSBiZWZvcmUudGlja3MpIC8gYmVmb3JlLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRpY2sgLyB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBzb21lIG51bWJlciBvZiB0aWNrcyB0aGVpciB0aGUgZHVyYXRpb24gaW4gc2Vjb25kcyBhY2NvdW50aW5nXG4gICAgICogZm9yIGFueSBhdXRvbWF0aW9uIGN1cnZlcyBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY29udmVydCB0byBzZWNvbmRzLlxuICAgICAqIEBwYXJhbSAgd2hlbiAgV2hlbiBhbG9uZyB0aGUgYXV0b21hdGlvbiB0aW1lbGluZSB0byBjb252ZXJ0IHRoZSB0aWNrcy5cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIG9mIHRoZSB0aWNrcy5cbiAgICAgKi9cbiAgICB0aWNrc1RvVGltZSh0aWNrcywgd2hlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHdoZW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW52ZXJzZSBvZiBbW3RpY2tzVG9UaW1lXV0uIENvbnZlcnQgYSBkdXJhdGlvbiBpblxuICAgICAqIHNlY29uZHMgdG8gdGhlIGNvcnJlc3BvbmRpbmcgbnVtYmVyIG9mIHRpY2tzIGFjY291bnRpbmcgZm9yIGFueVxuICAgICAqIGF1dG9tYXRpb24gY3VydmVzIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gVGhlIHRpbWUgaW50ZXJ2YWwgdG8gY29udmVydCB0byB0aWNrcy5cbiAgICAgKiBAcGFyYW0gIHdoZW4gV2hlbiBhbG9uZyB0aGUgYXV0b21hdGlvbiB0aW1lbGluZSB0byBjb252ZXJ0IHRoZSB0aWNrcy5cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBpbiB0aWNrcy5cbiAgICAgKi9cbiAgICB0aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbikge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgY29uc3Qgc3RhcnRUaWNrcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgZW5kVGlja3MgPSB0aGlzLmdldFRpY2tzQXRUaW1lKGNvbXB1dGVkVGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gZW5kVGlja3MgLSBzdGFydFRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGZyb20gdGhlIHR5cGUgd2hlbiB0aGUgdW5pdCB2YWx1ZSBpcyBCUE1cbiAgICAgKi9cbiAgICBfZnJvbVR5cGUodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLnVuaXRzID09PSBcImJwbVwiICYmIHRoaXMubXVsdGlwbGllcikge1xuICAgICAgICAgICAgcmV0dXJuIDEgLyAoNjAgLyB2YWwgLyB0aGlzLm11bHRpcGxpZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLl9mcm9tVHlwZSh2YWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNwZWNpYWwgY2FzZSBvZiB0eXBlIGNvbnZlcnNpb24gd2hlcmUgdGhlIHVuaXRzID09PSBcImJwbVwiXG4gICAgICovXG4gICAgX3RvVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiYnBtXCIgJiYgdGhpcy5tdWx0aXBsaWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gKHZhbCAvIHRoaXMubXVsdGlwbGllcikgKiA2MDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdXBlci5fdG9UeXBlKHZhbCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtdWx0aXBsaWVyIG9uIHRoZSBicG0gdmFsdWUuIFVzZWZ1bCBmb3Igc2V0dGluZyBhIFBQUSByZWxhdGl2ZSB0byB0aGUgYmFzZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IG11bHRpcGxpZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgbXVsdGlwbGllcihtKSB7XG4gICAgICAgIC8vIGdldCBhbmQgcmVzZXQgdGhlIGN1cnJlbnQgdmFsdWUgd2l0aCB0aGUgbmV3IG11bHRpcGxpZXJcbiAgICAgICAgLy8gbWlnaHQgYmUgbmVjZXNzYXJ5IHRvIGNsZWFyIGFsbCB0aGUgcHJldmlvdXMgdmFsdWVzXG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWwgPSB0aGlzLnZhbHVlO1xuICAgICAgICB0aGlzLl9tdWx0aXBsaWVyID0gbTtcbiAgICAgICAgdGhpcy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoMCk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUoY3VycmVudFZhbCwgMCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja1BhcmFtLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaWNrUGFyYW0gfSBmcm9tIFwiLi9UaWNrUGFyYW1cIjtcbi8qKlxuICogVGlja1NpZ25hbCBleHRlbmRzIFRvbmUuU2lnbmFsLCBidXQgYWRkcyB0aGUgY2FwYWJpbGl0eVxuICogdG8gY2FsY3VsYXRlIHRoZSBudW1iZXIgb2YgZWxhcHNlZCB0aWNrcy4gZXhwb25lbnRpYWwgYW5kIHRhcmdldCBjdXJ2ZXNcbiAqIGFyZSBhcHByb3hpbWF0ZWQgd2l0aCBtdWx0aXBsZSBsaW5lYXIgcmFtcHMuXG4gKlxuICogVGhhbmsgeW91IEJydW5vIERpYXMsIEguIFNvZmlhIFBpbnRvLCBhbmQgRGF2aWQgTS4gTWF0b3MsXG4gKiBmb3IgeW91ciBbV0FDIHBhcGVyXShodHRwczovL3NtYXJ0ZWNoLmdhdGVjaC5lZHUvYml0c3RyZWFtL2hhbmRsZS8xODUzLzU0NTg4L1dBQzIwMTYtNDkucGRmKVxuICogZGVzY3JpYmluZyBpbnRlZ3JhdGluZyB0aW1pbmcgZnVuY3Rpb25zIGZvciB0ZW1wbyBjYWxjdWxhdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrU2lnbmFsIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja1NpZ25hbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3BhcmFtID0gbmV3IFRpY2tQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBtdWx0aXBsaWVyOiBvcHRpb25zLm11bHRpcGxpZXIsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11bHRpcGxpZXI6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0aWNrc1RvVGltZSh0aWNrcywgd2hlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udGlja3NUb1RpbWUodGlja3MsIHdoZW4pO1xuICAgIH1cbiAgICB0aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbikge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udGltZVRvVGlja3MoZHVyYXRpb24sIHdoZW4pO1xuICAgIH1cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2spIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFRpbWVPZlRpY2sodGljayk7XG4gICAgfVxuICAgIGdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKTtcbiAgICB9XG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgbXVsdGlwbGllciBvbiB0aGUgYnBtIHZhbHVlLiBVc2VmdWwgZm9yIHNldHRpbmcgYSBQUFEgcmVsYXRpdmUgdG8gdGhlIGJhc2UgZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBtdWx0aXBsaWVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubXVsdGlwbGllcjtcbiAgICB9XG4gICAgc2V0IG11bHRpcGxpZXIobSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5tdWx0aXBsaWVyID0gbTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYXJhbS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tTaWduYWwuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVGlja1NpZ25hbCB9IGZyb20gXCIuL1RpY2tTaWduYWxcIjtcbmltcG9ydCB7IEVRIH0gZnJvbSBcIi4uL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBVc2VzIFtUaWNrU2lnbmFsXShUaWNrU2lnbmFsKSB0byB0cmFjayBlbGFwc2VkIHRpY2tzIHdpdGggY29tcGxleCBhdXRvbWF0aW9uIGN1cnZlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tTb3VyY2UgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja1NvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0YXRlIHRpbWVsaW5lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2Zmc2V0IHZhbHVlcyBvZiB0aGUgdGlja3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBUaWNrU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCBzdGF0ZVxuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgMCk7XG4gICAgICAgIC8vIGFkZCB0aGUgZmlyc3QgZXZlbnRcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSgwLCAwKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICB9LCBUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIgb3IgXCJwYXVzZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFN0YXRlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgY2xvY2sgYXQgdGhlIGdpdmVuIHRpbWUuIE9wdGlvbmFsbHkgcGFzcyBpbiBhbiBvZmZzZXRcbiAgICAgKiBvZiB3aGVyZSB0byBzdGFydCB0aGUgdGljayBjb3VudGVyIGZyb20uXG4gICAgICogQHBhcmFtICB0aW1lICAgIFRoZSB0aW1lIHRoZSBjbG9jayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSBudW1iZXIgb2YgdGlja3MgdG8gc3RhcnQgdGhlIHNvdXJjZSBhdFxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmIChpc0RlZmluZWQob2Zmc2V0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUob2Zmc2V0LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBjbG9jay4gU3RvcHBpbmcgdGhlIGNsb2NrIHJlc2V0cyB0aGUgdGljayBjb3VudGVyIHRvIDAuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXRlLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGV2ZW50ICYmIGV2ZW50LnRpbWUgPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGlja09mZnNldC5jYW5jZWwoZXZlbnQudGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSgwLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIGNsb2NrLiBQYXVzaW5nIGRvZXMgbm90IHJlc2V0IHRoZSB0aWNrIGNvdW50ZXIuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgcGF1c2UodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInBhdXNlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgc3RhcnQvc3RvcC9wYXVzZSBhbmQgc2V0VGlja0F0VGltZSBldmVudHMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdG8gY2xlYXIgdGhlIGV2ZW50cyBhZnRlclxuICAgICAqL1xuICAgIGNhbmNlbCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZWxhcHNlZCB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIHRpY2sgdmFsdWVcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3NcbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXRMYXN0U3RhdGUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIC8vIHRoaXMgZXZlbnQgYWxsb3dzIGZvckVhY2hCZXR3ZWVuIHRvIGl0ZXJhdGUgdW50aWwgdGhlIGN1cnJlbnQgdGltZVxuICAgICAgICBjb25zdCB0bXBFdmVudCA9IHsgc3RhdGU6IFwicGF1c2VkXCIsIHRpbWU6IGNvbXB1dGVkVGltZSB9O1xuICAgICAgICB0aGlzLl9zdGF0ZS5hZGQodG1wRXZlbnQpO1xuICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIHRoZSBwcmV2aW91cyBvZmZzZXQgZXZlbnRcbiAgICAgICAgbGV0IGxhc3RTdGF0ZSA9IHN0b3BFdmVudDtcbiAgICAgICAgbGV0IGVsYXBzZWRUaWNrcyA9IDA7XG4gICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCBzdG9wXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0b3BFdmVudC50aW1lLCBjb21wdXRlZFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUsIGUgPT4ge1xuICAgICAgICAgICAgbGV0IHBlcmlvZFN0YXJ0VGltZSA9IGxhc3RTdGF0ZS50aW1lO1xuICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gb2Zmc2V0IGV2ZW50IGluIHRoaXMgcGVyaW9kIHVzZSB0aGF0XG4gICAgICAgICAgICBjb25zdCBvZmZzZXRFdmVudCA9IHRoaXMuX3RpY2tPZmZzZXQuZ2V0KGUudGltZSk7XG4gICAgICAgICAgICBpZiAob2Zmc2V0RXZlbnQgJiYgb2Zmc2V0RXZlbnQudGltZSA+PSBsYXN0U3RhdGUudGltZSkge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRUaWNrcyA9IG9mZnNldEV2ZW50LnRpY2tzO1xuICAgICAgICAgICAgICAgIHBlcmlvZFN0YXJ0VGltZSA9IG9mZnNldEV2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFzdFN0YXRlLnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBlLnN0YXRlICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRUaWNrcyArPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShlLnRpbWUpIC0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUocGVyaW9kU3RhcnRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTdGF0ZSA9IGU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHRlbXBvcmFyeSBldmVudFxuICAgICAgICB0aGlzLl9zdGF0ZS5yZW1vdmUodG1wRXZlbnQpO1xuICAgICAgICAvLyByZXR1cm4gdGhlIHRpY2tzXG4gICAgICAgIHJldHVybiBlbGFwc2VkVGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBTdGFydHMgY291bnRpbmcgYXQgMFxuICAgICAqIGFuZCBpbmNyZW1lbnRzIGFmdGVyIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gUmV0dXJucyAtMSB3aGVuIHN0b3BwZWQuXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUaWNrc0F0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgc2V0IHRpY2tzKHQpIHtcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSh0LCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2luY2UgdGlja3M9MCB0aGF0IHRoZSBUaWNrU291cmNlIGhhcyBiZWVuIHJ1bm5pbmcuIEFjY291bnRzXG4gICAgICogZm9yIHRlbXBvIGN1cnZlc1xuICAgICAqL1xuICAgIGdldCBzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTZWNvbmRzQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgc2Vjb25kcyhzKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5mcmVxdWVuY3kudGltZVRvVGlja3Mocywgbm93KTtcbiAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZSh0aWNrcywgbm93KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXRMYXN0U3RhdGUoXCJzdG9wcGVkXCIsIHRpbWUpO1xuICAgICAgICAvLyB0aGlzIGV2ZW50IGFsbG93cyBmb3JFYWNoQmV0d2VlbiB0byBpdGVyYXRlIHVudGlsIHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgY29uc3QgdG1wRXZlbnQgPSB7IHN0YXRlOiBcInBhdXNlZFwiLCB0aW1lIH07XG4gICAgICAgIHRoaXMuX3N0YXRlLmFkZCh0bXBFdmVudCk7XG4gICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIHByZXZpb3VzIG9mZnNldCBldmVudFxuICAgICAgICBsZXQgbGFzdFN0YXRlID0gc3RvcEV2ZW50O1xuICAgICAgICBsZXQgZWxhcHNlZFNlY29uZHMgPSAwO1xuICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggYWxsIHRoZSBldmVudHMgc2luY2UgdGhlIGxhc3Qgc3RvcFxuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdG9wRXZlbnQudGltZSwgdGltZSArIHRoaXMuc2FtcGxlVGltZSwgZSA9PiB7XG4gICAgICAgICAgICBsZXQgcGVyaW9kU3RhcnRUaW1lID0gbGFzdFN0YXRlLnRpbWU7XG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBvZmZzZXQgZXZlbnQgaW4gdGhpcyBwZXJpb2QgdXNlIHRoYXRcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEV2ZW50ID0gdGhpcy5fdGlja09mZnNldC5nZXQoZS50aW1lKTtcbiAgICAgICAgICAgIGlmIChvZmZzZXRFdmVudCAmJiBvZmZzZXRFdmVudC50aW1lID49IGxhc3RTdGF0ZS50aW1lKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFNlY29uZHMgPSBvZmZzZXRFdmVudC5zZWNvbmRzO1xuICAgICAgICAgICAgICAgIHBlcmlvZFN0YXJ0VGltZSA9IG9mZnNldEV2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobGFzdFN0YXRlLnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBlLnN0YXRlICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRTZWNvbmRzICs9IGUudGltZSAtIHBlcmlvZFN0YXJ0VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTdGF0ZSA9IGU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHRlbXBvcmFyeSBldmVudFxuICAgICAgICB0aGlzLl9zdGF0ZS5yZW1vdmUodG1wRXZlbnQpO1xuICAgICAgICAvLyByZXR1cm4gdGhlIHRpY2tzXG4gICAgICAgIHJldHVybiBlbGFwc2VkU2Vjb25kcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIHRpY2sgdmFsdWUgdG8gc2V0XG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHNldCB0aGUgdGljayB2YWx1ZVxuICAgICAqL1xuICAgIHNldFRpY2tzQXRUaW1lKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5jYW5jZWwodGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuYWRkKHtcbiAgICAgICAgICAgIHNlY29uZHM6IHRoaXMuZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSksXG4gICAgICAgICAgICB0aWNrcyxcbiAgICAgICAgICAgIHRpbWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgZ2V0U3RhdGVBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBnaXZlbiB0aWNrLiBUaGUgc2Vjb25kIGFyZ3VtZW50XG4gICAgICogaXMgd2hlbiB0byB0ZXN0IGJlZm9yZS4gU2luY2UgdGlja3MgY2FuIGJlIHNldCAod2l0aCBzZXRUaWNrc0F0VGltZSlcbiAgICAgKiB0aGVyZSBtYXkgYmUgbXVsdGlwbGUgdGltZXMgZm9yIGEgZ2l2ZW4gdGljayB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gIHRpY2sgVGhlIHRpY2sgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgYmVmb3JlIFdoZW4gdG8gbWVhc3VyZSB0aGUgdGljayB2YWx1ZSBmcm9tLlxuICAgICAqIEByZXR1cm4gVGhlIHRpbWUgb2YgdGhlIHRpY2tcbiAgICAgKi9cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSA9IHRoaXMubm93KCkpIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5fdGlja09mZnNldC5nZXQoYmVmb3JlKTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoYmVmb3JlKTtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gTWF0aC5tYXgob2Zmc2V0LnRpbWUsIGV2ZW50LnRpbWUpO1xuICAgICAgICBjb25zdCBhYnNvbHV0ZVRpY2tzID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUoc3RhcnRUaW1lKSArIHRpY2sgLSBvZmZzZXQudGlja3M7XG4gICAgICAgIHJldHVybiB0aGlzLmZyZXF1ZW5jeS5nZXRUaW1lT2ZUaWNrKGFic29sdXRlVGlja3MpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrIGV2ZW50IGF0IGFsbCBzY2hlZHVsZWQgdGlja3MgYmV0d2VlbiB0aGVcbiAgICAgKiBzdGFydCB0aW1lIGFuZCB0aGUgZW5kIHRpbWVcbiAgICAgKiBAcGFyYW0gIHN0YXJ0VGltZSAgVGhlIGJlZ2lubmluZyBvZiB0aGUgc2VhcmNoIHJhbmdlXG4gICAgICogQHBhcmFtICBlbmRUaW1lICAgIFRoZSBlbmQgb2YgdGhlIHNlYXJjaCByYW5nZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZWFjaCB0aWNrXG4gICAgICovXG4gICAgZm9yRWFjaFRpY2tCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gb25seSBpdGVyYXRlIHRocm91Z2ggdGhlIHNlY3Rpb25zIHdoZXJlIGl0IGlzIFwic3RhcnRlZFwiXG4gICAgICAgIGxldCBsYXN0U3RhdGVFdmVudCA9IHRoaXMuX3N0YXRlLmdldChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGVFdmVudCAmJiBsYXN0U3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiYgZXZlbnQuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JFYWNoVGlja0JldHdlZW4oTWF0aC5tYXgobGFzdFN0YXRlRXZlbnQudGltZSwgc3RhcnRUaW1lKSwgZXZlbnQudGltZSAtIHRoaXMuc2FtcGxlVGltZSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlRXZlbnQgPSBldmVudDtcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBlcnJvciA9IG51bGw7XG4gICAgICAgIGlmIChsYXN0U3RhdGVFdmVudCAmJiBsYXN0U3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IG1heFN0YXJ0VGltZSA9IE1hdGgubWF4KGxhc3RTdGF0ZUV2ZW50LnRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAvLyBmaWd1cmUgb3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGZyZXF1ZW5jeSB0aWNrcyBhbmQgdGhlXG4gICAgICAgICAgICBjb25zdCBzdGFydFRpY2tzID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUobWF4U3RhcnRUaW1lKTtcbiAgICAgICAgICAgIGNvbnN0IHRpY2tzQXRTdGFydCA9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKGxhc3RTdGF0ZUV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgY29uc3QgZGlmZiA9IHN0YXJ0VGlja3MgLSB0aWNrc0F0U3RhcnQ7XG4gICAgICAgICAgICBsZXQgb2Zmc2V0ID0gTWF0aC5jZWlsKGRpZmYpIC0gZGlmZjtcbiAgICAgICAgICAgIC8vIGd1YXJkIGFnYWluc3QgZmxvYXRpbmcgcG9pbnQgaXNzdWVzXG4gICAgICAgICAgICBvZmZzZXQgPSBFUShvZmZzZXQsIDEpID8gMCA6IG9mZnNldDtcbiAgICAgICAgICAgIGxldCBuZXh0VGlja1RpbWUgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaW1lT2ZUaWNrKHN0YXJ0VGlja3MgKyBvZmZzZXQpO1xuICAgICAgICAgICAgd2hpbGUgKG5leHRUaWNrVGltZSA8IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhuZXh0VGlja1RpbWUsIE1hdGgucm91bmQodGhpcy5nZXRUaWNrc0F0VGltZShuZXh0VGlja1RpbWUpKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yID0gZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5leHRUaWNrVGltZSArPSB0aGlzLmZyZXF1ZW5jeS5nZXREdXJhdGlvbk9mVGlja3MoMSwgbmV4dFRpY2tUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrU291cmNlLmpzLm1hcCIsImltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi91dGlsL0VtaXR0ZXJcIjtcbmltcG9ydCB7IG5vT3AsIHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGlja1NvdXJjZSB9IGZyb20gXCIuL1RpY2tTb3VyY2VcIjtcbmltcG9ydCB7IGFzc2VydENvbnRleHRSdW5uaW5nIH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQSBzYW1wbGUgYWNjdXJhdGUgY2xvY2sgd2hpY2ggcHJvdmlkZXMgYSBjYWxsYmFjayBhdCB0aGUgZ2l2ZW4gcmF0ZS5cbiAqIFdoaWxlIHRoZSBjYWxsYmFjayBpcyBub3Qgc2FtcGxlLWFjY3VyYXRlIChpdCBpcyBzdGlsbCBzdXNjZXB0aWJsZSB0b1xuICogbG9vc2UgSlMgdGltaW5nKSwgdGhlIHRpbWUgcGFzc2VkIGluIGFzIHRoZSBhcmd1bWVudCB0byB0aGUgY2FsbGJhY2tcbiAqIGlzIHByZWNpc2UuIEZvciBtb3N0IGFwcGxpY2F0aW9ucywgaXQgaXMgYmV0dGVyIHRvIHVzZSBUb25lLlRyYW5zcG9ydFxuICogaW5zdGVhZCBvZiB0aGUgQ2xvY2sgYnkgaXRzZWxmIHNpbmNlIHlvdSBjYW4gc3luY2hyb25pemUgbXVsdGlwbGUgY2FsbGJhY2tzLlxuICogQGV4YW1wbGVcbiAqIC8vIHRoZSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWQgYXBwcm94aW1hdGVseSBvbmNlIGEgc2Vjb25kXG4gKiAvLyBhbmQgd2lsbCBwcmludCB0aGUgdGltZSBleGFjdGx5IG9uY2UgYSBzZWNvbmQgYXBhcnQuXG4gKiBjb25zdCBjbG9jayA9IG5ldyBUb25lLkNsb2NrKHRpbWUgPT4ge1xuICogXHRjb25zb2xlLmxvZyh0aW1lKTtcbiAqIH0sIDEpO1xuICogY2xvY2suc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG9jayBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENsb2NrLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDbG9ja1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGludm9rZSBhdCB0aGUgc2NoZWR1bGVkIHRpY2suXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gbm9PcDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsYXN0IHRpbWUgdGhlIGxvb3AgY2FsbGJhY2sgd2FzIGludm9rZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgcGxheWJhY2sgc3RhdGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udGV4dCBib3VuZCByZWZlcmVuY2UgdG8gdGhlIF9sb29wIG1ldGhvZFxuICAgICAgICAgKiBUaGlzIGlzIG5lY2Vzc2FyeSB0byByZW1vdmUgdGhlIGV2ZW50IGluIHRoZSBlbmQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ib3VuZExvb3AgPSB0aGlzLl9sb29wLmJpbmQodGhpcyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDbG9jay5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UgPSBuZXcgVGlja1NvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sYXN0VXBkYXRlID0gMDtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl90aWNrU291cmNlLmZyZXF1ZW5jeTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIC8vIGFkZCBhbiBpbml0aWFsIHN0YXRlXG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCAwKTtcbiAgICAgICAgLy8gYmluZCBhIGNhbGxiYWNrIHRvIHRoZSB3b3JrZXIgdGhyZWFkXG4gICAgICAgIHRoaXMuY29udGV4dC5vbihcInRpY2tcIiwgdGhpcy5fYm91bmRMb29wKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgY2xvY2sgYXQgdGhlIGdpdmVuIHRpbWUuIE9wdGlvbmFsbHkgcGFzcyBpbiBhbiBvZmZzZXRcbiAgICAgKiBvZiB3aGVyZSB0byBzdGFydCB0aGUgdGljayBjb3VudGVyIGZyb20uXG4gICAgICogQHBhcmFtICB0aW1lICAgIFRoZSB0aW1lIHRoZSBjbG9jayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gb2Zmc2V0ICBXaGVyZSB0aGUgdGljayBjb3VudGVyIHN0YXJ0cyBjb3VudGluZyBmcm9tLlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGNvbnRleHQgaXMgcnVubmluZ1xuICAgICAgICBhc3NlcnRDb250ZXh0UnVubmluZyh0aGlzLmNvbnRleHQpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbG9vcFxuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zdGFydChjb21wdXRlZFRpbWUsIG9mZnNldCk7XG4gICAgICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgY2xvY2suIFN0b3BwaW5nIHRoZSBjbG9jayByZXNldHMgdGhlIHRpY2sgY291bnRlciB0byAwLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIGNsb2NrIHNob3VsZCBzdG9wLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2xvY2sgPSBuZXcgVG9uZS5DbG9jayh0aW1lID0+IHtcbiAgICAgKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICAgICAqIH0sIDEpO1xuICAgICAqIGNsb2NrLnN0YXJ0KCk7XG4gICAgICogLy8gc3RvcCB0aGUgY2xvY2sgYWZ0ZXIgMTAgc2Vjb25kc1xuICAgICAqIGNsb2NrLnN0b3AoXCIrMTBcIik7XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0b3BcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKGNvbXB1dGVkVGltZSA8IHRoaXMuX2xhc3RVcGRhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIGNsb2NrLiBQYXVzaW5nIGRvZXMgbm90IHJlc2V0IHRoZSB0aWNrIGNvdW50ZXIuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgcGF1c2UodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInBhdXNlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5wYXVzZShjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGNvbXB1dGVkVGltZSA8IHRoaXMuX2xhc3RVcGRhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJwYXVzZVwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gU3RhcnRzIGNvdW50aW5nIGF0IDBcbiAgICAgKiBhbmQgaW5jcmVtZW50cyBhZnRlciB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMuZ2V0VGlja3NBdFRpbWUodGhpcy5ub3coKSkpO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnRpY2tzID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2luY2UgdGlja3M9MCB0aGF0IHRoZSBDbG9jayBoYXMgYmVlbiBydW5uaW5nLiBBY2NvdW50cyBmb3IgdGVtcG8gY3VydmVzXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLnNlY29uZHM7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zZWNvbmRzID0gcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0U2Vjb25kc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIHRpY2sgdmFsdWUgdG8gc2V0XG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHNldCB0aGUgdGljayB2YWx1ZVxuICAgICAqL1xuICAgIHNldFRpY2tzQXRUaW1lKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBnaXZlbiB0aWNrLiBUaGUgc2Vjb25kIGFyZ3VtZW50XG4gICAgICogaXMgd2hlbiB0byB0ZXN0IGJlZm9yZS4gU2luY2UgdGlja3MgY2FuIGJlIHNldCAod2l0aCBzZXRUaWNrc0F0VGltZSlcbiAgICAgKiB0aGVyZSBtYXkgYmUgbXVsdGlwbGUgdGltZXMgZm9yIGEgZ2l2ZW4gdGljayB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gIHRpY2sgVGhlIHRpY2sgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgYmVmb3JlIFdoZW4gdG8gbWVhc3VyZSB0aGUgdGljayB2YWx1ZSBmcm9tLlxuICAgICAqIEByZXR1cm4gVGhlIHRpbWUgb2YgdGhlIHRpY2tcbiAgICAgKi9cbiAgICBnZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSA9IHRoaXMubm93KCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGltZU9mVGljayh0aWNrLCBiZWZvcmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIHRpY2sgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBuZXh0IHRpY2tcbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgdGljayBudW1iZXIuXG4gICAgICovXG4gICAgbmV4dFRpY2tUaW1lKG9mZnNldCwgd2hlbikge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcbiAgICAgICAgY29uc3QgY3VycmVudFRpY2sgPSB0aGlzLmdldFRpY2tzQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFRpbWVPZlRpY2soY3VycmVudFRpY2sgKyBvZmZzZXQsIGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzY2hlZHVsaW5nIGxvb3AuXG4gICAgICovXG4gICAgX2xvb3AoKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IHRoaXMuX2xhc3RVcGRhdGU7XG4gICAgICAgIGNvbnN0IGVuZFRpbWUgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl9sYXN0VXBkYXRlID0gZW5kVGltZTtcbiAgICAgICAgdGhpcy5sb2coXCJsb29wXCIsIHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgICAgIGlmIChzdGFydFRpbWUgIT09IGVuZFRpbWUpIHtcbiAgICAgICAgICAgIC8vIHRoZSBzdGF0ZSBjaGFuZ2UgZXZlbnRzXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGUgPT4ge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAoZS5zdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3RhcnRlZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5fdGlja1NvdXJjZS5nZXRUaWNrc0F0VGltZShlLnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgZS50aW1lLCBvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzdG9wcGVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZS50aW1lICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCBlLnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJwYXVzZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInBhdXNlXCIsIGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHRoZSB0aWNrIGNhbGxiYWNrc1xuICAgICAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5mb3JFYWNoVGlja0JldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCAodGltZSwgdGlja3MpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRpY2tzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNjaGVkdWxlZCBzdGF0ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqIEByZXR1cm4gIFRoZSBuYW1lIG9mIHRoZSBzdGF0ZSBpbnB1dCBpbiBzZXRTdGF0ZUF0VGltZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGNsb2NrID0gbmV3IFRvbmUuQ2xvY2soKTtcbiAgICAgKiBjbG9jay5zdGFydChcIiswLjFcIik7XG4gICAgICogY2xvY2suZ2V0U3RhdGVBdFRpbWUoXCIrMC4xXCIpOyAvLyByZXR1cm5zIFwic3RhcnRlZFwiXG4gICAgICovXG4gICAgZ2V0U3RhdGVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbnRleHQub2ZmKFwidGlja1wiLCB0aGlzLl9ib3VuZExvb3ApO1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5FbWl0dGVyLm1peGluKENsb2NrKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNsb2NrLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCBXZWIgQXVkaW8ncyBuYXRpdmUgW0RlbGF5Tm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtZGVsYXlub2RlLWludGVyZmFjZSkuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBkZWxheSA9IG5ldyBUb25lLkRlbGF5KDAuMSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBjb25uZWN0IHRoZSBzaWduYWwgdG8gYm90aCB0aGUgZGVsYXkgYW5kIHRoZSBkZXN0aW5hdGlvblxuICogXHRjb25zdCBwdWxzZSA9IG5ldyBUb25lLlB1bHNlT3NjaWxsYXRvcigpLmNvbm5lY3QoZGVsYXkpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Ly8gc3RhcnQgYW5kIHN0b3AgdGhlIHB1bHNlXG4gKiBcdHB1bHNlLnN0YXJ0KDApLnN0b3AoMC4wMSk7XG4gKiB9LCAwLjUsIDEpO1xuICovXG5leHBvcnQgY2xhc3MgRGVsYXkgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJtYXhEZWxheVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRlbGF5XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcIm1heERlbGF5XCJdKTtcbiAgICAgICAgY29uc3QgbWF4RGVsYXlJblNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLm1heERlbGF5KTtcbiAgICAgICAgdGhpcy5fbWF4RGVsYXkgPSBNYXRoLm1heChtYXhEZWxheUluU2Vjb25kcywgdGhpcy50b1NlY29uZHMob3B0aW9ucy5kZWxheVRpbWUpKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZURlbGF5KG1heERlbGF5SW5TZWNvbmRzKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2RlbGF5Tm9kZS5kZWxheVRpbWUsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBtaW5WYWx1ZTogMCxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZWxheVRpbWVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAsXG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIGRlbGF5IHRpbWUuIFRoaXMgY2Fubm90IGJlIGNoYW5nZWQgYWZ0ZXJcbiAgICAgKiB0aGUgdmFsdWUgaXMgcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLlxuICAgICAqL1xuICAgIGdldCBtYXhEZWxheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heERlbGF5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVsYXkuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBnZXRDb250ZXh0LCBzZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4vVG9uZUF1ZGlvQnVmZmVyXCI7XG4vKipcbiAqIEdlbmVyYXRlIGEgYnVmZmVyIGJ5IHJlbmRlcmluZyBhbGwgb2YgdGhlIFRvbmUuanMgY29kZSB3aXRoaW4gdGhlIGNhbGxiYWNrIHVzaW5nIHRoZSBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICogVGhlIE9mZmxpbmVBdWRpb0NvbnRleHQgaXMgY2FwYWJsZSBvZiByZW5kZXJpbmcgbXVjaCBmYXN0ZXIgdGhhbiByZWFsIHRpbWUgaW4gbWFueSBjYXNlcy5cbiAqIFRoZSBjYWxsYmFjayBmdW5jdGlvbiBhbHNvIHBhc3NlcyBpbiBhbiBvZmZsaW5lIGluc3RhbmNlIG9mIFtbQ29udGV4dF1dIHdoaWNoIGNhbiBiZSB1c2VkXG4gKiB0byBzY2hlZHVsZSBldmVudHMgYWxvbmcgdGhlIFRyYW5zcG9ydC5cbiAqIEBwYXJhbSAgY2FsbGJhY2sgIEFsbCBUb25lLmpzIG5vZGVzIHdoaWNoIGFyZSBjcmVhdGVkIGFuZCBzY2hlZHVsZWQgd2l0aGluIHRoaXMgY2FsbGJhY2sgYXJlIHJlY29yZGVkIGludG8gdGhlIG91dHB1dCBCdWZmZXIuXG4gKiBAcGFyYW0gIGR1cmF0aW9uICAgICB0aGUgYW1vdW50IG9mIHRpbWUgdG8gcmVjb3JkIGZvci5cbiAqIEByZXR1cm4gIFRoZSBwcm9taXNlIHdoaWNoIGlzIGludm9rZWQgd2l0aCB0aGUgVG9uZUF1ZGlvQnVmZmVyIG9mIHRoZSByZWNvcmRlZCBvdXRwdXQuXG4gKiBAZXhhbXBsZVxuICogLy8gcmVuZGVyIDIgc2Vjb25kcyBvZiB0aGUgb3NjaWxsYXRvclxuICogVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Ly8gb25seSBub2RlcyBjcmVhdGVkIGluIHRoaXMgY2FsbGJhY2sgd2lsbCBiZSByZWNvcmRlZFxuICogXHRjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgwKTtcbiAqIH0sIDIpLnRoZW4oKGJ1ZmZlcikgPT4ge1xuICogXHQvLyBkbyBzb21ldGhpbmcgd2l0aCB0aGUgb3V0cHV0IGJ1ZmZlclxuICogXHRjb25zb2xlLmxvZyhidWZmZXIpO1xuICogfSk7XG4gKiBAZXhhbXBsZVxuICogLy8gY2FuIGFsc28gc2NoZWR1bGUgZXZlbnRzIGFsb25nIHRoZSBUcmFuc3BvcnRcbiAqIC8vIHVzaW5nIHRoZSBwYXNzZWQgaW4gT2ZmbGluZSBUcmFuc3BvcnRcbiAqIFRvbmUuT2ZmbGluZSgoeyB0cmFuc3BvcnQgfSkgPT4ge1xuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHR0cmFuc3BvcnQuc2NoZWR1bGUodGltZSA9PiB7XG4gKiBcdFx0b3NjLnN0YXJ0KHRpbWUpLnN0b3AodGltZSArIDAuMSk7XG4gKiBcdH0sIDEpO1xuICogXHQvLyBtYWtlIHN1cmUgdG8gc3RhcnQgdGhlIHRyYW5zcG9ydFxuICogXHR0cmFuc3BvcnQuc3RhcnQoMC4yKTtcbiAqIH0sIDQpLnRoZW4oKGJ1ZmZlcikgPT4ge1xuICogXHQvLyBkbyBzb21ldGhpbmcgd2l0aCB0aGUgb3V0cHV0IGJ1ZmZlclxuICogXHRjb25zb2xlLmxvZyhidWZmZXIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gT2ZmbGluZShjYWxsYmFjaywgZHVyYXRpb24sIGNoYW5uZWxzID0gMiwgc2FtcGxlUmF0ZSA9IGdldENvbnRleHQoKS5zYW1wbGVSYXRlKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgLy8gc2V0IHRoZSBPZmZsaW5lQXVkaW9Db250ZXh0IGJhc2VkIG9uIHRoZSBjdXJyZW50IGNvbnRleHRcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxDb250ZXh0ID0gZ2V0Q29udGV4dCgpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KGNoYW5uZWxzLCBkdXJhdGlvbiwgc2FtcGxlUmF0ZSk7XG4gICAgICAgIHNldENvbnRleHQoY29udGV4dCk7XG4gICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2svc2NoZWR1bGluZ1xuICAgICAgICB5aWVsZCBjYWxsYmFjayhjb250ZXh0KTtcbiAgICAgICAgLy8gdGhlbiByZW5kZXIgdGhlIGF1ZGlvXG4gICAgICAgIGNvbnN0IGJ1ZmZlclByb21pc2UgPSBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAvLyByZXR1cm4gdGhlIG9yaWdpbmFsIEF1ZGlvQ29udGV4dFxuICAgICAgICBzZXRDb250ZXh0KG9yaWdpbmFsQ29udGV4dCk7XG4gICAgICAgIC8vIGF3YWl0IHRoZSByZW5kZXJpbmdcbiAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgYnVmZmVyUHJvbWlzZTtcbiAgICAgICAgLy8gcmV0dXJuIHRoZSBhdWRpb1xuICAgICAgICByZXR1cm4gbmV3IFRvbmVBdWRpb0J1ZmZlcihidWZmZXIpO1xuICAgIH0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T2ZmbGluZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEEgZGF0YSBzdHJ1Y3R1cmUgZm9yIGhvbGRpbmcgbXVsdGlwbGUgYnVmZmVycyBpbiBhIE1hcC1saWtlIGRhdGFzdHJ1Y3R1cmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBpYW5vU2FtcGxlcyA9IG5ldyBUb25lLlRvbmVBdWRpb0J1ZmZlcnMoe1xuICogXHRBMTogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vQTEubXAzXCIsXG4gKiBcdEEyOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMi5tcDNcIixcbiAqIH0sICgpID0+IHtcbiAqIFx0Y29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBwbGF5IG9uZSBvZiB0aGUgc2FtcGxlcyB3aGVuIHRoZXkgYWxsIGxvYWRcbiAqIFx0cGxheWVyLmJ1ZmZlciA9IHBpYW5vU2FtcGxlcy5nZXQoXCJBMlwiKTtcbiAqIFx0cGxheWVyLnN0YXJ0KCk7XG4gKiB9KTtcbiAqIEBleGFtcGxlXG4gKiAvLyBUbyBwYXNzIGluIGFkZGl0aW9uYWwgcGFyYW1ldGVycyBpbiB0aGUgc2Vjb25kIHBhcmFtZXRlclxuICogY29uc3QgYnVmZmVycyA9IG5ldyBUb25lLlRvbmVBdWRpb0J1ZmZlcnMoe1xuICogXHQgdXJsczoge1xuICogXHRcdCBBMTogXCJBMS5tcDNcIixcbiAqIFx0XHQgQTI6IFwiQTIubXAzXCIsXG4gKiBcdCB9LFxuICogXHQgb25sb2FkOiAoKSA9PiBjb25zb2xlLmxvZyhcImxvYWRlZFwiKSxcbiAqIFx0IGJhc2VVcmw6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL1wiXG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9CdWZmZXJzIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvQnVmZmVyc1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBidWZmZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgbnVtYmVyIG9mIGxvYWRlZCBidWZmZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb2FkaW5nQ291bnQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUF1ZGlvQnVmZmVycy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIik7XG4gICAgICAgIHRoaXMuYmFzZVVybCA9IG9wdGlvbnMuYmFzZVVybDtcbiAgICAgICAgLy8gYWRkIGVhY2ggb25lXG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMudXJscykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudCsrO1xuICAgICAgICAgICAgY29uc3QgdXJsID0gb3B0aW9ucy51cmxzW25hbWVdO1xuICAgICAgICAgICAgdGhpcy5hZGQobmFtZSwgdXJsLCB0aGlzLl9idWZmZXJMb2FkZWQuYmluZCh0aGlzLCBvcHRpb25zLm9ubG9hZCksIG9wdGlvbnMub25lcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBiYXNlVXJsOiBcIlwiLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIHVybHM6IHt9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcnVlIGlmIHRoZSBidWZmZXJzIG9iamVjdCBoYXMgYSBidWZmZXIgYnkgdGhhdCBuYW1lLlxuICAgICAqIEBwYXJhbSAgbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmhhcyhuYW1lLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYSBidWZmZXIgYnkgbmFtZS4gSWYgYW4gYXJyYXkgd2FzIGxvYWRlZCxcbiAgICAgKiB0aGVuIHVzZSB0aGUgYXJyYXkgaW5kZXguXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUga2V5IG9yIGluZGV4IG9mIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgZ2V0KG5hbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuaGFzKG5hbWUpLCBgVG9uZUF1ZGlvQnVmZmVycyBoYXMgbm8gYnVmZmVyIG5hbWVkOiAke25hbWV9YCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmdldChuYW1lLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIGJ1ZmZlciB3YXMgbG9hZGVkLiBkZWNyZW1lbnQgdGhlIGNvdW50ZXIuXG4gICAgICovXG4gICAgX2J1ZmZlckxvYWRlZChjYWxsYmFjaykge1xuICAgICAgICB0aGlzLl9sb2FkaW5nQ291bnQtLTtcbiAgICAgICAgaWYgKHRoaXMuX2xvYWRpbmdDb3VudCA9PT0gMCAmJiBjYWxsYmFjaykge1xuICAgICAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMuX2J1ZmZlcnMpLmV2ZXJ5KChbXywgYnVmZmVyXSkgPT4gYnVmZmVyLmxvYWRlZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIGJ1ZmZlciBieSBuYW1lIGFuZCB1cmwgdG8gdGhlIEJ1ZmZlcnNcbiAgICAgKiBAcGFyYW0gIG5hbWUgICAgICBBIHVuaXF1ZSBuYW1lIHRvIGdpdmUgdGhlIGJ1ZmZlclxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZXIsIG9yIGEgYnVmZmVyIHdoaWNoIHdpbGwgYmUgYWRkZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIHVybCBpcyBsb2FkZWQuXG4gICAgICogQHBhcmFtICBvbmVycm9yICBJbnZva2VkIGlmIHRoZSBidWZmZXIgY2FuJ3QgYmUgbG9hZGVkXG4gICAgICovXG4gICAgYWRkKG5hbWUsIHVybCwgY2FsbGJhY2sgPSBub09wLCBvbmVycm9yID0gbm9PcCkge1xuICAgICAgICBpZiAoaXNTdHJpbmcodXJsKSkge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5zZXQobmFtZS50b1N0cmluZygpLCBuZXcgVG9uZUF1ZGlvQnVmZmVyKHRoaXMuYmFzZVVybCArIHVybCwgY2FsbGJhY2ssIG9uZXJyb3IpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuc2V0KG5hbWUudG9TdHJpbmcoKSwgbmV3IFRvbmVBdWRpb0J1ZmZlcih1cmwsIGNhbGxiYWNrLCBvbmVycm9yKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5mb3JFYWNoKGJ1ZmZlciA9PiBidWZmZXIuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9CdWZmZXJzLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBmdG9tLCBtdG9mIH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4vRnJlcXVlbmN5XCI7XG4vKipcbiAqIE1pZGkgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgVGltZSB2YWx1ZXMuXG4gKiBNaWRpIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIG9yIHdpdGhvdXQgdGhlIGBuZXdgIGtleXdvcmQuIE1pZGkgY2FuIGJlIHBhc3NlZFxuICogaW50byB0aGUgcGFyYW1ldGVyIG9mIGFueSBtZXRob2Qgd2hpY2ggdGFrZXMgdGltZSBhcyBhbiBhcmd1bWVudC5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRpQ2xhc3MgZXh0ZW5kcyBGcmVxdWVuY3lDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkaUNsYXNzXCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJtaWRpXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fdGlja3NUb1VuaXRzKHRpY2tzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fYmVhdHNUb1VuaXRzKGJlYXRzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oc3VwZXIuX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGFzIGEgTUlESSBub3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLk1pZGkoNjApLnRvTWlkaSgpOyAvLyA2MFxuICAgICAqL1xuICAgIHRvTWlkaSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaSg2MCkudG9GcmVxdWVuY3koKTsgLy8gMjYxLjYyNTU2NTMwMDU5ODZcbiAgICAgKi9cbiAgICB0b0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIG10b2YodGhpcy50b01pZGkoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyYW5zcG9zZXMgdGhlIGZyZXF1ZW5jeSBieSB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHNlbWl0b25lcy5cbiAgICAgKiBAcmV0dXJuIEEgbmV3IHRyYW5zcG9zZWQgTWlkaUNsYXNzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLk1pZGkoXCJBNFwiKS50cmFuc3Bvc2UoMyk7IC8vIFwiQzVcIlxuICAgICAqL1xuICAgIHRyYW5zcG9zZShpbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gbmV3IE1pZGlDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMudG9NaWRpKCkgKyBpbnRlcnZhbCk7XG4gICAgfVxufVxuLyoqXG4gKiBDb252ZXJ0IGEgdmFsdWUgaW50byBhIEZyZXF1ZW5jeUNsYXNzIG9iamVjdC5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBNaWRpKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgTWlkaUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZGkuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuL1RyYW5zcG9ydFRpbWVcIjtcbi8qKlxuICogVGlja3MgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgVGltZSB2YWx1ZXMuXG4gKiBUaWNrcyBjYW4gYmUgY29uc3RydWN0ZWQgd2l0aCBvciB3aXRob3V0IHRoZSBgbmV3YCBrZXl3b3JkLiBUaWNrcyBjYW4gYmUgcGFzc2VkXG4gKiBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHQgPSBUb25lLlRpY2tzKFwiNG5cIik7IC8vIGEgcXVhcnRlciBub3RlIGFzIHRpY2tzXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgY2xhc3MgVGlja3NDbGFzcyBleHRlbmRzIFRyYW5zcG9ydFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGlja3NcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcImlcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHRpbWUgaW4gdGhlIGdpdmVuIHVuaXRzXG4gICAgICovXG4gICAgX25vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQudGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0UFBRKCkgKiBiZWF0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihzZWNvbmRzIC8gKDYwIC8gdGhpcy5fZ2V0QnBtKCkpICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuICAgICAqL1xuICAgIF90aWNrc1RvVW5pdHModGlja3MpIHtcbiAgICAgICAgcmV0dXJuIHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gdGlja3NcbiAgICAgKi9cbiAgICB0b1RpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBzZWNvbmRzXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMudmFsdWVPZigpIC8gdGhpcy5fZ2V0UFBRKCkpICogKDYwIC8gdGhpcy5fZ2V0QnBtKCkpO1xuICAgIH1cbn1cbi8qKlxuICogQ29udmVydCBhIHRpbWUgcmVwcmVzZW50YXRpb24gdG8gdGlja3NcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUaWNrcyh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja3MuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuLyoqXG4gKiBEcmF3IGlzIHVzZWZ1bCBmb3Igc3luY2hyb25pemluZyB2aXN1YWxzIGFuZCBhdWRpbyBldmVudHMuXG4gKiBDYWxsYmFja3MgZnJvbSBUb25lLlRyYW5zcG9ydCBvciBhbnkgb2YgdGhlIFRvbmUuRXZlbnQgY2xhc3Nlc1xuICogYWx3YXlzIGhhcHBlbiBfYmVmb3JlXyB0aGUgc2NoZWR1bGVkIHRpbWUgYW5kIGFyZSBub3Qgc3luY2hyb25pemVkXG4gKiB0byB0aGUgYW5pbWF0aW9uIGZyYW1lIHNvIHRoZXkgYXJlIG5vdCBnb29kIGZvciB0cmlnZ2VyaW5nIHRpZ2h0bHlcbiAqIHN5bmNocm9uaXplZCB2aXN1YWxzIGFuZCBzb3VuZC4gRHJhdyBtYWtlcyBpdCBlYXN5IHRvIHNjaGVkdWxlXG4gKiBjYWxsYmFja3MgdXNpbmcgdGhlIEF1ZGlvQ29udGV4dCB0aW1lIGFuZCB1c2VzIHJlcXVlc3RBbmltYXRpb25GcmFtZS5cbiAqIEBleGFtcGxlXG4gKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZSgodGltZSkgPT4ge1xuICogXHQvLyB1c2UgdGhlIHRpbWUgYXJndW1lbnQgdG8gc2NoZWR1bGUgYSBjYWxsYmFjayB3aXRoIERyYXdcbiAqIFx0VG9uZS5EcmF3LnNjaGVkdWxlKCgpID0+IHtcbiAqIFx0XHQvLyBkbyBkcmF3aW5nIG9yIERPTSBtYW5pcHVsYXRpb24gaGVyZVxuICogXHRcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogXHR9LCB0aW1lKTtcbiAqIH0sIFwiKzAuNVwiKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRHJhdyBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRHJhd1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGR1cmF0aW9uIGFmdGVyIHdoaWNoIGV2ZW50cyBhcmUgbm90IGludm9rZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmV4cGlyYXRpb24gPSAwLjI1O1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGJlZm9yZSB0aGUgc2NoZWR1bGVkIHRpbWVcbiAgICAgICAgICogdGhhdCB0aGUgY2FsbGJhY2sgY2FuIGJlIGludm9rZWQuIERlZmF1bHQgaXNcbiAgICAgICAgICogaGFsZiB0aGUgdGltZSBvZiBhbiBhbmltYXRpb24gZnJhbWUgKDAuMDA4IHNlY29uZHMpLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hbnRpY2lwYXRpb24gPSAwLjAwODtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZHJhdyBsb29wXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ib3VuZERyYXdMb29wID0gdGhpcy5fZHJhd0xvb3AuYmluZCh0aGlzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbmltYXRpb24gZnJhbWUgaWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FuaW1hdGlvbkZyYW1lID0gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGEgZnVuY3Rpb24gYXQgdGhlIGdpdmVuIHRpbWUgdG8gYmUgaW52b2tlZFxuICAgICAqIG9uIHRoZSBuZWFyZXN0IGFuaW1hdGlvbiBmcmFtZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBDYWxsYmFjayBpcyBpbnZva2VkIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgIFRoZSB0aW1lIHJlbGF0aXZlIHRvIHRoZSBBdWRpb0NvbnRleHQgdGltZSB0byBpbnZva2UgdGhlIGNhbGxiYWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGltZSA9PiB7XG4gICAgICogXHRUb25lLkRyYXcuc2NoZWR1bGUoKCkgPT4gY29uc29sZS5sb2codGltZSksIHRpbWUpO1xuICAgICAqIH0sIDEpO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICovXG4gICAgc2NoZWR1bGUoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIHRpbWU6IHRoaXMudG9TZWNvbmRzKHRpbWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIGRyYXcgbG9vcCBvbiB0aGUgZmlyc3QgZXZlbnRcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuX2JvdW5kRHJhd0xvb3ApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgZXZlbnRzIHNjaGVkdWxlZCBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRpbWUgYWZ0ZXIgd2hpY2ggc2NoZWR1bGVkIGV2ZW50cyB3aWxsIGJlIHJlbW92ZWQgZnJvbSB0aGUgc2NoZWR1bGluZyB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbCh0aGlzLnRvU2Vjb25kcyhhZnRlcikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRyYXcgbG9vcFxuICAgICAqL1xuICAgIF9kcmF3TG9vcCgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICB3aGlsZSAodGhpcy5fZXZlbnRzLmxlbmd0aCAmJiB0aGlzLl9ldmVudHMucGVlaygpLnRpbWUgLSB0aGlzLmFudGljaXBhdGlvbiA8PSBub3cpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLnNoaWZ0KCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgbm93IC0gZXZlbnQudGltZSA8PSB0aGlzLmV4cGlyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBldmVudC5jYWxsYmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudHMuZGlzcG9zZSgpO1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLl9hbmltYXRpb25GcmFtZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZHJhdyA9IG5ldyBEcmF3KHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kcmF3LmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RHJhdy5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogU2ltaWxhciB0byBUb25lLlRpbWVsaW5lLCBidXQgYWxsIGV2ZW50cyByZXByZXNlbnRcbiAqIGludGVydmFscyB3aXRoIGJvdGggXCJ0aW1lXCIgYW5kIFwiZHVyYXRpb25cIiB0aW1lcy4gVGhlXG4gKiBldmVudHMgYXJlIHBsYWNlZCBpbiBhIHRyZWUgc3RydWN0dXJlIG9wdGltaXplZFxuICogZm9yIHF1ZXJ5aW5nIGFuIGludGVyc2VjdGlvbiBwb2ludCB3aXRoIHRoZSB0aW1lbGluZVxuICogZXZlbnRzLiBJbnRlcm5hbGx5IHVzZXMgYW4gW0ludGVydmFsIFRyZWVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ludGVydmFsX3RyZWUpXG4gKiB0byByZXByZXNlbnQgdGhlIGRhdGEuXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnRlcnZhbFRpbWVsaW5lIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiSW50ZXJ2YWxUaW1lbGluZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHJvb3Qgbm9kZSBvZiB0aGUgaW50ZXZhbCB0cmVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIGxlbmd0aCBvZiB0aGUgdGltZWxpbmUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sZW5ndGggPSAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgdG8gYWRkIHRvIHRoZSB0aW1lbGluZS4gQWxsIGV2ZW50cyBtdXN0XG4gICAgICogaGF2ZSBhIHRpbWUgYW5kIGR1cmF0aW9uIHZhbHVlXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIGFkZCB0byB0aGUgdGltZWxpbmVcbiAgICAgKi9cbiAgICBhZGQoZXZlbnQpIHtcbiAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZChldmVudC50aW1lKSwgXCJFdmVudHMgbXVzdCBoYXZlIGEgdGltZSBwcm9wZXJ0eVwiKTtcbiAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZChldmVudC5kdXJhdGlvbiksIFwiRXZlbnRzIG11c3QgaGF2ZSBhIGR1cmF0aW9uIHBhcmFtZXRlclwiKTtcbiAgICAgICAgZXZlbnQudGltZSA9IGV2ZW50LnRpbWUudmFsdWVPZigpO1xuICAgICAgICBsZXQgbm9kZSA9IG5ldyBJbnRlcnZhbE5vZGUoZXZlbnQudGltZSwgZXZlbnQudGltZSArIGV2ZW50LmR1cmF0aW9uLCBldmVudCk7XG4gICAgICAgIGlmICh0aGlzLl9yb290ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yb290ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QuaW5zZXJ0KG5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xlbmd0aCsrO1xuICAgICAgICAvLyBSZXN0cnVjdHVyZSB0cmVlIHRvIGJlIGJhbGFuY2VkXG4gICAgICAgIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICAgICAgbm9kZS51cGRhdGVNYXgoKTtcbiAgICAgICAgICAgIHRoaXMuX3JlYmFsYW5jZShub2RlKTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGZyb20gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBldmVudCB0byByZW1vdmUgZnJvbSB0aGUgdGltZWxpbmVcbiAgICAgKi9cbiAgICByZW1vdmUoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKGV2ZW50LnRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCA9PT0gZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlTm9kZShub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGVuZ3RoLS07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgdGltZWxpbmUuXG4gICAgICogQHJlYWRPbmx5XG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGV2ZW50cyB3aG9zZSB0aW1lIHRpbWUgaXMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIGFmdGVyICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5mb3JFYWNoRnJvbShhZnRlciwgZXZlbnQgPT4gdGhpcy5yZW1vdmUoZXZlbnQpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgcm9vdCBub2RlIGFzIHRoZSBnaXZlbiBub2RlXG4gICAgICovXG4gICAgX3NldFJvb3Qobm9kZSkge1xuICAgICAgICB0aGlzLl9yb290ID0gbm9kZTtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QucGFyZW50ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlIHRoZSByZWZlcmVuY2VzIHRvIHRoZSBub2RlIGluIHRoZSBub2RlJ3MgcGFyZW50XG4gICAgICogd2l0aCB0aGUgcmVwbGFjZW1lbnQgbm9kZS5cbiAgICAgKi9cbiAgICBfcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCByZXBsYWNlbWVudCkge1xuICAgICAgICBpZiAobm9kZS5wYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChub2RlLmlzTGVmdENoaWxkKCkpIHtcbiAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKG5vZGUucGFyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocmVwbGFjZW1lbnQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgbm9kZSBmcm9tIHRoZSB0cmVlIGFuZCByZXBsYWNlIGl0IHdpdGhcbiAgICAgKiBhIHN1Y2Nlc3NvciB3aGljaCBmb2xsb3dzIHRoZSBzY2hlbWEuXG4gICAgICovXG4gICAgX3JlbW92ZU5vZGUobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5sZWZ0ID09PSBudWxsICYmIG5vZGUucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgbnVsbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBub2RlLmxlZnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5vZGUubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBub2RlLnJpZ2h0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGJhbGFuY2UgPSBub2RlLmdldEJhbGFuY2UoKTtcbiAgICAgICAgICAgIGxldCByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIGxldCB0ZW1wID0gbnVsbDtcbiAgICAgICAgICAgIGlmIChiYWxhbmNlID4gMCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmxlZnQucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLmxlZnQucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChyZXBsYWNlbWVudC5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSByZXBsYWNlbWVudC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocmVwbGFjZW1lbnQucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5wYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudC5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50LnBhcmVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LmxlZnQgPSBub2RlLmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5yaWdodCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChub2RlLnJpZ2h0LmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUucmlnaHQubGVmdDtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVwbGFjZW1lbnQubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LmxlZnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXBsYWNlbWVudC5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50LnBhcmVudDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmlzTGVmdENoaWxkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zZXRSb290KHJlcGxhY2VtZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0ZW1wKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKHRlbXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG5vZGUuZGlzcG9zZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgdGhlIHRyZWUgdG8gdGhlIGxlZnRcbiAgICAgKi9cbiAgICBfcm90YXRlTGVmdChub2RlKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuICAgICAgICBjb25zdCBpc0xlZnRDaGlsZCA9IG5vZGUuaXNMZWZ0Q2hpbGQoKTtcbiAgICAgICAgLy8gTWFrZSBub2RlLnJpZ2h0IHRoZSBuZXcgcm9vdCBvZiB0aGlzIHN1YiB0cmVlIChpbnN0ZWFkIG9mIG5vZGUpXG4gICAgICAgIGNvbnN0IHBpdm90Tm9kZSA9IG5vZGUucmlnaHQ7XG4gICAgICAgIGlmIChwaXZvdE5vZGUpIHtcbiAgICAgICAgICAgIG5vZGUucmlnaHQgPSBwaXZvdE5vZGUubGVmdDtcbiAgICAgICAgICAgIHBpdm90Tm9kZS5sZWZ0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSb3RhdGUgdGhlIHRyZWUgdG8gdGhlIHJpZ2h0XG4gICAgICovXG4gICAgX3JvdGF0ZVJpZ2h0KG5vZGUpIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIGNvbnN0IGlzTGVmdENoaWxkID0gbm9kZS5pc0xlZnRDaGlsZCgpO1xuICAgICAgICAvLyBNYWtlIG5vZGUubGVmdCB0aGUgbmV3IHJvb3Qgb2YgdGhpcyBzdWIgdHJlZSAoaW5zdGVhZCBvZiBub2RlKVxuICAgICAgICBjb25zdCBwaXZvdE5vZGUgPSBub2RlLmxlZnQ7XG4gICAgICAgIGlmIChwaXZvdE5vZGUpIHtcbiAgICAgICAgICAgIG5vZGUubGVmdCA9IHBpdm90Tm9kZS5yaWdodDtcbiAgICAgICAgICAgIHBpdm90Tm9kZS5yaWdodCA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGlzTGVmdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LmxlZnQgPSBwaXZvdE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQucmlnaHQgPSBwaXZvdE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRSb290KHBpdm90Tm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQmFsYW5jZSB0aGUgQlNUXG4gICAgICovXG4gICAgX3JlYmFsYW5jZShub2RlKSB7XG4gICAgICAgIGNvbnN0IGJhbGFuY2UgPSBub2RlLmdldEJhbGFuY2UoKTtcbiAgICAgICAgaWYgKGJhbGFuY2UgPiAxICYmIG5vZGUubGVmdCkge1xuICAgICAgICAgICAgaWYgKG5vZGUubGVmdC5nZXRCYWxhbmNlKCkgPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlTGVmdChub2RlLmxlZnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlUmlnaHQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmFsYW5jZSA8IC0xICYmIG5vZGUucmlnaHQpIHtcbiAgICAgICAgICAgIGlmIChub2RlLnJpZ2h0LmdldEJhbGFuY2UoKSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVSaWdodChub2RlLnJpZ2h0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZUxlZnQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFuIGV2ZW50IHdob3NlIHRpbWUgYW5kIGR1cmF0aW9uIHNwYW4gdGhlIGdpdmUgdGltZS4gV2lsbFxuICAgICAqIHJldHVybiB0aGUgbWF0Y2ggd2hvc2UgXCJ0aW1lXCIgdmFsdWUgaXMgY2xvc2VzdCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcmV0dXJuICBUaGUgZXZlbnQgd2hpY2ggc3BhbnMgdGhlIGRlc2lyZWQgdGltZVxuICAgICAqL1xuICAgIGdldCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnNlYXJjaCh0aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBsZXQgbWF4ID0gcmVzdWx0c1swXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJlc3VsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdHNbaV0ubG93ID4gbWF4Lmxvdykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF4ID0gcmVzdWx0c1tpXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWF4LmV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsbE5vZGVzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnRyYXZlcnNlKG5vZGUgPT4gYWxsTm9kZXMucHVzaChub2RlKSk7XG4gICAgICAgICAgICBhbGxOb2Rlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5vZGUuZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgaW4gd2hpY2ggdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBvdmVybGFwcyB3aXRoIHRoZSB0aW1lIGFuZCBkdXJhdGlvbiB0aW1lIG9mIHRoZSBldmVudC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIG92ZXJsYXBwaW5nXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBdFRpbWUodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKHRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgcmVzdWx0cy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5vZGUuZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgaW4gd2hpY2ggdGhlIHRpbWUgaXMgZ3JlYXRlclxuICAgICAqIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEZyb20odGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoQWZ0ZXIodGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICByZXN1bHRzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC50cmF2ZXJzZShub2RlID0+IG5vZGUuZGlzcG9zZSgpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOVEVSVkFMIE5PREUgSEVMUEVSXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogUmVwcmVzZW50cyBhIG5vZGUgaW4gdGhlIGJpbmFyeSBzZWFyY2ggdHJlZSwgd2l0aCB0aGUgYWRkaXRpb25cbiAqIG9mIGEgXCJoaWdoXCIgdmFsdWUgd2hpY2gga2VlcHMgdHJhY2sgb2YgdGhlIGhpZ2hlc3QgdmFsdWUgb2ZcbiAqIGl0cyBjaGlsZHJlbi5cbiAqIFJlZmVyZW5jZXM6XG4gKiBodHRwczovL2Jyb29rbm92YWsud29yZHByZXNzLmNvbS8yMDEzLzEyLzA3L2F1Z21lbnRlZC1pbnRlcnZhbC10cmVlLWluLWMvXG4gKiBodHRwOi8vd3d3Lm1pZi52dS5sdC9+dmFsZGFzL0FMR09SSVRNQUkvTElURVJBVFVSQS9Db3JtZW4vQ29ybWVuLnBkZlxuICogQHBhcmFtIGxvd1xuICogQHBhcmFtIGhpZ2hcbiAqL1xuY2xhc3MgSW50ZXJ2YWxOb2RlIHtcbiAgICBjb25zdHJ1Y3Rvcihsb3csIGhpZ2gsIGV2ZW50KSB7XG4gICAgICAgIC8vIHRoZSBub2RlcyB0byB0aGUgbGVmdFxuICAgICAgICB0aGlzLl9sZWZ0ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIG5vZGVzIHRvIHRoZSByaWdodFxuICAgICAgICB0aGlzLl9yaWdodCA9IG51bGw7XG4gICAgICAgIC8vIHRoZSBwYXJlbnQgbm9kZVxuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIC8vIHRoZSBudW1iZXIgb2YgY2hpbGQgbm9kZXNcbiAgICAgICAgdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgICB0aGlzLmV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIC8vIHRoZSBsb3cgdmFsdWVcbiAgICAgICAgdGhpcy5sb3cgPSBsb3c7XG4gICAgICAgIC8vIHRoZSBoaWdoIHZhbHVlXG4gICAgICAgIHRoaXMuaGlnaCA9IGhpZ2g7XG4gICAgICAgIC8vIHRoZSBoaWdoIHZhbHVlIGZvciB0aGlzIGFuZCBhbGwgY2hpbGQgbm9kZXNcbiAgICAgICAgdGhpcy5tYXggPSB0aGlzLmhpZ2g7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc2VydCBhIG5vZGUgaW50byB0aGUgY29ycmVjdCBzcG90IGluIHRoZSB0cmVlXG4gICAgICovXG4gICAgaW5zZXJ0KG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUubG93IDw9IHRoaXMubG93KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sZWZ0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0ID0gbm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubGVmdC5pbnNlcnQobm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodCA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0Lmluc2VydChub2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWFyY2ggdGhlIHRyZWUgZm9yIG5vZGVzIHdoaWNoIG92ZXJsYXBcbiAgICAgKiB3aXRoIHRoZSBnaXZlbiBwb2ludFxuICAgICAqIEBwYXJhbSAgcG9pbnQgIFRoZSBwb2ludCB0byBxdWVyeVxuICAgICAqIEBwYXJhbSAgcmVzdWx0cyAgVGhlIGFycmF5IHRvIHB1dCB0aGUgcmVzdWx0c1xuICAgICAqL1xuICAgIHNlYXJjaChwb2ludCwgcmVzdWx0cykge1xuICAgICAgICAvLyBJZiBwIGlzIHRvIHRoZSByaWdodCBvZiB0aGUgcmlnaHRtb3N0IHBvaW50IG9mIGFueSBpbnRlcnZhbFxuICAgICAgICAvLyBpbiB0aGlzIG5vZGUgYW5kIGFsbCBjaGlsZHJlbiwgdGhlcmUgd29uJ3QgYmUgYW55IG1hdGNoZXMuXG4gICAgICAgIGlmIChwb2ludCA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VhcmNoIGxlZnQgY2hpbGRyZW5cbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5sZWZ0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2hlY2sgdGhpcyBub2RlXG4gICAgICAgIGlmICh0aGlzLmxvdyA8PSBwb2ludCAmJiB0aGlzLmhpZ2ggPiBwb2ludCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHAgaXMgdG8gdGhlIGxlZnQgb2YgdGhlIHRpbWUgb2YgdGhpcyBpbnRlcnZhbCxcbiAgICAgICAgLy8gdGhlbiBpdCBjYW4ndCBiZSBpbiBhbnkgY2hpbGQgdG8gdGhlIHJpZ2h0LlxuICAgICAgICBpZiAodGhpcy5sb3cgPiBwb2ludCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlYXJjaCByaWdodCBjaGlsZHJlblxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodC5zZWFyY2gocG9pbnQsIHJlc3VsdHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgdHJlZSBmb3Igbm9kZXMgd2hpY2ggYXJlIGxlc3NcbiAgICAgKiB0aGFuIHRoZSBnaXZlbiBwb2ludFxuICAgICAqIEBwYXJhbSAgcG9pbnQgIFRoZSBwb2ludCB0byBxdWVyeVxuICAgICAqIEBwYXJhbSAgcmVzdWx0cyAgVGhlIGFycmF5IHRvIHB1dCB0aGUgcmVzdWx0c1xuICAgICAqL1xuICAgIHNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKSB7XG4gICAgICAgIC8vIENoZWNrIHRoaXMgbm9kZVxuICAgICAgICBpZiAodGhpcy5sb3cgPj0gcG9pbnQpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQuc2VhcmNoQWZ0ZXIocG9pbnQsIHJlc3VsdHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNlYXJjaCB0aGUgcmlnaHQgc2lkZVxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodC5zZWFyY2hBZnRlcihwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBjYWxsYmFjayBvbiB0aGlzIGVsZW1lbnQgYW5kIGJvdGggaXQncyBicmFuY2hlc1xuICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSAgY2FsbGJhY2tcbiAgICAgKi9cbiAgICB0cmF2ZXJzZShjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjayh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5sZWZ0LnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5yaWdodC50cmF2ZXJzZShjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBoZWlnaHQgb2YgdGhlIG5vZGVcbiAgICAgKi9cbiAgICB1cGRhdGVIZWlnaHQoKSB7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwgJiYgdGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBNYXRoLm1heCh0aGlzLmxlZnQuaGVpZ2h0LCB0aGlzLnJpZ2h0LmhlaWdodCkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5yaWdodC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLmxlZnQuaGVpZ2h0ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuICAgICAqL1xuICAgIHVwZGF0ZU1heCgpIHtcbiAgICAgICAgdGhpcy5tYXggPSB0aGlzLmhpZ2g7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gTWF0aC5tYXgodGhpcy5tYXgsIHRoaXMubGVmdC5tYXgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1heCA9IE1hdGgubWF4KHRoaXMubWF4LCB0aGlzLnJpZ2h0Lm1heCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhbGFuY2UgaXMgaG93IHRoZSBsZWFmcyBhcmUgZGlzdHJpYnV0ZWQgb24gdGhlIG5vZGVcbiAgICAgKiBAcmV0dXJuICBOZWdhdGl2ZSBudW1iZXJzIGFyZSBiYWxhbmNlZCB0byB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBnZXRCYWxhbmNlKCkge1xuICAgICAgICBsZXQgYmFsYW5jZSA9IDA7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwgJiYgdGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgYmFsYW5jZSA9IHRoaXMubGVmdC5oZWlnaHQgLSB0aGlzLnJpZ2h0LmhlaWdodDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGJhbGFuY2UgPSB0aGlzLmxlZnQuaGVpZ2h0ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBiYWxhbmNlID0gLSh0aGlzLnJpZ2h0LmhlaWdodCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBiYWxhbmNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcmV0dXJucyB0cnVlIGlmIHRoaXMgbm9kZSBpcyB0aGUgbGVmdCBjaGlsZCBvZiBpdHMgcGFyZW50XG4gICAgICovXG4gICAgaXNMZWZ0Q2hpbGQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudCAhPT0gbnVsbCAmJiB0aGlzLnBhcmVudC5sZWZ0ID09PSB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQvc2V0IHRoZSBsZWZ0IG5vZGVcbiAgICAgKi9cbiAgICBnZXQgbGVmdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xlZnQ7XG4gICAgfVxuICAgIHNldCBsZWZ0KG5vZGUpIHtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG5vZGU7XG4gICAgICAgIGlmIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnBhcmVudCA9IHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgdGhpcy51cGRhdGVNYXgoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZ2V0L3NldCB0aGUgcmlnaHQgbm9kZVxuICAgICAqL1xuICAgIGdldCByaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JpZ2h0O1xuICAgIH1cbiAgICBzZXQgcmlnaHQobm9kZSkge1xuICAgICAgICB0aGlzLl9yaWdodCA9IG5vZGU7XG4gICAgICAgIGlmIChub2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICBub2RlLnBhcmVudCA9IHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgdGhpcy51cGRhdGVNYXgoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogbnVsbCBvdXQgcmVmZXJlbmNlcy5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICB0aGlzLnBhcmVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9yaWdodCA9IG51bGw7XG4gICAgICAgIHRoaXMuZXZlbnQgPSBudWxsO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUludGVydmFsVGltZWxpbmUuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vY2xvY2svQ2xvY2tcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL2Nsb2NrL1RyYW5zcG9ydFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Db250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0Jhc2VDb250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0RlbGF5XCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0Rlc3RpbmF0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0dhaW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvT2ZmbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9QYXJhbVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL0ZyZXF1ZW5jeVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9NaWRpXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL1RpbWVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVGlja3NcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IFwiLi91dGlsL0RyYXdcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvRW1pdHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9JbnRlcnZhbFRpbWVsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvVHlwZUNoZWNrXCI7XG5leHBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIsIGludGVydmFsVG9GcmVxdWVuY3lSYXRpbywgZnRvbSwgbXRvZiB9IGZyb20gXCIuL3R5cGUvQ29udmVyc2lvbnNcIjtcbmV4cG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzLCBkZWZhdWx0QXJnIH0gZnJvbSBcIi4vdXRpbC9EZWZhdWx0c1wiO1xuLy8gZ2V0IHRoZSB1bml0cyBhbmQgZXhwb3J0IHRoZW0gdW5kZXIgdGhlIFwiVW5pdFwiIG5hbWVzcGFjZVxuaW1wb3J0ICogYXMgVW5pdCBmcm9tIFwiLi90eXBlL1VuaXRzXCI7XG5leHBvcnQgeyBVbml0IH07XG4vLyBleHBvcnQgdGhlIGRlYnVnIHN0dWZmIGFzIERlYnVnXG5pbXBvcnQgKiBhcyBkZWJ1ZyBmcm9tIFwiLi91dGlsL0RlYnVnXCI7XG5leHBvcnQgeyBkZWJ1ZyB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFZvbHVtZSBpcyBhIHNpbXBsZSB2b2x1bWUgbm9kZSwgdXNlZnVsIGZvciBjcmVhdGluZyBhIHZvbHVtZSBmYWRlci5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgdm9sID0gbmV3IFRvbmUuVm9sdW1lKC0xMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3Qodm9sKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgVm9sdW1lIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFZvbHVtZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlZvbHVtZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVm9sdW1lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLm91dHB1dC5nYWluO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5fdW5tdXRlZFZvbHVtZSA9IG9wdGlvbnMudm9sdW1lO1xuICAgICAgICAvLyBzZXQgdGhlIG11dGUgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgdm9sID0gbmV3IFRvbmUuVm9sdW1lKC0xMikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHZvbCkuc3RhcnQoKTtcbiAgICAgKiAvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiB2b2wubXV0ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZvbHVtZS52YWx1ZSA9PT0gLUluZmluaXR5O1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5tdXRlICYmIG11dGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3VubXV0ZWRWb2x1bWUgPSB0aGlzLnZvbHVtZS52YWx1ZTtcbiAgICAgICAgICAgIC8vIG1heWJlIGl0IHNob3VsZCByYW1wIGhlcmU/XG4gICAgICAgICAgICB0aGlzLnZvbHVtZS52YWx1ZSA9IC1JbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLm11dGUgJiYgIW11dGUpIHtcbiAgICAgICAgICAgIHRoaXMudm9sdW1lLnZhbHVlID0gdGhpcy5fdW5tdXRlZFZvbHVtZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Vm9sdW1lLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi8uLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4vR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogQSBzaW5nbGUgbWFzdGVyIG91dHB1dCB3aGljaCBpcyBjb25uZWN0ZWQgdG8gdGhlXG4gKiBBdWRpb0Rlc3RpbmF0aW9uTm9kZSAoYWthIHlvdXIgc3BlYWtlcnMpLlxuICogSXQgcHJvdmlkZXMgdXNlZnVsIGNvbnZlbmllbmNlcyBzdWNoIGFzIHRoZSBhYmlsaXR5XG4gKiB0byBzZXQgdGhlIHZvbHVtZSBhbmQgbXV0ZSB0aGUgZW50aXJlIGFwcGxpY2F0aW9uLlxuICogSXQgYWxzbyBnaXZlcyB5b3UgdGhlIGFiaWxpdHkgdG8gYXBwbHkgbWFzdGVyIGVmZmVjdHMgdG8geW91ciBhcHBsaWNhdGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5zdGFydCgpO1xuICogLy8gdGhlIGF1ZGlvIHdpbGwgZ28gZnJvbSB0aGUgb3NjaWxsYXRvciB0byB0aGUgc3BlYWtlcnNcbiAqIG9zY2lsbGF0b3IuY29ubmVjdChUb25lLmdldERlc3RpbmF0aW9uKCkpO1xuICogLy8gYSBjb252ZW5pZW5jZSBmb3IgY29ubmVjdGluZyB0byB0aGUgbWFzdGVyIG91dHB1dCBpcyBhbHNvIHByb3ZpZGVkOlxuICogb3NjaWxsYXRvci50b0Rlc3RpbmF0aW9uKCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRGVzdGluYXRpb24gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVzdGluYXRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGVzdGluYXRpb25cIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBWb2x1bWUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdm9sdW1lIG9mIHRoZSBtYXN0ZXIgb3V0cHV0IGluIGRlY2liZWxzLiAtSW5maW5pdHkgaXMgc2lsZW50LCBhbmQgMCBpcyBubyBjaGFuZ2UuXG4gICAgICAgICAqIEBleGFtcGxlXG4gICAgICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAqIG9zYy5zdGFydCgpO1xuICAgICAgICAgKiAvLyByYW1wIHRoZSB2b2x1bWUgZG93biB0byBzaWxlbnQgb3ZlciAxMCBzZWNvbmRzXG4gICAgICAgICAqIFRvbmUuZ2V0RGVzdGluYXRpb24oKS52b2x1bWUucmFtcFRvKC1JbmZpbml0eSwgMTApO1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLmlucHV0LnZvbHVtZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERlc3RpbmF0aW9uLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgdGhpcy5vdXRwdXQsIHRoaXMuY29udGV4dC5yYXdDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuaW5wdXQsIHRoaXMuY29udGV4dC5yYXdDb250ZXh0LmRlc3RpbmF0aW9uLCB0aGlzLm91dHB1dF07XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuc3RhcnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICogXHQvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiBcdFRvbmUuRGVzdGluYXRpb24ubXV0ZSA9IHRydWU7XG4gICAgICogfSwgMTAwMCk7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0Lm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5pbnB1dC5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgbWFzdGVyIGVmZmVjdHMgY2hhaW4uIE5PVEU6IHRoaXMgd2lsbCBkaXNjb25uZWN0IGFueSBub2RlcyB3aGljaCB3ZXJlIHByZXZpb3VzbHlcbiAgICAgKiBjaGFpbmVkIGluIHRoZSBtYXN0ZXIgZWZmZWN0cyBjaGFpbi5cbiAgICAgKiBAcGFyYW0gYXJncyBBbGwgYXJndW1lbnRzIHdpbGwgYmUgY29ubmVjdGVkIGluIGEgcm93IGFuZCB0aGUgTWFzdGVyIHdpbGwgYmUgcm91dGVkIHRocm91Z2ggaXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyByb3V0ZSBhbGwgYXVkaW8gdGhyb3VnaCBhIGZpbHRlciBhbmQgY29tcHJlc3NvclxuICAgICAqIGNvbnN0IGxvd3Bhc3MgPSBuZXcgVG9uZS5GaWx0ZXIoODAwLCBcImxvd3Bhc3NcIik7XG4gICAgICogY29uc3QgY29tcHJlc3NvciA9IG5ldyBUb25lLkNvbXByZXNzb3IoLTE4KTtcbiAgICAgKiBUb25lLkRlc3RpbmF0aW9uLmNoYWluKGxvd3Bhc3MsIGNvbXByZXNzb3IpO1xuICAgICAqL1xuICAgIGNoYWluKC4uLmFyZ3MpIHtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgIGFyZ3MudW5zaGlmdCh0aGlzLmlucHV0KTtcbiAgICAgICAgYXJncy5wdXNoKHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29ubmVjdFNlcmllcyguLi5hcmdzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBjaGFubmVscyB0aGUgc3lzdGVtIGNhbiBvdXRwdXRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuRGVzdGluYXRpb24ubWF4Q2hhbm5lbENvdW50KTtcbiAgICAgKi9cbiAgICBnZXQgbWF4Q2hhbm5lbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24ubWF4Q2hhbm5lbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRlc3RpbmF0aW9uID0gbmV3IERlc3RpbmF0aW9uKHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kZXN0aW5hdGlvbi5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlc3RpbmF0aW9uLmpzLm1hcCIsImltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuLyoqXG4gKiBSZXByZXNlbnRzIGEgc2luZ2xlIHZhbHVlIHdoaWNoIGlzIGdldHRhYmxlIGFuZCBzZXR0YWJsZSBpbiBhIHRpbWVkIHdheVxuICovXG5leHBvcnQgY2xhc3MgVGltZWxpbmVWYWx1ZSBleHRlbmRzIFRvbmUge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBpbml0aWFsVmFsdWUgVGhlIHZhbHVlIHRvIHJldHVybiBpZiB0aGVyZSBpcyBubyBzY2hlZHVsZWQgdmFsdWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoaW5pdGlhbFZhbHVlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGltZWxpbmVWYWx1ZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVsaW5lIHdoaWNoIHN0b3JlcyB0aGUgdmFsdWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lbGluZSA9IG5ldyBUaW1lbGluZSh7IG1lbW9yeTogMTAgfSk7XG4gICAgICAgIHRoaXMuX2luaXRpYWxWYWx1ZSA9IGluaXRpYWxWYWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqL1xuICAgIHNldCh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5hZGQoe1xuICAgICAgICAgICAgdmFsdWUsIHRpbWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICovXG4gICAgZ2V0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl90aW1lbGluZS5nZXQodGltZSk7XG4gICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGV2ZW50LnZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpbWVsaW5lVmFsdWUuanMubWFwIiwiaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBUcmFuc3BvcnRFdmVudCBpcyBhbiBpbnRlcm5hbCBjbGFzcyB1c2VkIGJ5IFtbVHJhbnNwb3J0XV1cbiAqIHRvIHNjaGVkdWxlIGV2ZW50cy4gRG8gbm8gaW52b2tlIHRoaXMgY2xhc3MgZGlyZWN0bHksIGl0IGlzXG4gKiBoYW5kbGVkIGZyb20gd2l0aGluIFRvbmUuVHJhbnNwb3J0LlxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0RXZlbnQge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB0cmFuc3BvcnQgVGhlIHRyYW5zcG9ydCBvYmplY3Qgd2hpY2ggdGhlIGV2ZW50IGJlbG9uZ3MgdG9cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0cmFuc3BvcnQsIG9wdHMpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB1bmlxdWUgaWQgb2YgdGhlIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlkID0gVHJhbnNwb3J0RXZlbnQuX2V2ZW50SWQrKztcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oVHJhbnNwb3J0RXZlbnQuZ2V0RGVmYXVsdHMoKSwgb3B0cyk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy5fb25jZSA9IG9wdGlvbnMub25jZTtcbiAgICAgICAgdGhpcy50aW1lID0gb3B0aW9ucy50aW1lO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIG9uY2U6IGZhbHNlLFxuICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBldmVudCBjYWxsYmFjay5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSBBdWRpb0NvbnRleHQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBldmVudFxuICAgICAqL1xuICAgIGludm9rZSh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmNhbGxiYWNrKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29uY2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLmlkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogQ3VycmVudCBJRCBjb3VudGVyXG4gKi9cblRyYW5zcG9ydEV2ZW50Ll9ldmVudElkID0gMDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydEV2ZW50LmpzLm1hcCIsImltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0RXZlbnQgfSBmcm9tIFwiLi9UcmFuc3BvcnRFdmVudFwiO1xuLyoqXG4gKiBUcmFuc3BvcnRSZXBlYXRFdmVudCBpcyBhbiBpbnRlcm5hbCBjbGFzcyB1c2VkIGJ5IFRvbmUuVHJhbnNwb3J0XG4gKiB0byBzY2hlZHVsZSByZXBlYXQgZXZlbnRzLiBUaGlzIGNsYXNzIHNob3VsZCBub3QgYmUgaW5zdGFudGlhdGVkIGRpcmVjdGx5LlxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0UmVwZWF0RXZlbnQgZXh0ZW5kcyBUcmFuc3BvcnRFdmVudCB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHRyYW5zcG9ydCBUaGUgdHJhbnNwb3J0IG9iamVjdCB3aGljaCB0aGUgZXZlbnQgYmVsb25ncyB0b1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCwgb3B0cykge1xuICAgICAgICBzdXBlcih0cmFuc3BvcnQsIG9wdHMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIElEIG9mIHRoZSBjdXJyZW50IHRpbWVsaW5lIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jdXJyZW50SWQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJRCBvZiB0aGUgbmV4dCB0aW1lbGluZSBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmV4dElkID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZSBvZiB0aGUgbmV4dCBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhIHJlZmVyZW5jZSB0byB0aGUgYm91bmQgc3RhcnQgbWV0aG9kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ib3VuZFJlc3RhcnQgPSB0aGlzLl9yZXN0YXJ0LmJpbmQodGhpcyk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFRyYW5zcG9ydFJlcGVhdEV2ZW50LmdldERlZmF1bHRzKCksIG9wdHMpO1xuICAgICAgICB0aGlzLmR1cmF0aW9uID0gbmV3IFRpY2tzQ2xhc3ModHJhbnNwb3J0LmNvbnRleHQsIG9wdGlvbnMuZHVyYXRpb24pLnZhbHVlT2YoKTtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwgPSBuZXcgVGlja3NDbGFzcyh0cmFuc3BvcnQuY29udGV4dCwgb3B0aW9ucy5pbnRlcnZhbCkudmFsdWVPZigpO1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IG9wdGlvbnMudGltZTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vbihcImxvb3BTdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSB0aGlzLnRyYW5zcG9ydC5jb250ZXh0O1xuICAgICAgICB0aGlzLl9yZXN0YXJ0KCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIFRyYW5zcG9ydEV2ZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGR1cmF0aW9uOiBJbmZpbml0eSxcbiAgICAgICAgICAgIGludGVydmFsOiAxLFxuICAgICAgICAgICAgb25jZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrLiBSZXR1cm5zIHRoZSB0aWNrIHRpbWUgd2hpY2hcbiAgICAgKiB0aGUgbmV4dCBldmVudCBzaG91bGQgYmUgc2NoZWR1bGVkIGF0LlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIEF1ZGlvQ29udGV4dCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgaW52b2tlKHRpbWUpIHtcbiAgICAgICAgLy8gY3JlYXRlIG1vcmUgZXZlbnRzIGlmIG5lY2Vzc2FyeVxuICAgICAgICB0aGlzLl9jcmVhdGVFdmVudHModGltZSk7XG4gICAgICAgIC8vIGNhbGwgdGhlIHN1cGVyIGNsYXNzXG4gICAgICAgIHN1cGVyLmludm9rZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHVzaCBtb3JlIGV2ZW50cyBvbnRvIHRoZSB0aW1lbGluZSB0byBrZWVwIHVwIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIF9jcmVhdGVFdmVudHModGltZSkge1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgbmV4dCBldmVudFxuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudHJhbnNwb3J0LmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAodGlja3MgPj0gdGhpcy50aW1lICYmIHRpY2tzID49IHRoaXMuX25leHRUaWNrICYmIHRoaXMuX25leHRUaWNrICsgdGhpcy5faW50ZXJ2YWwgPCB0aGlzLnRpbWUgKyB0aGlzLmR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9uZXh0VGljayArPSB0aGlzLl9pbnRlcnZhbDtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IHRoaXMuX25leHRJZDtcbiAgICAgICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUHVzaCBtb3JlIGV2ZW50cyBvbnRvIHRoZSB0aW1lbGluZSB0byBrZWVwIHVwIHdpdGggdGhlIHBvc2l0aW9uIG9mIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fY3VycmVudElkKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fbmV4dElkKTtcbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWU7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50cmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aWNrcyA+IHRoaXMudGltZSkge1xuICAgICAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSB0aGlzLnRpbWUgKyBNYXRoLmNlaWwoKHRpY2tzIC0gdGhpcy50aW1lKSAvIHRoaXMuX2ludGVydmFsKSAqIHRoaXMuX2ludGVydmFsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuICAgICAgICB0aGlzLl9uZXh0SWQgPSB0aGlzLnRyYW5zcG9ydC5zY2hlZHVsZU9uY2UodGhpcy5pbnZva2UuYmluZCh0aGlzKSwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9uZXh0VGljaykudG9TZWNvbmRzKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fY3VycmVudElkKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5fbmV4dElkKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub2ZmKFwibG9vcFN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydFJlcGVhdEV2ZW50LmpzLm1hcCIsImltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvVGltZVwiO1xuaW1wb3J0IHsgVGltZWxpbmVWYWx1ZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVGltZWxpbmVWYWx1ZVwiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi4vY29udGV4dC9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW1pdHRlciB9IGZyb20gXCIuLi91dGlsL0VtaXR0ZXJcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgSW50ZXJ2YWxUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL0ludGVydmFsVGltZWxpbmVcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgQ2xvY2sgfSBmcm9tIFwiLi9DbG9ja1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0RXZlbnQgfSBmcm9tIFwiLi9UcmFuc3BvcnRFdmVudFwiO1xuaW1wb3J0IHsgVHJhbnNwb3J0UmVwZWF0RXZlbnQgfSBmcm9tIFwiLi9UcmFuc3BvcnRSZXBlYXRFdmVudFwiO1xuLyoqXG4gKiBUcmFuc3BvcnQgZm9yIHRpbWluZyBtdXNpY2FsIGV2ZW50cy5cbiAqIFN1cHBvcnRzIHRlbXBvIGN1cnZlcyBhbmQgdGltZSBjaGFuZ2VzLiBVbmxpa2UgYnJvd3Nlci1iYXNlZCB0aW1pbmcgKHNldEludGVydmFsLCByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpXG4gKiBUcmFuc3BvcnQgdGltaW5nIGV2ZW50cyBwYXNzIGluIHRoZSBleGFjdCB0aW1lIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnRcbiAqIGluIHRoZSBhcmd1bWVudCBvZiB0aGUgY2FsbGJhY2sgZnVuY3Rpb24uIFBhc3MgdGhhdCB0aW1lIHZhbHVlIHRvIHRoZSBvYmplY3RcbiAqIHlvdSdyZSBzY2hlZHVsaW5nLiA8YnI+PGJyPlxuICogQSBzaW5nbGUgdHJhbnNwb3J0IGlzIGNyZWF0ZWQgZm9yIHlvdSB3aGVuIHRoZSBsaWJyYXJ5IGlzIGluaXRpYWxpemVkLlxuICogPGJyPjxicj5cbiAqIFRoZSB0cmFuc3BvcnQgZW1pdHMgdGhlIGV2ZW50czogXCJzdGFydFwiLCBcInN0b3BcIiwgXCJwYXVzZVwiLCBhbmQgXCJsb29wXCIgd2hpY2ggYXJlXG4gKiBjYWxsZWQgd2l0aCB0aGUgdGltZSBvZiB0aGF0IGV2ZW50IGFzIHRoZSBhcmd1bWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHJlcGVhdGVkIGV2ZW50IGV2ZXJ5IDh0aCBub3RlXG4gKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCgodGltZSkgPT4ge1xuICogXHQvLyB1c2UgdGhlIGNhbGxiYWNrIHRpbWUgdG8gc2NoZWR1bGUgZXZlbnRzXG4gKiBcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpO1xuICogfSwgXCI4blwiKTtcbiAqIC8vIHRyYW5zcG9ydCBtdXN0IGJlIHN0YXJ0ZWQgYmVmb3JlIGl0IHN0YXJ0cyBpbnZva2luZyBldmVudHNcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJhbnNwb3J0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRyYW5zcG9ydFwiO1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRMT09QSU5HXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIHRyYW5zcG9ydCBsb29wcyBvciBub3QuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb29wID0gbmV3IFRpbWVsaW5lVmFsdWUoZmFsc2UpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvb3Agc3RhcnQgcG9zaXRpb24gaW4gdGlja3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbG9vcCBlbmQgcG9zaXRpb24gaW4gdGlja3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSAwO1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRUSU1FTElORSBFVkVOVFNcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgdGhlIGV2ZW50cyBpbiBhbiBvYmplY3QgdG8ga2VlcCB0cmFjayBieSBJRFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0ge307XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2NoZWR1bGVkIGV2ZW50cy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbmV3IFRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXBlYXRlZCBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzID0gbmV3IEludGVydmFsVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgc3luY2VkIFNpZ25hbHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzd2luZyBhbW91bnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyYW5zcG9ydC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICAvLyBDTE9DSy9URU1QT1xuICAgICAgICB0aGlzLl9wcHEgPSBvcHRpb25zLnBwcTtcbiAgICAgICAgdGhpcy5fY2xvY2sgPSBuZXcgQ2xvY2soe1xuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3Byb2Nlc3NUaWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB1bml0czogXCJicG1cIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2JpbmRDbG9ja0V2ZW50cygpO1xuICAgICAgICB0aGlzLmJwbSA9IHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fY2xvY2suZnJlcXVlbmN5Lm11bHRpcGxpZXIgPSBvcHRpb25zLnBwcTtcbiAgICAgICAgdGhpcy5icG0uc2V0VmFsdWVBdFRpbWUob3B0aW9ucy5icG0sIDApO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImJwbVwiKTtcbiAgICAgICAgdGhpcy5fdGltZVNpZ25hdHVyZSA9IG9wdGlvbnMudGltZVNpZ25hdHVyZTtcbiAgICAgICAgLy8gU1dJTkdcbiAgICAgICAgdGhpcy5fc3dpbmdUaWNrcyA9IG9wdGlvbnMucHBxIC8gMjsgLy8gOG5cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYnBtOiAxMjAsXG4gICAgICAgICAgICBsb29wRW5kOiBcIjRtXCIsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBwcHE6IDE5MixcbiAgICAgICAgICAgIHN3aW5nOiAwLFxuICAgICAgICAgICAgc3dpbmdTdWJkaXZpc2lvbjogXCI4blwiLFxuICAgICAgICAgICAgdGltZVNpZ25hdHVyZTogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VElDS1NcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBjYWxsZWQgb24gZXZlcnkgdGlja1xuICAgICAqIEBwYXJhbSAgdGlja1RpbWUgY2xvY2sgcmVsYXRpdmUgdGljayB0aW1lXG4gICAgICovXG4gICAgX3Byb2Nlc3NUaWNrKHRpY2tUaW1lLCB0aWNrcykge1xuICAgICAgICAvLyBkbyB0aGUgbG9vcCB0ZXN0XG4gICAgICAgIGlmICh0aGlzLl9sb29wLmdldCh0aWNrVGltZSkpIHtcbiAgICAgICAgICAgIGlmICh0aWNrcyA+PSB0aGlzLl9sb29wRW5kKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwibG9vcEVuZFwiLCB0aWNrVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodGhpcy5fbG9vcFN0YXJ0LCB0aWNrVGltZSk7XG4gICAgICAgICAgICAgICAgdGlja3MgPSB0aGlzLl9sb29wU3RhcnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwibG9vcFN0YXJ0XCIsIHRpY2tUaW1lLCB0aGlzLl9jbG9jay5nZXRTZWNvbmRzQXRUaW1lKHRpY2tUaW1lKSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwibG9vcFwiLCB0aWNrVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaGFuZGxlIHN3aW5nXG4gICAgICAgIGlmICh0aGlzLl9zd2luZ0Ftb3VudCA+IDAgJiZcbiAgICAgICAgICAgIHRpY2tzICUgdGhpcy5fcHBxICE9PSAwICYmIC8vIG5vdCBvbiBhIGRvd25iZWF0XG4gICAgICAgICAgICB0aWNrcyAlICh0aGlzLl9zd2luZ1RpY2tzICogMikgIT09IDApIHtcbiAgICAgICAgICAgIC8vIGFkZCBzb21lIHN3aW5nXG4gICAgICAgICAgICBjb25zdCBwcm9ncmVzcyA9ICh0aWNrcyAlICh0aGlzLl9zd2luZ1RpY2tzICogMikpIC8gKHRoaXMuX3N3aW5nVGlja3MgKiAyKTtcbiAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IE1hdGguc2luKChwcm9ncmVzcykgKiBNYXRoLlBJKSAqIHRoaXMuX3N3aW5nQW1vdW50O1xuICAgICAgICAgICAgdGlja1RpbWUgKz0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9zd2luZ1RpY2tzICogMiAvIDMpLnRvU2Vjb25kcygpICogYW1vdW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIGludm9rZSB0aGUgdGltZWxpbmUgZXZlbnRzIHNjaGVkdWxlZCBvbiB0aGlzIHRpY2tcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZm9yRWFjaEF0VGltZSh0aWNrcywgZXZlbnQgPT4gZXZlbnQuaW52b2tlKHRpY2tUaW1lKSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U0NIRURVTEFCTEUgRVZFTlRTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYW4gZXZlbnQgYWxvbmcgdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gYmUgaW52b2tlZCBhdCB0aGUgdGltZS5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0byBpbnZva2UgdGhlIGNhbGxiYWNrIGF0LlxuICAgICAqIEByZXR1cm4gVGhlIGlkIG9mIHRoZSBldmVudCB3aGljaCBjYW4gYmUgdXNlZCBmb3IgY2FuY2VsaW5nIHRoZSBldmVudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHNjaGVkdWxlIGFuIGV2ZW50IG9uIHRoZSAxNnRoIG1lYXN1cmVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZSgodGltZSkgPT4ge1xuICAgICAqIFx0Ly8gaW52b2tlZCBvbiBtZWFzdXJlIDE2XG4gICAgICogXHRjb25zb2xlLmxvZyhcIm1lYXN1cmUgMTYhXCIpO1xuICAgICAqIH0sIFwiMTY6MDowXCIpO1xuICAgICAqL1xuICAgIHNjaGVkdWxlKGNhbGxiYWNrLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IFRyYW5zcG9ydEV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgdGltZTogbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fdGltZWxpbmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhIHJlcGVhdGVkIGV2ZW50IGFsb25nIHRoZSB0aW1lbGluZS4gVGhlIGV2ZW50IHdpbGwgZmlyZVxuICAgICAqIGF0IHRoZSBgaW50ZXJ2YWxgIHN0YXJ0aW5nIGF0IHRoZSBgc3RhcnRUaW1lYCBhbmQgZm9yIHRoZSBzcGVjaWZpZWRcbiAgICAgKiBgZHVyYXRpb25gLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlLlxuICAgICAqIEBwYXJhbSAgaW50ZXJ2YWwgICBUaGUgZHVyYXRpb24gYmV0d2VlbiBzdWNjZXNzaXZlIGNhbGxiYWNrcy4gTXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlci5cbiAgICAgKiBAcGFyYW0gIHN0YXJ0VGltZSAgV2hlbiBhbG9uZyB0aGUgdGltZWxpbmUgdGhlIGV2ZW50cyBzaG91bGQgc3RhcnQgYmVpbmcgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBldmVudCBzaG91bGQgcmVwZWF0LlxuICAgICAqIEByZXR1cm4gIFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50LiBVc2UgdGhpcyB0byBjYW5jZWwgdGhlIGV2ZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIGEgY2FsbGJhY2sgaW52b2tlZCBldmVyeSBlaWdodGggbm90ZSBhZnRlciB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KCh0aW1lKSA9PiB7XG4gICAgICogXHRvc2Muc3RhcnQodGltZSkuc3RvcCh0aW1lICsgMC4xKTtcbiAgICAgKiB9LCBcIjhuXCIsIFwiMW1cIik7XG4gICAgICovXG4gICAgc2NoZWR1bGVSZXBlYXQoY2FsbGJhY2ssIGludGVydmFsLCBzdGFydFRpbWUsIGR1cmF0aW9uID0gSW5maW5pdHkpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0UmVwZWF0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICBkdXJhdGlvbjogbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGR1cmF0aW9uKS50b1RpY2tzKCksXG4gICAgICAgICAgICBpbnRlcnZhbDogbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGludGVydmFsKS50b1RpY2tzKCksXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1RpY2tzKCksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBraWNrIGl0IG9mZiBpZiB0aGUgVHJhbnNwb3J0IGlzIHN0YXJ0ZWRcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByZXR1cm4gdGhpcy5fYWRkRXZlbnQoZXZlbnQsIHRoaXMuX3JlcGVhdGVkRXZlbnRzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYW4gZXZlbnQgdGhhdCB3aWxsIGJlIHJlbW92ZWQgYWZ0ZXIgaXQgaXMgaW52b2tlZC5cbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSBvbmNlLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRoZSBjYWxsYmFjayBzaG91bGQgYmUgaW52b2tlZC5cbiAgICAgKiBAcmV0dXJucyBUaGUgSUQgb2YgdGhlIHNjaGVkdWxlZCBldmVudC5cbiAgICAgKi9cbiAgICBzY2hlZHVsZU9uY2UoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICBvbmNlOiB0cnVlLFxuICAgICAgICAgICAgdGltZTogbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fdGltZWxpbmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhciB0aGUgcGFzc2VkIGluIGV2ZW50IGlkIGZyb20gdGhlIHRpbWVsaW5lXG4gICAgICogQHBhcmFtIGV2ZW50SWQgVGhlIGlkIG9mIHRoZSBldmVudC5cbiAgICAgKi9cbiAgICBjbGVhcihldmVudElkKSB7XG4gICAgICAgIGlmICh0aGlzLl9zY2hlZHVsZWRFdmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnRJZCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnRJZC50b1N0cmluZygpXTtcbiAgICAgICAgICAgIGl0ZW0udGltZWxpbmUucmVtb3ZlKGl0ZW0uZXZlbnQpO1xuICAgICAgICAgICAgaXRlbS5ldmVudC5kaXNwb3NlKCk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fc2NoZWR1bGVkRXZlbnRzW2V2ZW50SWQudG9TdHJpbmcoKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhbiBldmVudCB0byB0aGUgY29ycmVjdCB0aW1lbGluZS4gS2VlcCB0cmFjayBvZiB0aGVcbiAgICAgKiB0aW1lbGluZSBpdCB3YXMgYWRkZWQgdG8uXG4gICAgICogQHJldHVybnMgdGhlIGV2ZW50IGlkIHdoaWNoIHdhcyBqdXN0IGFkZGVkXG4gICAgICovXG4gICAgX2FkZEV2ZW50KGV2ZW50LCB0aW1lbGluZSkge1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnQuaWQudG9TdHJpbmcoKV0gPSB7XG4gICAgICAgICAgICBldmVudCxcbiAgICAgICAgICAgIHRpbWVsaW5lLFxuICAgICAgICB9O1xuICAgICAgICB0aW1lbGluZS5hZGQoZXZlbnQpO1xuICAgICAgICByZXR1cm4gZXZlbnQuaWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBzY2hlZHVsZWQgZXZlbnRzIGZyb20gdGhlIHRpbWVsaW5lIGFmdGVyXG4gICAgICogdGhlIGdpdmVuIHRpbWUuIFJlcGVhdGVkIGV2ZW50cyB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBpZiB0aGVpciBzdGFydFRpbWUgaXMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gYWZ0ZXIgQ2xlYXIgYWxsIGV2ZW50cyBhZnRlciB0aGlzIHRpbWUuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyID0gMCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZEFmdGVyID0gdGhpcy50b1RpY2tzKGFmdGVyKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZm9yRWFjaEZyb20oY29tcHV0ZWRBZnRlciwgZXZlbnQgPT4gdGhpcy5jbGVhcihldmVudC5pZCkpO1xuICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cy5mb3JFYWNoRnJvbShjb21wdXRlZEFmdGVyLCBldmVudCA9PiB0aGlzLmNsZWFyKGV2ZW50LmlkKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNUQVJUL1NUT1AvUEFVU0VcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBCaW5kIHN0YXJ0L3N0b3AvcGF1c2UgZXZlbnRzIGZyb20gdGhlIGNsb2NrIGFuZCBlbWl0IHRoZW0uXG4gICAgICovXG4gICAgX2JpbmRDbG9ja0V2ZW50cygpIHtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdGFydFwiLCAodGltZSwgb2Zmc2V0KSA9PiB7XG4gICAgICAgICAgICBvZmZzZXQgPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIG9mZnNldCkudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCB0aW1lLCBvZmZzZXQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdG9wXCIsICh0aW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIHRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJwYXVzZVwiLCAodGltZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwicGF1c2VcIiwgdGltZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiLCBvciBcInBhdXNlZFwiXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB3aGVuIHRoZSB0cmFuc3BvcnQgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSB0aW1lbGluZSBvZmZzZXQgdG8gc3RhcnQgdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHN0YXJ0IHRoZSB0cmFuc3BvcnQgaW4gb25lIHNlY29uZCBzdGFydGluZyBhdCBiZWdpbm5pbmcgb2YgdGhlIDV0aCBtZWFzdXJlLlxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KFwiKzFcIiwgXCI0OjA6MFwiKTtcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgbGV0IG9mZnNldFRpY2tzO1xuICAgICAgICBpZiAoaXNEZWZpbmVkKG9mZnNldCkpIHtcbiAgICAgICAgICAgIG9mZnNldFRpY2tzID0gdGhpcy50b1RpY2tzKG9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc3RhcnQgdGhlIGNsb2NrXG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0YXJ0KHRpbWUsIG9mZnNldFRpY2tzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgdHJhbnNwb3J0IHNob3VsZCBzdG9wLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RvcCgpO1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgcGF1c2UodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5wYXVzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRvZ2dsZSB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgdHJhbnNwb3J0LiBJZiBpdCBpc1xuICAgICAqIHN0YXJ0ZWQsIGl0IHdpbGwgc3RvcCBpdCwgb3RoZXJ3aXNlIGl0IHdpbGwgc3RhcnQgdGhlIFRyYW5zcG9ydC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgdG9nZ2xlKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fY2xvY2suZ2V0U3RhdGVBdFRpbWUodGltZSkgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0KHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNFVFRFUlMvR0VUVEVSU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIHNpZ25hdHVyZSBhcyBqdXN0IHRoZSBudW1lcmF0b3Igb3ZlciA0LlxuICAgICAqIEZvciBleGFtcGxlIDQvNCB3b3VsZCBiZSBqdXN0IDQgYW5kIDYvOCB3b3VsZCBiZSAzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gY29tbW9uIHRpbWVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC50aW1lU2lnbmF0dXJlID0gNDtcbiAgICAgKiAvLyA3LzhcbiAgICAgKiBUb25lLlRyYW5zcG9ydC50aW1lU2lnbmF0dXJlID0gWzcsIDhdO1xuICAgICAqIC8vIHRoaXMgd2lsbCBiZSByZWR1Y2VkIHRvIGEgc2luZ2xlIG51bWJlclxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmU7IC8vIHJldHVybnMgMy41XG4gICAgICovXG4gICAgZ2V0IHRpbWVTaWduYXR1cmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lU2lnbmF0dXJlO1xuICAgIH1cbiAgICBzZXQgdGltZVNpZ25hdHVyZSh0aW1lU2lnKSB7XG4gICAgICAgIGlmIChpc0FycmF5KHRpbWVTaWcpKSB7XG4gICAgICAgICAgICB0aW1lU2lnID0gKHRpbWVTaWdbMF0gLyB0aW1lU2lnWzFdKSAqIDQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGltZVNpZ25hdHVyZSA9IHRpbWVTaWc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIFRyYW5zcG9ydC5sb29wID0gdHJ1ZSwgdGhpcyBpcyB0aGUgc3RhcnRpbmcgcG9zaXRpb24gb2YgdGhlIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wU3RhcnQsIFwiaVwiKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChzdGFydFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhzdGFydFBvc2l0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgVHJhbnNwb3J0Lmxvb3AgPSB0cnVlLCB0aGlzIGlzIHRoZSBlbmRpbmcgcG9zaXRpb24gb2YgdGhlIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcEVuZCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChlbmRQb3NpdGlvbikge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGVuZFBvc2l0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHRyYW5zcG9ydCBsb29wcyBvciBub3QuXG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wLmdldCh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wLnNldChsb29wLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsb29wIHN0YXJ0IGFuZCBzdG9wIGF0IHRoZSBzYW1lIHRpbWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBsb29wIG92ZXIgdGhlIGZpcnN0IG1lYXN1cmVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zZXRMb29wUG9pbnRzKDAsIFwiMW1cIik7XG4gICAgICogVG9uZS5UcmFuc3BvcnQubG9vcCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0TG9vcFBvaW50cyhzdGFydFBvc2l0aW9uLCBlbmRQb3NpdGlvbikge1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IHN0YXJ0UG9zaXRpb247XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IGVuZFBvc2l0aW9uO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN3aW5nIHZhbHVlLiBCZXR3ZWVuIDAtMSB3aGVyZSAxIGVxdWFsIHRvIHRoZSBub3RlICsgaGFsZiB0aGUgc3ViZGl2aXNpb24uXG4gICAgICovXG4gICAgZ2V0IHN3aW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3dpbmdBbW91bnQ7XG4gICAgfVxuICAgIHNldCBzd2luZyhhbW91bnQpIHtcbiAgICAgICAgLy8gc2NhbGUgdGhlIHZhbHVlcyB0byBhIG5vcm1hbCByYW5nZVxuICAgICAgICB0aGlzLl9zd2luZ0Ftb3VudCA9IGFtb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBzdWJkaXZpc2lvbiB3aGljaCB0aGUgc3dpbmcgd2lsbCBiZSBhcHBsaWVkIHRvLlxuICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGFuIDh0aCBub3RlLiBWYWx1ZSBtdXN0IGJlIGxlc3NcbiAgICAgKiB0aGFuIGEgcXVhcnRlciBub3RlLlxuICAgICAqL1xuICAgIGdldCBzd2luZ1N1YmRpdmlzaW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9zd2luZ1RpY2tzKS50b05vdGF0aW9uKCk7XG4gICAgfVxuICAgIHNldCBzd2luZ1N1YmRpdmlzaW9uKHN1YmRpdmlzaW9uKSB7XG4gICAgICAgIHRoaXMuX3N3aW5nVGlja3MgPSB0aGlzLnRvVGlja3Moc3ViZGl2aXNpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgcG9zaXRpb24gaW4gQmFyczpCZWF0czpTaXh0ZWVudGhzLlxuICAgICAqIFNldHRpbmcgdGhlIHZhbHVlIHdpbGwganVtcCB0byB0aGF0IHBvc2l0aW9uIHJpZ2h0IGF3YXkuXG4gICAgICovXG4gICAgZ2V0IHBvc2l0aW9uKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKG5vdyk7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKS50b0JhcnNCZWF0c1NpeHRlZW50aHMoKTtcbiAgICB9XG4gICAgc2V0IHBvc2l0aW9uKHByb2dyZXNzKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHByb2dyZXNzKTtcbiAgICAgICAgdGhpcy50aWNrcyA9IHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgcG9zaXRpb24gaW4gc2Vjb25kc1xuICAgICAqIFNldHRpbmcgdGhlIHZhbHVlIHdpbGwganVtcCB0byB0aGF0IHBvc2l0aW9uIHJpZ2h0IGF3YXkuXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5zZWNvbmRzO1xuICAgIH1cbiAgICBzZXQgc2Vjb25kcyhzKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5LnRpbWVUb1RpY2tzKHMsIG5vdyk7XG4gICAgICAgIHRoaXMudGlja3MgPSB0aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIFRyYW5zcG9ydCdzIGxvb3AgcG9zaXRpb24gYXMgYSBub3JtYWxpemVkIHZhbHVlLiBBbHdheXNcbiAgICAgKiByZXR1cm5zIDAgaWYgdGhlIHRyYW5zcG9ydCBpZiBsb29wIGlzIG5vdCB0cnVlLlxuICAgICAqL1xuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgICAgIHJldHVybiAodGlja3MgLSB0aGlzLl9sb29wU3RhcnQpIC8gKHRoaXMuX2xvb3BFbmQgLSB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRyYW5zcG9ydHMgY3VycmVudCB0aWNrIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIGdldCB0aWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLnRpY2tzO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICBpZiAodGhpcy5fY2xvY2sudGlja3MgIT09IHQpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICAvLyBzdG9wIGV2ZXJ5dGhpbmcgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnRcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgICAgICAgICAvLyBzY2hlZHVsZSB0byBzdGFydCBvbiB0aGUgbmV4dCB0aWNrLCAjNTczXG4gICAgICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVGljayA9IHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5nZXREdXJhdGlvbk9mVGlja3MoTWF0aC5jZWlsKHRpY2tzKSAtIHRpY2tzLCBub3cpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbWUgPSBub3cgKyByZW1haW5pbmdUaWNrO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgdGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodCwgdGltZSk7XG4gICAgICAgICAgICAgICAgLy8gcmVzdGFydCBpdCB3aXRoIHRoZSBuZXcgdGltZVxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIHRpbWUsIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xvY2suc2V0VGlja3NBdFRpbWUodCwgbm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIHRpY2sgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCh0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZSh0aW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZWxhcHNlZCBzZWNvbmRzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqIEByZXR1cm4gIFRoZSBudW1iZXIgb2YgZWxhcHNlZCBzZWNvbmRzXG4gICAgICovXG4gICAgZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5nZXRTZWNvbmRzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdWxzZXMgUGVyIFF1YXJ0ZXIgbm90ZS4gVGhpcyBpcyB0aGUgc21hbGxlc3QgcmVzb2x1dGlvblxuICAgICAqIHRoZSBUcmFuc3BvcnQgdGltaW5nIHN1cHBvcnRzLiBUaGlzIHNob3VsZCBiZSBzZXQgb25jZVxuICAgICAqIG9uIGluaXRpYWxpemF0aW9uIGFuZCBub3Qgc2V0IGFnYWluLiBDaGFuZ2luZyB0aGlzIHZhbHVlXG4gICAgICogYWZ0ZXIgb3RoZXIgb2JqZWN0cyBoYXZlIGJlZW4gY3JlYXRlZCBjYW4gY2F1c2UgcHJvYmxlbXMuXG4gICAgICovXG4gICAgZ2V0IFBQUSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgUFBRKHBwcSkge1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kubXVsdGlwbGllciA9IHBwcTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTWU5DSU5HXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdGltZSBhbGlnbmVkIHRvIHRoZSBuZXh0IHN1YmRpdmlzaW9uXG4gICAgICogb2YgdGhlIFRyYW5zcG9ydC4gSWYgdGhlIFRyYW5zcG9ydCBpcyBub3Qgc3RhcnRlZCxcbiAgICAgKiBpdCB3aWxsIHJldHVybiAwLlxuICAgICAqIE5vdGU6IHRoaXMgd2lsbCBub3Qgd29yayBwcmVjaXNlbHkgZHVyaW5nIHRlbXBvIHJhbXBzLlxuICAgICAqIEBwYXJhbSAgc3ViZGl2aXNpb24gIFRoZSBzdWJkaXZpc2lvbiB0byBxdWFudGl6ZSB0b1xuICAgICAqIEByZXR1cm4gIFRoZSBjb250ZXh0IHRpbWUgb2YgdGhlIG5leHQgc3ViZGl2aXNpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyB0aGUgdHJhbnNwb3J0IG11c3QgYmUgc3RhcnRlZCwgb3RoZXJ3aXNlIHJldHVybnMgMFxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICogVG9uZS5UcmFuc3BvcnQubmV4dFN1YmRpdmlzaW9uKFwiNG5cIik7XG4gICAgICovXG4gICAgbmV4dFN1YmRpdmlzaW9uKHN1YmRpdmlzaW9uKSB7XG4gICAgICAgIHN1YmRpdmlzaW9uID0gdGhpcy50b1RpY2tzKHN1YmRpdmlzaW9uKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAvLyBpZiB0aGUgdHJhbnNwb3J0J3Mgbm90IHN0YXJ0ZWQsIHJldHVybiAwXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICAvLyB0aGUgcmVtYWluZGVyIG9mIHRoZSBjdXJyZW50IHRpY2tzIGFuZCB0aGUgc3ViZGl2aXNpb25cbiAgICAgICAgICAgIGNvbnN0IHRyYW5zcG9ydFBvcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ1RpY2tzID0gc3ViZGl2aXNpb24gLSB0cmFuc3BvcnRQb3MgJSBzdWJkaXZpc2lvbjtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5uZXh0VGlja1RpbWUocmVtYWluaW5nVGlja3MsIG5vdyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQXR0YWNoZXMgdGhlIHNpZ25hbCB0byB0aGUgdGVtcG8gY29udHJvbCBzaWduYWwgc28gdGhhdFxuICAgICAqIGFueSBjaGFuZ2VzIGluIHRoZSB0ZW1wbyB3aWxsIGNoYW5nZSB0aGUgc2lnbmFsIGluIHRoZSBzYW1lXG4gICAgICogcmF0aW8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc2lnbmFsXG4gICAgICogQHBhcmFtIHJhdGlvIE9wdGlvbmFsbHkgcGFzcyBpbiB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHNpZ25hbHMuXG4gICAgICogXHRcdFx0T3RoZXJ3aXNlIGl0IHdpbGwgYmUgY29tcHV0ZWQgYmFzZWQgb24gdGhlaXIgY3VycmVudCB2YWx1ZXMuXG4gICAgICovXG4gICAgc3luY1NpZ25hbChzaWduYWwsIHJhdGlvKSB7XG4gICAgICAgIGlmICghcmF0aW8pIHtcbiAgICAgICAgICAgIC8vIGdldCB0aGUgc3luYyByYXRpb1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGlmIChzaWduYWwuZ2V0VmFsdWVBdFRpbWUobm93KSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJwbSA9IHRoaXMuYnBtLmdldFZhbHVlQXRUaW1lKG5vdyk7XG4gICAgICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRGcmVxID0gMSAvICg2MCAvIGJwbSAvIHRoaXMuUFBRKTtcbiAgICAgICAgICAgICAgICByYXRpbyA9IHNpZ25hbC5nZXRWYWx1ZUF0VGltZShub3cpIC8gY29tcHV0ZWRGcmVxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmF0aW8gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJhdGlvU2lnbmFsID0gbmV3IEdhaW4ocmF0aW8pO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuYnBtLmNvbm5lY3QocmF0aW9TaWduYWwpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJhdGlvU2lnbmFsLmNvbm5lY3Qoc2lnbmFsLl9wYXJhbSk7XG4gICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMucHVzaCh7XG4gICAgICAgICAgICBpbml0aWFsOiBzaWduYWwudmFsdWUsXG4gICAgICAgICAgICByYXRpbzogcmF0aW9TaWduYWwsXG4gICAgICAgICAgICBzaWduYWwsXG4gICAgICAgIH0pO1xuICAgICAgICBzaWduYWwudmFsdWUgPSAwO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jcyBhIHByZXZpb3VzbHkgc3luY2VkIHNpZ25hbCBmcm9tIHRoZSB0cmFuc3BvcnQncyBjb250cm9sLlxuICAgICAqIFNlZSBUcmFuc3BvcnQuc3luY1NpZ25hbC5cbiAgICAgKi9cbiAgICB1bnN5bmNTaWduYWwoc2lnbmFsKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLl9zeW5jZWRTaWduYWxzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCBzeW5jZWRTaWduYWwgPSB0aGlzLl9zeW5jZWRTaWduYWxzW2ldO1xuICAgICAgICAgICAgaWYgKHN5bmNlZFNpZ25hbC5zaWduYWwgPT09IHNpZ25hbCkge1xuICAgICAgICAgICAgICAgIHN5bmNlZFNpZ25hbC5yYXRpby5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgc3luY2VkU2lnbmFsLnNpZ25hbC52YWx1ZSA9IHN5bmNlZFNpZ25hbC5pbml0aWFsO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNlZFNpZ25hbHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmRpc3Bvc2UoKTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgXCJicG1cIik7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5FbWl0dGVyLm1peGluKFRyYW5zcG9ydCk7XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LnRyYW5zcG9ydCA9IG5ldyBUcmFuc3BvcnQoeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LnRyYW5zcG9ydC5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydC5qcy5tYXAiLCJpbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgXCIuLi9jb3JlL2NvbnRleHQvRGVzdGluYXRpb25cIjtcbmltcG9ydCBcIi4uL2NvcmUvY2xvY2svVHJhbnNwb3J0XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc1VuZGVmIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0Q29udGV4dFJ1bm5pbmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBHVCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBzb3VyY2VzLlxuICogc3RhcnQvc3RvcCBvZiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LlxuICpcbiAqIGBgYFxuICogLy8gTXVsdGlwbGUgc3RhdGUgY2hhbmdlIGV2ZW50cyBjYW4gYmUgY2hhaW5lZCB0b2dldGhlcixcbiAqIC8vIGJ1dCBtdXN0IGJlIHNldCBpbiB0aGUgY29ycmVjdCBvcmRlciBhbmQgd2l0aCBhc2NlbmRpbmcgdGltZXNcbiAqIC8vIE9LXG4gKiBzdGF0ZS5zdGFydCgpLnN0b3AoXCIrMC4yXCIpO1xuICogLy8gT0tcbiAqIHN0YXRlLnN0YXJ0KCkuc3RvcChcIiswLjJcIikuc3RhcnQoXCIrMC40XCIpLnN0b3AoXCIrMC43XCIpXG4gKiAvLyBCQURcbiAqIHN0YXRlLnN0b3AoXCIrMC4yXCIpLnN0YXJ0KCk7XG4gKiAvLyBCQURcbiAqIHN0YXRlLnN0YXJ0KFwiKzAuM1wiKS5zdG9wKFwiKzAuMlwiKTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgU291cmNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNvdXJjZXMgaGF2ZSBubyBpbnB1dHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBzY2hlZHVsZWQgc3RhdGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzeW5jZWQgYHN0YXJ0YCBjYWxsYmFjayBmdW5jdGlvbiBmcm9tIHRoZSB0cmFuc3BvcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiBhbGwgb2YgdGhlIHNjaGVkdWxlZCBldmVudCBpZHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZCA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogUGxhY2Vob2xkZXIgZnVuY3Rpb25zIGZvciBzeW5jaW5nL3Vuc3luY2luZyB0byB0cmFuc3BvcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0ID0gbm9PcDtcbiAgICAgICAgdGhpcy5fc3luY2VkU3RvcCA9IG5vT3A7XG4gICAgICAgIHRoaXMuX3N0YXRlLm1lbW9yeSA9IDEwMDtcbiAgICAgICAgdGhpcy5fc3RhdGUuaW5jcmVhc2luZyA9IHRydWU7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtdXRlOiBvcHRpb25zLm11dGUsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5vbnN0b3AgPSBvcHRpb25zLm9uc3RvcDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgb25zdG9wOiBub09wLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiIG9yIFwic3RvcHBlZFwiLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvYWhudG9uZV9jMy5tcDNcIiwgKCkgPT4ge1xuICAgICAqIFx0cGxheWVyLnN0YXJ0KCk7XG4gICAgICogXHRjb25zb2xlLmxvZyhwbGF5ZXIuc3RhdGUpO1xuICAgICAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwic3RvcHBlZFwiO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiAvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiBvc2MubXV0ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVuc3VyZSB0aGF0IHRoZSBzY2hlZHVsZWQgdGltZSBpcyBub3QgYmVmb3JlIHRoZSBjdXJyZW50IHRpbWUuXG4gICAgICogU2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIHNjaGVkdWxlZCB1bnN5bmNlZC5cbiAgICAgKi9cbiAgICBfY2xhbXBUb0N1cnJlbnRUaW1lKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5tYXgodGltZSwgdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIGF0IHRoZSBzcGVjaWZpZWQgdGltZS4gSWYgbm8gdGltZSBpcyBnaXZlbixcbiAgICAgKiBzdGFydCB0aGUgc291cmNlIG5vdy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgc291cmNlIHNob3VsZCBiZSBzdGFydGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc291cmNlID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzb3VyY2Uuc3RhcnQoXCIrMC41XCIpOyAvLyBzdGFydHMgdGhlIHNvdXJjZSAwLjUgc2Vjb25kcyBmcm9tIG5vd1xuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgbGV0IGNvbXB1dGVkVGltZSA9IGlzVW5kZWYodGltZSkgJiYgdGhpcy5fc3luY2VkID8gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzIDogdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbXB1dGVkVGltZSA9IHRoaXMuX2NsYW1wVG9DdXJyZW50VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICAvLyBpZiBpdCdzIHN0YXJ0ZWQsIHN0b3AgaXQgYW5kIHJlc3RhcnQgaXRcbiAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQgJiYgdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIHRpbWUgc2hvdWxkIGJlIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiB0aGUgcHJldmlvdXMgc3RhcnQgdGltZVxuICAgICAgICAgICAgYXNzZXJ0KEdUKGNvbXB1dGVkVGltZSwgdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSkudGltZSksIFwiU3RhcnQgdGltZSBtdXN0IGJlIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiBwcmV2aW91cyBzdGFydCB0aW1lXCIpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMubG9nKFwicmVzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5yZXN0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIG9mZnNldCB0aW1lIHRvIHRoZSBldmVudFxuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Lm9mZnNldCA9IHRoaXMudG9TZWNvbmRzKGRlZmF1bHRBcmcob2Zmc2V0LCAwKSk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmR1cmF0aW9uID0gZHVyYXRpb24gPyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSh0ID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodCwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWQucHVzaChzY2hlZCk7XG4gICAgICAgICAgICAgICAgLy8gaWYgdGhlIHRyYW5zcG9ydCBpcyBhbHJlYWR5IHN0YXJ0ZWRcbiAgICAgICAgICAgICAgICAvLyBhbmQgdGhlIHRpbWUgaXMgZ3JlYXRlciB0aGFuIHdoZXJlIHRoZSB0cmFuc3BvcnQgaXNcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRTZWNvbmRzQXRUaW1lKHRoaXMuaW1tZWRpYXRlKCkpID4gY29tcHV0ZWRUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0KHRoaXMubm93KCksIHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0Q29udGV4dFJ1bm5pbmcodGhpcy5jb250ZXh0KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydChjb21wdXRlZFRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBzb3VyY2UgYXQgdGhlIHNwZWNpZmllZCB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLFxuICAgICAqIHN0b3AgdGhlIHNvdXJjZSBub3cuXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHNvdXJjZSBzaG91bGQgYmUgc3RvcHBlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc291cmNlLnN0YXJ0KCk7XG4gICAgICogc291cmNlLnN0b3AoXCIrMC41XCIpOyAvLyBzdG9wcyB0aGUgc291cmNlIDAuNSBzZWNvbmRzIGZyb20gbm93XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGxldCBjb21wdXRlZFRpbWUgPSBpc1VuZGVmKHRpbWUpICYmIHRoaXMuX3N5bmNlZCA/IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyA6IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb21wdXRlZFRpbWUgPSB0aGlzLl9jbGFtcFRvQ3VycmVudFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiIHx8IGlzRGVmaW5lZCh0aGlzLl9zdGF0ZS5nZXROZXh0U3RhdGUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSkpKSB7XG4gICAgICAgICAgICB0aGlzLmxvZyhcInN0b3BcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKHRoaXMuX3N0b3AuYmluZCh0aGlzKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWQucHVzaChzY2hlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXN0YXJ0IHRoZSBzb3VyY2UuXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQgc28gdGhhdCBhbGwgc3Vic2VxdWVudFxuICAgICAqIGNhbGxzIHRvIGBzdGFydGAgYW5kIGBzdG9wYCBhcmUgc3luY2VkIHRvIHRoZSBUcmFuc3BvcnRUaW1lXG4gICAgICogaW5zdGVhZCBvZiB0aGUgQXVkaW9Db250ZXh0IHRpbWUuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc3luYyB0aGUgc291cmNlIHNvIHRoYXQgaXQgcGxheXMgYmV0d2VlbiAwIGFuZCAwLjMgb24gdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lXG4gICAgICogb3NjLnN5bmMoKS5zdGFydCgwKS5zdG9wKDAuMyk7XG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICAgICAqIC8vIHNldCBpdCB0byBsb29wIG9uY2UgYSBzZWNvbmRcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wID0gdHJ1ZTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wRW5kID0gMTtcbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0YXJ0ID0gKHRpbWUsIG9mZnNldCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhhdCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXRlRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQob2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gbGlzdGVuIGZvciBzdGFydCBldmVudHMgd2hpY2ggbWF5IG9jY3VyIGluIHRoZSBtaWRkbGUgb2YgdGhlIHN5bmMnZWQgdGltZVxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGVFdmVudCAmJiBzdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBzdGF0ZUV2ZW50LnRpbWUgIT09IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBvZmZzZXRcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0T2Zmc2V0ID0gb2Zmc2V0IC0gdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50LmR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50LmR1cmF0aW9uKSAtIHN0YXJ0T2Zmc2V0O1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC5vZmZzZXQpICsgc3RhcnRPZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWRTdG9wID0gdGltZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuZ2V0U2Vjb25kc0F0VGltZShNYXRoLm1heCh0aW1lIC0gdGhpcy5zYW1wbGVUaW1lLCAwKSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHNlY29uZHMpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcImxvb3BTdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwic3RvcFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJsb29wRW5kXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIHNvdXJjZSB0byB0aGUgVHJhbnNwb3J0LiBTZWUgU291cmNlLnN5bmNcbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RvcFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcImxvb3BFbmRcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwibG9vcFN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gY2xlYXIgYWxsIG9mIHRoZSBzY2hlZHVsZWQgaWRzXG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZC5mb3JFYWNoKGlkID0+IHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoaWQpKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCgwKTtcbiAgICAgICAgLy8gc3RvcCBpdCBhbHNvXG4gICAgICAgIHRoaXMuX3N0b3AoMCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub25zdG9wID0gbm9PcDtcbiAgICAgICAgdGhpcy51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Tb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBPbmVTaG90U291cmNlIH0gZnJvbSBcIi4uL09uZVNob3RTb3VyY2VcIjtcbmltcG9ydCB7IEVRLCBHVEUsIExUIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgQnVmZmVyU291cmNlTm9kZS5cbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVCdWZmZXJTb3VyY2UgZXh0ZW5kcyBPbmVTaG90U291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUJ1ZmZlclNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVCdWZmZXJTb3VyY2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zb3VyY2UgPSB0aGlzLmNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fc291cmNlXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGluZGljYXRvcnMgaWYgdGhlIHNvdXJjZSBoYXMgc3RhcnRlZC9zdG9wcGVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zb3VyY2VTdGFydGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX3NvdXJjZVN0b3BwZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVCdWZmZXJTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NvdXJjZSwgdGhpcy5fZ2Fpbk5vZGUpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uub25lbmRlZCA9ICgpID0+IHRoaXMuX3N0b3BTb3VyY2UoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwbGF5YmFja1JhdGUgb2YgdGhlIGJ1ZmZlclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3NvdXJjZS5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucGxheWJhY2tSYXRlLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc2V0IHNvbWUgdmFsdWVzIGluaXRpYWxseVxuICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcihvcHRpb25zLnVybCwgb3B0aW9ucy5vbmxvYWQsIG9wdGlvbnMub25lcnJvcik7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMucHVzaCh0aGlzLl9zb3VyY2UpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdXJsOiBuZXcgVG9uZUF1ZGlvQnVmZmVyKCksXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVJbiB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVJbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVJbjtcbiAgICB9XG4gICAgc2V0IGZhZGVJbih0KSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlT3V0IHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZU91dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG4gICAgfVxuICAgIHNldCBmYWRlT3V0KHQpIHtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJ2ZSBhcHBsaWVkIHRvIHRoZSBmYWRlcywgZWl0aGVyIFwibGluZWFyXCIgb3IgXCJleHBvbmVudGlhbFwiXG4gICAgICovXG4gICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VydmU7XG4gICAgfVxuICAgIHNldCBjdXJ2ZSh0KSB7XG4gICAgICAgIHRoaXMuX2N1cnZlID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGJ1ZmZlclxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbiwgaXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqIEBwYXJhbSAgZ2FpbiAgVGhlIGdhaW4gdG8gcGxheSB0aGUgYnVmZmVyIGJhY2sgYXQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbiwgZ2FpbiA9IDEpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuYnVmZmVyLmxvYWRlZCwgXCJidWZmZXIgaXMgZWl0aGVyIG5vdCBzZXQgb3Igbm90IGxvYWRlZFwiKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIGFwcGx5IHRoZSBnYWluIGVudmVsb3BlXG4gICAgICAgIHRoaXMuX3N0YXJ0R2Fpbihjb21wdXRlZFRpbWUsIGdhaW4pO1xuICAgICAgICAvLyBpZiBpdCdzIGEgbG9vcCB0aGUgZGVmYXVsdCBvZmZzZXQgaXMgdGhlIGxvb3BzdGFydCBwb2ludFxuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgdGhpcy5sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG9mZnNldCBpcyAwXG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBvZmZzZXQgaXMgbm90IGxlc3MgdGhhbiAwXG4gICAgICAgIGxldCBjb21wdXRlZE9mZnNldCA9IE1hdGgubWF4KHRoaXMudG9TZWNvbmRzKG9mZnNldCksIDApO1xuICAgICAgICAvLyBzdGFydCB0aGUgYnVmZmVyIHNvdXJjZVxuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICAvLyBtb2RpZnkgdGhlIG9mZnNldCBpZiBpdCdzIGdyZWF0ZXIgdGhhbiB0aGUgbG9vcCB0aW1lXG4gICAgICAgICAgICBjb25zdCBsb29wRW5kID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wRW5kKSB8fCB0aGlzLmJ1ZmZlci5kdXJhdGlvbjtcbiAgICAgICAgICAgIGNvbnN0IGxvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKHRoaXMubG9vcFN0YXJ0KTtcbiAgICAgICAgICAgIGNvbnN0IGxvb3BEdXJhdGlvbiA9IGxvb3BFbmQgLSBsb29wU3RhcnQ7XG4gICAgICAgICAgICAvLyBtb3ZlIHRoZSBvZmZzZXQgYmFja1xuICAgICAgICAgICAgaWYgKEdURShjb21wdXRlZE9mZnNldCwgbG9vcEVuZCkpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlZE9mZnNldCA9ICgoY29tcHV0ZWRPZmZzZXQgLSBsb29wU3RhcnQpICUgbG9vcER1cmF0aW9uKSArIGxvb3BTdGFydDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHdoZW4gdGhlIG9mZnNldCBpcyB2ZXJ5IGNsb3NlIHRvIHRoZSBkdXJhdGlvbiwgc2V0IGl0IHRvIDBcbiAgICAgICAgICAgIGlmIChFUShjb21wdXRlZE9mZnNldCwgdGhpcy5idWZmZXIuZHVyYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZWRPZmZzZXQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHRoaXMuYnVmZmVyLmxvYWRlZCB3b3VsZCBoYXZlIHJldHVybiBmYWxzZSBpZiB0aGUgQXVkaW9CdWZmZXIgd2FzIHVuZGVmaW5lZFxuICAgICAgICB0aGlzLl9zb3VyY2UuYnVmZmVyID0gdGhpcy5idWZmZXIuZ2V0KCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wRW5kID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wRW5kKSB8fCB0aGlzLmJ1ZmZlci5kdXJhdGlvbjtcbiAgICAgICAgaWYgKExUKGNvbXB1dGVkT2Zmc2V0LCB0aGlzLmJ1ZmZlci5kdXJhdGlvbikpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSwgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGEgZHVyYXRpb24gaXMgZ2l2ZW4sIHNjaGVkdWxlIGEgc3RvcFxuICAgICAgICBpZiAoaXNEZWZpbmVkKGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgbGV0IGNvbXB1dGVkRHVyID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIGl0J3MgbmV2ZXIgbmVnYXRpdmVcbiAgICAgICAgICAgIGNvbXB1dGVkRHVyID0gTWF0aC5tYXgoY29tcHV0ZWREdXIsIDApO1xuICAgICAgICAgICAgdGhpcy5zdG9wKGNvbXB1dGVkVGltZSArIGNvbXB1dGVkRHVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3N0b3BTb3VyY2UodGltZSkge1xuICAgICAgICBpZiAoIXRoaXMuX3NvdXJjZVN0b3BwZWQgJiYgdGhpcy5fc291cmNlU3RhcnRlZCkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlU3RvcHBlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RvcCh0aGlzLnRvU2Vjb25kcyh0aW1lKSk7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIHN0YXJ0IGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wU3RhcnQ7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyhsb29wU3RhcnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgZW5kIGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2UubG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQobG9vcEVuZCkge1xuICAgICAgICB0aGlzLl9zb3VyY2UubG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKGxvb3BFbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gYnVmZmVyIGJlbG9uZ2luZyB0byB0aGUgcGxheWVyLlxuICAgICAqL1xuICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBzaG91bGQgbG9vcCBvbmNlIGl0J3Mgb3Zlci5cbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wID0gbG9vcDtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZVN0YXJ0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsU3RvcCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc291cmNlLm9uZW5kZWQgPSBudWxsO1xuICAgICAgICB0aGlzLl9zb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVCdWZmZXJTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZVwiO1xuLyoqXG4gKiBOb2lzZSBpcyBhIG5vaXNlIGdlbmVyYXRvci4gSXQgdXNlcyBsb29wZWQgbm9pc2UgYnVmZmVycyB0byBzYXZlIG9uIHBlcmZvcm1hbmNlLlxuICogTm9pc2Ugc3VwcG9ydHMgdGhlIG5vaXNlIHR5cGVzOiBcInBpbmtcIiwgXCJ3aGl0ZVwiLCBhbmQgXCJicm93blwiLiBSZWFkIG1vcmUgYWJvdXRcbiAqIGNvbG9ycyBvZiBub2lzZSBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db2xvcnNfb2Zfbm9pc2UpLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBpbml0aWFsaXplIHRoZSBub2lzZSBhbmQgc3RhcnRcbiAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoXCJwaW5rXCIpLnN0YXJ0KCk7XG4gKiAvLyBtYWtlIGFuIGF1dG9maWx0ZXIgdG8gc2hhcGUgdGhlIG5vaXNlXG4gKiBjb25zdCBhdXRvRmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcih7XG4gKiBcdGZyZXF1ZW5jeTogXCI4blwiLFxuICogXHRiYXNlRnJlcXVlbmN5OiAyMDAsXG4gKiBcdG9jdGF2ZXM6IDhcbiAqIH0pLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gY29ubmVjdCB0aGUgbm9pc2VcbiAqIG5vaXNlLmNvbm5lY3QoYXV0b0ZpbHRlcik7XG4gKiAvLyBzdGFydCB0aGUgYXV0b2ZpbHRlciBMRk9cbiAqIGF1dG9GaWx0ZXIuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE5vaXNlIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTm9pc2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTm9pc2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByaXZhdGUgcmVmZXJlbmNlIHRvIHRoZSBzb3VyY2VcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHR5cGU6IFwid2hpdGVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBub2lzZS4gQ2FuIGJlIFwid2hpdGVcIiwgXCJicm93blwiLCBvciBcInBpbmtcIi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBub2lzZS50eXBlID0gXCJicm93blwiO1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBhc3NlcnQodHlwZSBpbiBfbm9pc2VCdWZmZXJzLCBcIk5vaXNlOiBpbnZhbGlkIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlICE9PSB0eXBlKSB7XG4gICAgICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgcGxheWluZywgc3RvcCBhbmQgcmVzdGFydCBpdFxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKG5vdyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQobm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbm9pc2UuIEFmZmVjdHNcbiAgICAgKiB0aGUgXCJmcmVxdWVuY3lcIiBvZiB0aGUgbm9pc2UuXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5wbGF5YmFja1JhdGUudmFsdWUgPSByYXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IF9ub2lzZUJ1ZmZlcnNbdGhpcy5fdHlwZV07XG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgIHVybDogYnVmZmVyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZmFkZUluOiB0aGlzLl9mYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9mYWRlT3V0LFxuICAgICAgICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgICAgICAgIG9uZW5kZWQ6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiB0aGlzLl9wbGF5YmFja1JhdGUsXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQodGhpcy50b1NlY29uZHModGltZSksIE1hdGgucmFuZG9tKCkgKiAoYnVmZmVyLmR1cmF0aW9uIC0gMC4wMDEpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogaW50ZXJuYWwgc3RvcCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVJbiB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVJbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVJbjtcbiAgICB9XG4gICAgc2V0IGZhZGVJbih0aW1lKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IHRpbWU7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5mYWRlSW4gPSB0aGlzLl9mYWRlSW47XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlT3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZU91dDtcbiAgICB9XG4gICAgc2V0IGZhZGVPdXQodGltZSkge1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gdGltZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmZhZGVPdXQgPSB0aGlzLl9mYWRlT3V0O1xuICAgICAgICB9XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgLy8gVE9ETyBjb3VsZCBiZSBvcHRpbWl6ZWQgYnkgY2FuY2VsbGluZyB0aGUgYnVmZmVyIHNvdXJjZSAnc3RvcCdcbiAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUSEUgTk9JU0UgQlVGRkVSU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTm9pc2UgYnVmZmVyIHN0YXRzXG5jb25zdCBCVUZGRVJfTEVOR1RIID0gNDQxMDAgKiA1O1xuY29uc3QgTlVNX0NIQU5ORUxTID0gMjtcbi8qKlxuICogQ2FjaGUgdGhlIG5vaXNlIGJ1ZmZlcnNcbiAqL1xuY29uc3QgX25vaXNlQ2FjaGUgPSB7XG4gICAgYnJvd246IG51bGwsXG4gICAgcGluazogbnVsbCxcbiAgICB3aGl0ZTogbnVsbCxcbn07XG4vKipcbiAqIFRoZSBub2lzZSBhcnJheXMuIEdlbmVyYXRlZCBvbiBpbml0aWFsaXphdGlvbi5cbiAqIGJvcnJvd2VkIGhlYXZpbHkgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vemFjaGFyeWRlbnRvbi9ub2lzZS5qc1xuICogKGMpIDIwMTMgWmFjaCBEZW50b24gKE1JVClcbiAqL1xuY29uc3QgX25vaXNlQnVmZmVycyA9IHtcbiAgICBnZXQgYnJvd24oKSB7XG4gICAgICAgIGlmICghX25vaXNlQ2FjaGUuYnJvd24pIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RPdXQgPSAwLjA7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBCVUZGRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2hpdGUgPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gPSAobGFzdE91dCArICgwLjAyICogd2hpdGUpKSAvIDEuMDI7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RPdXQgPSBjaGFubmVsW2ldO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldICo9IDMuNTsgLy8gKHJvdWdobHkpIGNvbXBlbnNhdGUgZm9yIGdhaW5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfbm9pc2VDYWNoZS5icm93biA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUuYnJvd247XG4gICAgfSxcbiAgICBnZXQgcGluaygpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS5waW5rKSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGNoYW5uZWxOdW0gPSAwOyBjaGFubmVsTnVtIDwgTlVNX0NIQU5ORUxTOyBjaGFubmVsTnVtKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IEZsb2F0MzJBcnJheShCVUZGRVJfTEVOR1RIKTtcbiAgICAgICAgICAgICAgICBidWZmZXJbY2hhbm5lbE51bV0gPSBjaGFubmVsO1xuICAgICAgICAgICAgICAgIGxldCBiMCwgYjEsIGIyLCBiMywgYjQsIGI1LCBiNjtcbiAgICAgICAgICAgICAgICBiMCA9IGIxID0gYjIgPSBiMyA9IGI0ID0gYjUgPSBiNiA9IDAuMDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGl0ZSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgYjAgPSAwLjk5ODg2ICogYjAgKyB3aGl0ZSAqIDAuMDU1NTE3OTtcbiAgICAgICAgICAgICAgICAgICAgYjEgPSAwLjk5MzMyICogYjEgKyB3aGl0ZSAqIDAuMDc1MDc1OTtcbiAgICAgICAgICAgICAgICAgICAgYjIgPSAwLjk2OTAwICogYjIgKyB3aGl0ZSAqIDAuMTUzODUyMDtcbiAgICAgICAgICAgICAgICAgICAgYjMgPSAwLjg2NjUwICogYjMgKyB3aGl0ZSAqIDAuMzEwNDg1NjtcbiAgICAgICAgICAgICAgICAgICAgYjQgPSAwLjU1MDAwICogYjQgKyB3aGl0ZSAqIDAuNTMyOTUyMjtcbiAgICAgICAgICAgICAgICAgICAgYjUgPSAtMC43NjE2ICogYjUgLSB3aGl0ZSAqIDAuMDE2ODk4MDtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IGIwICsgYjEgKyBiMiArIGIzICsgYjQgKyBiNSArIGI2ICsgd2hpdGUgKiAwLjUzNjI7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gKj0gMC4xMTsgLy8gKHJvdWdobHkpIGNvbXBlbnNhdGUgZm9yIGdhaW5cbiAgICAgICAgICAgICAgICAgICAgYjYgPSB3aGl0ZSAqIDAuMTE1OTI2O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLnBpbmsgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKCkuZnJvbUFycmF5KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9ub2lzZUNhY2hlLnBpbms7XG4gICAgfSxcbiAgICBnZXQgd2hpdGUoKSB7XG4gICAgICAgIGlmICghX25vaXNlQ2FjaGUud2hpdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBCVUZGRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfbm9pc2VDYWNoZS53aGl0ZSA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUud2hpdGU7XG4gICAgfSxcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ob2lzZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGNvbm5lY3QsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFVzZXJNZWRpYSB1c2VzIE1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEgdG8gb3BlbiB1cCBhbmQgZXh0ZXJuYWwgbWljcm9waG9uZSBvciBhdWRpbyBpbnB1dC5cbiAqIENoZWNrIFtNZWRpYURldmljZXMgQVBJIFN1cHBvcnRdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9NZWRpYURldmljZXMvZ2V0VXNlck1lZGlhKVxuICogdG8gc2VlIHdoaWNoIGJyb3dzZXJzIGFyZSBzdXBwb3J0ZWQuIEFjY2VzcyB0byBhbiBleHRlcm5hbCBpbnB1dFxuICogaXMgbGltaXRlZCB0byBzZWN1cmUgKEhUVFBTKSBjb25uZWN0aW9ucy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXRlciA9IG5ldyBUb25lLk1ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKS5jb25uZWN0KG1ldGVyKTtcbiAqIG1pYy5vcGVuKCkudGhlbigoKSA9PiB7XG4gKiBcdC8vIHByb21pc2UgcmVzb2x2ZXMgd2hlbiBpbnB1dCBpcyBhdmFpbGFibGVcbiAqIFx0Y29uc29sZS5sb2coXCJtaWMgb3BlblwiKTtcbiAqIFx0Ly8gcHJpbnQgdGhlIGluY29taW5nIG1pYyBsZXZlbHMgaW4gZGVjaWJlbHNcbiAqIFx0c2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2cobWV0ZXIuZ2V0VmFsdWUoKSksIDEwMCk7XG4gKiB9KS5jYXRjaChlID0+IHtcbiAqIFx0Ly8gcHJvbWlzZSBpcyByZWplY3RlZCB3aGVuIHRoZSB1c2VyIGRvZXNuJ3QgaGF2ZSBvciBhbGxvdyBtaWMgYWNjZXNzXG4gKiBcdGNvbnNvbGUubG9nKFwibWljIG5vdCBvcGVuXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2VyTWVkaWEgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVXNlck1lZGlhLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVXNlck1lZGlhXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhVc2VyTWVkaWEuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBPcGVuIHRoZSBtZWRpYSBzdHJlYW0uIElmIGEgc3RyaW5nIGlzIHBhc3NlZCBpbiwgaXQgaXMgYXNzdW1lZFxuICAgICAqIHRvIGJlIHRoZSBsYWJlbCBvciBpZCBvZiB0aGUgc3RyZWFtLCBpZiBhIG51bWJlciBpcyBwYXNzZWQgaW4sXG4gICAgICogaXQgaXMgdGhlIGlucHV0IG51bWJlciBvZiB0aGUgc3RyZWFtLlxuICAgICAqIEBwYXJhbSAgbGFiZWxPcklkIFRoZSBsYWJlbCBvciBpZCBvZiB0aGUgYXVkaW8gaW5wdXQgbWVkaWEgZGV2aWNlLlxuICAgICAqICAgICAgICAgICAgICAgICAgIFdpdGggbm8gYXJndW1lbnQsIHRoZSBkZWZhdWx0IHN0cmVhbSBpcyBvcGVuZWQuXG4gICAgICogQHJldHVybiBUaGUgcHJvbWlzZSBpcyByZXNvbHZlZCB3aGVuIHRoZSBzdHJlYW0gaXMgb3Blbi5cbiAgICAgKi9cbiAgICBvcGVuKGxhYmVsT3JJZCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KFVzZXJNZWRpYS5zdXBwb3J0ZWQsIFwiVXNlck1lZGlhIGlzIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgICAgICAgICAvLyBjbG9zZSB0aGUgcHJldmlvdXMgc3RyZWFtXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBkZXZpY2VzID0geWllbGQgVXNlck1lZGlhLmVudW1lcmF0ZURldmljZXMoKTtcbiAgICAgICAgICAgIGlmIChpc051bWJlcihsYWJlbE9ySWQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlc1tsYWJlbE9ySWRdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlcy5maW5kKChkZXZpY2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRldmljZS5sYWJlbCA9PT0gbGFiZWxPcklkIHx8IGRldmljZS5kZXZpY2VJZCA9PT0gbGFiZWxPcklkO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8vIGRpZG4ndCBmaW5kIGEgbWF0Y2hpbmcgZGV2aWNlXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9kZXZpY2UgJiYgZGV2aWNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2RldmljZSA9IGRldmljZXNbMF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFzc2VydChpc0RlZmluZWQodGhpcy5fZGV2aWNlKSwgYE5vIG1hdGNoaW5nIGRldmljZSAke2xhYmVsT3JJZH1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGRvIGdldFVzZXJNZWRpYVxuICAgICAgICAgICAgY29uc3QgY29uc3RyYWludHMgPSB7XG4gICAgICAgICAgICAgICAgYXVkaW86IHtcbiAgICAgICAgICAgICAgICAgICAgZWNob0NhbmNlbGxhdGlvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHNhbXBsZVJhdGU6IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlLFxuICAgICAgICAgICAgICAgICAgICBub2lzZVN1cHByZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbW96Tm9pc2VTdXBwcmVzc2lvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgY29uc3RyYWludHMuYXVkaW8uZGV2aWNlSWQgPSB0aGlzLl9kZXZpY2UuZGV2aWNlSWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBzdHJlYW0gPSB5aWVsZCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYShjb25zdHJhaW50cyk7XG4gICAgICAgICAgICAvLyBzdGFydCBhIG5ldyBzb3VyY2Ugb25seSBpZiB0aGUgcHJldmlvdXMgb25lIGlzIGNsb3NlZFxuICAgICAgICAgICAgaWYgKCF0aGlzLl9zdHJlYW0pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdHJlYW0gPSBzdHJlYW07XG4gICAgICAgICAgICAgICAgLy8gV3JhcCBhIE1lZGlhU3RyZWFtU291cmNlTm9kZSBhcm91bmQgdGhlIGxpdmUgaW5wdXQgc3RyZWFtLlxuICAgICAgICAgICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtTm9kZSA9IHRoaXMuY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgICAgICAgICAgICAgIC8vIENvbm5lY3QgdGhlIE1lZGlhU3RyZWFtU291cmNlTm9kZSB0byBhIGdhdGUgZ2FpbiBub2RlXG4gICAgICAgICAgICAgICAgY29ubmVjdChtZWRpYVN0cmVhbU5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbSA9IG1lZGlhU3RyZWFtTm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIG1lZGlhIHN0cmVhbVxuICAgICAqL1xuICAgIGNsb3NlKCkge1xuICAgICAgICBpZiAodGhpcy5fc3RyZWFtICYmIHRoaXMuX21lZGlhU3RyZWFtKSB7XG4gICAgICAgICAgICB0aGlzLl9zdHJlYW0uZ2V0QXVkaW9UcmFja3MoKS5mb3JFYWNoKCh0cmFjaykgPT4ge1xuICAgICAgICAgICAgICAgIHRyYWNrLnN0b3AoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBvbGQgbWVkaWEgc3RyZWFtXG4gICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB0aGlzLl9tZWRpYVN0cmVhbSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9kZXZpY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aXRoIHRoZSBsaXN0IG9mIGF1ZGlvIGlucHV0IGRldmljZXMgYXZhaWxhYmxlLlxuICAgICAqIEByZXR1cm4gVGhlIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCB3aXRoIHRoZSBkZXZpY2VzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlVzZXJNZWRpYS5lbnVtZXJhdGVEZXZpY2VzKCkudGhlbigoZGV2aWNlcykgPT4ge1xuICAgICAqIFx0Ly8gcHJpbnQgdGhlIGRldmljZSBsYWJlbHNcbiAgICAgKiBcdGNvbnNvbGUubG9nKGRldmljZXMubWFwKGRldmljZSA9PiBkZXZpY2UubGFiZWwpKTtcbiAgICAgKiB9KTtcbiAgICAgKi9cbiAgICBzdGF0aWMgZW51bWVyYXRlRGV2aWNlcygpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGFsbERldmljZXMgPSB5aWVsZCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKTtcbiAgICAgICAgICAgIHJldHVybiBhbGxEZXZpY2VzLmZpbHRlcihkZXZpY2UgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXZpY2Uua2luZCA9PT0gXCJhdWRpb2lucHV0XCI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIFwic3RhcnRlZFwiIHdoZW4gdGhlIG1pY3JvcGhvbmUgaXMgb3BlblxuICAgICAqIGFuZCBcInN0b3BwZWRcIiB3aGVuIHRoZSBtaWMgaXMgY2xvc2VkLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0cmVhbSAmJiB0aGlzLl9zdHJlYW0uYWN0aXZlID8gXCJzdGFydGVkXCIgOiBcInN0b3BwZWRcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBpZGVudGlmaWVyIGZvciB0aGUgcmVwcmVzZW50ZWQgZGV2aWNlIHRoYXQgaXNcbiAgICAgKiBwZXJzaXN0ZWQgYWNyb3NzIHNlc3Npb25zLiBJdCBpcyB1bi1ndWVzc2FibGUgYnkgb3RoZXIgYXBwbGljYXRpb25zIGFuZFxuICAgICAqIHVuaXF1ZSB0byB0aGUgb3JpZ2luIG9mIHRoZSBjYWxsaW5nIGFwcGxpY2F0aW9uLiBJdCBpcyByZXNldCB3aGVuIHRoZVxuICAgICAqIHVzZXIgY2xlYXJzIGNvb2tpZXMgKGZvciBQcml2YXRlIEJyb3dzaW5nLCBhIGRpZmZlcmVudCBpZGVudGlmaWVyIGlzXG4gICAgICogdXNlZCB0aGF0IGlzIG5vdCBwZXJzaXN0ZWQgYWNyb3NzIHNlc3Npb25zKS4gUmV0dXJucyB1bmRlZmluZWQgd2hlbiB0aGVcbiAgICAgKiBkZXZpY2UgaXMgbm90IG9wZW4uXG4gICAgICovXG4gICAgZ2V0IGRldmljZUlkKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmRldmljZUlkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgZ3JvdXAgaWRlbnRpZmllci4gVHdvIGRldmljZXMgaGF2ZSB0aGVcbiAgICAgKiBzYW1lIGdyb3VwIGlkZW50aWZpZXIgaWYgdGhleSBiZWxvbmcgdG8gdGhlIHNhbWUgcGh5c2ljYWwgZGV2aWNlLlxuICAgICAqIFJldHVybnMgbnVsbCAgd2hlbiB0aGUgZGV2aWNlIGlzIG5vdCBvcGVuLlxuICAgICAqL1xuICAgIGdldCBncm91cElkKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmdyb3VwSWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBsYWJlbCBkZXNjcmliaW5nIHRoaXMgZGV2aWNlIChmb3IgZXhhbXBsZSBcIkJ1aWx0LWluIE1pY3JvcGhvbmVcIikuXG4gICAgICogUmV0dXJucyB1bmRlZmluZWQgd2hlbiB0aGUgZGV2aWNlIGlzIG5vdCBvcGVuIG9yIGxhYmVsIGlzIG5vdCBhdmFpbGFibGVcbiAgICAgKiBiZWNhdXNlIG9mIHBlcm1pc3Npb25zLlxuICAgICAqL1xuICAgIGdldCBsYWJlbCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldmljZS5sYWJlbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCk7XG4gICAgICogbWljLm9wZW4oKS50aGVuKCgpID0+IHtcbiAgICAgKiBcdC8vIHByb21pc2UgcmVzb2x2ZXMgd2hlbiBpbnB1dCBpcyBhdmFpbGFibGVcbiAgICAgKiB9KTtcbiAgICAgKiAvLyBtdXRlIHRoZSBvdXRwdXRcbiAgICAgKiBtaWMubXV0ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBnZXRVc2VyTWVkaWEgaXMgc3VwcG9ydGVkIGJ5IHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc3VwcG9ydGVkKCkge1xuICAgICAgICByZXR1cm4gaXNEZWZpbmVkKG5hdmlnYXRvci5tZWRpYURldmljZXMpICYmXG4gICAgICAgICAgICBpc0RlZmluZWQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVVzZXJNZWRpYS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuLyoqXG4gKiBSZW5kZXIgYSBzZWdtZW50IG9mIHRoZSBvc2NpbGxhdG9yIHRvIGFuIG9mZmxpbmUgY29udGV4dCBhbmQgcmV0dXJuIHRoZSByZXN1bHRzIGFzIGFuIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVdhdmVmb3JtKGluc3RhbmNlLCBsZW5ndGgpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICBjb25zdCBkdXJhdGlvbiA9IGxlbmd0aCAvIGluc3RhbmNlLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dCgxLCBkdXJhdGlvbiwgaW5zdGFuY2UuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgY2xvbmUgPSBuZXcgaW5zdGFuY2UuY29uc3RydWN0b3IoT2JqZWN0LmFzc2lnbihpbnN0YW5jZS5nZXQoKSwge1xuICAgICAgICAgICAgLy8gc2hvdWxkIGRvIDIgaXRlcmF0aW9uc1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAyIC8gZHVyYXRpb24sXG4gICAgICAgICAgICAvLyB6ZXJvIG91dCB0aGUgZGV0dW5lXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBjb250ZXh0XG4gICAgICAgIH0pKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgIGNsb25lLnN0YXJ0KDApO1xuICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICByZXR1cm4gYnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgIH0pO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T3NjaWxsYXRvckludGVyZmFjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lU2hvdFNvdXJjZSB9IGZyb20gXCIuLi9PbmVTaG90U291cmNlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgZmlyZS1hbmQtZm9yZ2V0IE9zY2lsbGF0b3JOb2RlLlxuICogQWRkcyB0aGUgYWJpbGl0eSB0byByZXNjaGVkdWxlIHRoZSBzdG9wIG1ldGhvZC5cbiAqICoqKltbT3NjaWxsYXRvcl1dIGlzIGJldHRlciBmb3IgbW9zdCB1c2UtY2FzZXMqKipcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVPc2NpbGxhdG9yTm9kZSBleHRlbmRzIE9uZVNob3RTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lT3NjaWxsYXRvck5vZGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3NjaWxsYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fb3NjaWxsYXRvcl07XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lT3NjaWxsYXRvck5vZGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLCB0aGlzLl9nYWluTm9kZSk7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fb3NjaWxsYXRvci5kZXR1bmUsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPbmVTaG90U291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgb3NjaWxsYXRvciBub2RlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0R2Fpbihjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0cyBhbiBhcmJpdHJhcnkgY3VzdG9tIHBlcmlvZGljIHdhdmVmb3JtIGdpdmVuIGEgUGVyaW9kaWNXYXZlLlxuICAgICAqIEBwYXJhbSAgcGVyaW9kaWNXYXZlIFBlcmlvZGljV2F2ZSBzaG91bGQgYmUgY3JlYXRlZCB3aXRoIGNvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlXG4gICAgICovXG4gICAgc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZS4gRWl0aGVyICdzaW5lJywgJ3Nhd3Rvb3RoJywgJ3NxdWFyZScsIG9yICd0cmlhbmdsZSdcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lT3NjaWxsYXRvck5vZGUuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBkZWVwRXF1YWxzLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVPc2NpbGxhdG9yTm9kZSB9IGZyb20gXCIuL1RvbmVPc2NpbGxhdG9yTm9kZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBPc2NpbGxhdG9yIHN1cHBvcnRzIGEgbnVtYmVyIG9mIGZlYXR1cmVzIGluY2x1ZGluZ1xuICogcGhhc2Ugcm90YXRpb24sIG11bHRpcGxlIG9zY2lsbGF0b3IgdHlwZXMgKHNlZSBPc2NpbGxhdG9yLnR5cGUpLFxuICogYW5kIFRyYW5zcG9ydCBzeW5jaW5nIChzZWUgT3NjaWxsYXRvci5zeW5jRnJlcXVlbmN5KS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gbWFrZSBhbmQgc3RhcnQgYSA0NDBoeiBzaW5lIHRvbmVcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNpbmVcIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbWFpbiBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbnVsbDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmcmVxdWVuY3lcIik7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZXR1bmVcIik7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxzID0gb3B0aW9ucy5wYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gb3B0aW9ucy5wYXJ0aWFsQ291bnQ7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIGlmIChvcHRpb25zLnBhcnRpYWxDb3VudCAmJiBvcHRpb25zLnR5cGUgIT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0aGlzLmJhc2VUeXBlICsgb3B0aW9ucy5wYXJ0aWFsQ291bnQudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBoYXNlID0gb3B0aW9ucy5waGFzZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICBwYXJ0aWFsQ291bnQ6IDAsXG4gICAgICAgICAgICBwYXJ0aWFsczogW10sXG4gICAgICAgICAgICBwaGFzZTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gbmV3IG9zY2lsbGF0b3Igd2l0aCBwcmV2aW91cyB2YWx1ZXNcbiAgICAgICAgY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lT3NjaWxsYXRvck5vZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb25lbmRlZDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gb3NjaWxsYXRvcjtcbiAgICAgICAgaWYgKHRoaXMuX3dhdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb25uZWN0IHRoZSBjb250cm9sIHNpZ25hbCB0byB0aGUgb3NjaWxsYXRvciBmcmVxdWVuY3kgJiBkZXR1bmVcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5kZXR1bmUpO1xuICAgICAgICAvLyBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcikge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzdGFydCB0aGUgb3NjaWxsYXRvci4gRG9lcyBub3Qgc3RvcCB0aGUgb3NjaWxsYXRvciwgYnV0IGluc3RlYWRcbiAgICAgKiBqdXN0IGNhbmNlbHMgYW55IHNjaGVkdWxlZCAnc3RvcCcgZnJvbSBiZWluZyBpbnZva2VkLlxuICAgICAqL1xuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwicmVzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcikge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jYW5jZWxTdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzaWduYWwgdG8gdGhlIFRyYW5zcG9ydCdzIGJwbS4gQW55IGNoYW5nZXMgdG8gdGhlIHRyYW5zcG9ydHMgYnBtLFxuICAgICAqIHdpbGwgYWxzbyBhZmZlY3QgdGhlIG9zY2lsbGF0b3JzIGZyZXF1ZW5jeS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBvc2MuZnJlcXVlbmN5LnZhbHVlID0gNDQwO1xuICAgICAqIC8vIHRoZSByYXRpbyBiZXR3ZWVuIHRoZSBicG0gYW5kIHRoZSBmcmVxdWVuY3kgd2lsbCBiZSBtYWludGFpbmVkXG4gICAgICogb3NjLnN5bmNGcmVxdWVuY3koKTtcbiAgICAgKiAvLyBkb3VibGUgdGhlIHRlbXBvXG4gICAgICogVG9uZS5UcmFuc3BvcnQuYnBtLnZhbHVlICo9IDI7XG4gICAgICogLy8gdGhlIGZyZXF1ZW5jeSBvZiB0aGUgb3NjaWxsYXRvciBpcyBkb3VibGVkIHRvIDg4MFxuICAgICAqL1xuICAgIHN5bmNGcmVxdWVuY3koKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIG9zY2lsbGF0b3IncyBmcmVxdWVuY3kgZnJvbSB0aGUgVHJhbnNwb3J0LlxuICAgICAqIFNlZSBPc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3lcbiAgICAgKi9cbiAgICB1bnN5bmNGcmVxdWVuY3koKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQudW5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIGNhY2hlZCBwZXJpb2RpYyB3YXZlLiBBdm9pZHMgaGF2aW5nIHRvIHJlY29tcHV0ZVxuICAgICAqIHRoZSBvc2NpbGxhdG9yIHZhbHVlcyB3aGVuIHRoZXkgaGF2ZSBhbHJlYWR5IGJlZW4gY29tcHV0ZWRcbiAgICAgKiB3aXRoIHRoZSBzYW1lIHZhbHVlcy5cbiAgICAgKi9cbiAgICBfZ2V0Q2FjaGVkUGVyaW9kaWNXYXZlKCkge1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgY29uc3Qgb3NjUHJvcHMgPSBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5maW5kKGRlc2NyaXB0aW9uID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb24ucGhhc2UgPT09IHRoaXMuX3BoYXNlICYmXG4gICAgICAgICAgICAgICAgICAgIGRlZXBFcXVhbHMoZGVzY3JpcHRpb24ucGFydGlhbHMsIHRoaXMuX3BhcnRpYWxzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIG9zY1Byb3BzO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgb3NjUHJvcHMgPSBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5maW5kKGRlc2NyaXB0aW9uID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzY3JpcHRpb24udHlwZSA9PT0gdGhpcy5fdHlwZSAmJlxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbi5waGFzZSA9PT0gdGhpcy5fcGhhc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IG9zY1Byb3BzID8gb3NjUHJvcHMucGFydGlhbENvdW50IDogdGhpcy5fcGFydGlhbENvdW50O1xuICAgICAgICAgICAgcmV0dXJuIG9zY1Byb3BzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgY29uc3QgaXNCYXNpY1R5cGUgPSBbXCJzaW5lXCIsIFwic3F1YXJlXCIsIFwic2F3dG9vdGhcIiwgXCJ0cmlhbmdsZVwiXS5pbmRleE9mKHR5cGUpICE9PSAtMTtcbiAgICAgICAgaWYgKHRoaXMuX3BoYXNlID09PSAwICYmIGlzQmFzaWNUeXBlKSB7XG4gICAgICAgICAgICB0aGlzLl93YXZlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gMDtcbiAgICAgICAgICAgIC8vIGp1c3QgZ28gd2l0aCB0aGUgYmFzaWMgYXBwcm9hY2hcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgLy8gYWxyZWFkeSB0ZXN0ZWQgdGhhdCBpdCdzIGEgYmFzaWMgdHlwZVxuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBmaXJzdCBjaGVjayBpZiB0aGUgdmFsdWUgaXMgY2FjaGVkXG4gICAgICAgICAgICBjb25zdCBjYWNoZSA9IHRoaXMuX2dldENhY2hlZFBlcmlvZGljV2F2ZSgpO1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChjYWNoZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHBhcnRpYWxzLCB3YXZlIH0gPSBjYWNoZTtcbiAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gd2F2ZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtyZWFsLCBpbWFnXSA9IHRoaXMuX2dldFJlYWxJbWFnaW5hcnkodHlwZSwgdGhpcy5fcGhhc2UpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBlcmlvZGljV2F2ZSA9IHRoaXMuY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2F2ZSA9IHBlcmlvZGljV2F2ZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZSh0aGlzLl93YXZlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gc2V0IHRoZSBjYWNoZVxuICAgICAgICAgICAgICAgIE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpbWFnLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQ6IHRoaXMuX3BhcnRpYWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGlhbHM6IHRoaXMuX3BhcnRpYWxzLFxuICAgICAgICAgICAgICAgICAgICBwaGFzZTogdGhpcy5fcGhhc2UsXG4gICAgICAgICAgICAgICAgICAgIHJlYWwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHRoaXMuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgIHdhdmU6IHRoaXMuX3dhdmUsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmxlbmd0aCA+IDEwMCkge1xuICAgICAgICAgICAgICAgICAgICBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlLnJlcGxhY2UodGhpcy5wYXJ0aWFsQ291bnQudG9TdHJpbmcoKSwgXCJcIik7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICBpZiAodGhpcy5wYXJ0aWFsQ291bnQgJiYgdGhpcy5fdHlwZSAhPT0gXCJjdXN0b21cIiAmJiBiYXNlVHlwZSAhPT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGUgKyB0aGlzLnBhcnRpYWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocCkge1xuICAgICAgICBhc3NlcnRSYW5nZShwLCAwKTtcbiAgICAgICAgbGV0IHR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICBjb25zdCBwYXJ0aWFsID0gL14oc2luZXx0cmlhbmdsZXxzcXVhcmV8c2F3dG9vdGgpKFxcZCspJC8uZXhlYyh0aGlzLl90eXBlKTtcbiAgICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgICAgIHR5cGUgPSBwYXJ0aWFsWzFdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl90eXBlICE9PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBpZiAocCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlICsgcC50b1N0cmluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gZXh0ZW5kIG9yIHNob3J0ZW4gdGhlIHBhcnRpYWxzIGFycmF5XG4gICAgICAgICAgICBjb25zdCBmdWxsUGFydGlhbHMgPSBuZXcgRmxvYXQzMkFycmF5KHApO1xuICAgICAgICAgICAgLy8gY29weSBvdmVyIHRoZSBwYXJ0aWFscyBhcnJheVxuICAgICAgICAgICAgdGhpcy5fcGFydGlhbHMuZm9yRWFjaCgodiwgaSkgPT4gZnVsbFBhcnRpYWxzW2ldID0gdik7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IEFycmF5LmZyb20oZnVsbFBhcnRpYWxzKTtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcmVhbCBhbmQgaW1hZ2luYXJ5IGNvbXBvbmVudHMgYmFzZWRcbiAgICAgKiBvbiB0aGUgb3NjaWxsYXRvciB0eXBlLlxuICAgICAqIEByZXR1cm5zIFtyZWFsOiBGbG9hdDMyQXJyYXksIGltYWdpbmFyeTogRmxvYXQzMkFycmF5XVxuICAgICAqL1xuICAgIF9nZXRSZWFsSW1hZ2luYXJ5KHR5cGUsIHBoYXNlKSB7XG4gICAgICAgIGNvbnN0IGZmdFNpemUgPSA0MDk2O1xuICAgICAgICBsZXQgcGVyaW9kaWNXYXZlU2l6ZSA9IGZmdFNpemUgLyAyO1xuICAgICAgICBjb25zdCByZWFsID0gbmV3IEZsb2F0MzJBcnJheShwZXJpb2RpY1dhdmVTaXplKTtcbiAgICAgICAgY29uc3QgaW1hZyA9IG5ldyBGbG9hdDMyQXJyYXkocGVyaW9kaWNXYXZlU2l6ZSk7XG4gICAgICAgIGxldCBwYXJ0aWFsQ291bnQgPSAxO1xuICAgICAgICBpZiAodHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoICsgMTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aDtcbiAgICAgICAgICAgIHBlcmlvZGljV2F2ZVNpemUgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICAvLyBpZiB0aGUgcGFydGlhbCBjb3VudCBpcyAwLCBkb24ndCBib3RoZXIgZG9pbmcgYW55IGNvbXB1dGF0aW9uXG4gICAgICAgICAgICBpZiAodGhpcy5fcGFydGlhbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtyZWFsLCBpbWFnXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWwgPSAvXihzaW5lfHRyaWFuZ2xlfHNxdWFyZXxzYXd0b290aCkoXFxkKykkLy5leGVjKHR5cGUpO1xuICAgICAgICAgICAgaWYgKHBhcnRpYWwpIHtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSBwYXJzZUludChwYXJ0aWFsWzJdLCAxMCkgKyAxO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHBhcnNlSW50KHBhcnRpYWxbMl0sIDEwKTtcbiAgICAgICAgICAgICAgICB0eXBlID0gcGFydGlhbFsxXTtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSBNYXRoLm1heChwYXJ0aWFsQ291bnQsIDIpO1xuICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZVNpemUgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBuID0gMTsgbiA8IHBlcmlvZGljV2F2ZVNpemU7ICsrbikge1xuICAgICAgICAgICAgY29uc3QgcGlGYWN0b3IgPSAyIC8gKG4gKiBNYXRoLlBJKTtcbiAgICAgICAgICAgIGxldCBiO1xuICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNpbmVcIjpcbiAgICAgICAgICAgICAgICAgICAgYiA9IChuIDw9IHBhcnRpYWxDb3VudCkgPyAxIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNxdWFyZVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gKG4gJiAxKSA/IDIgKiBwaUZhY3RvciA6IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzYXd0b290aFwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gcGlGYWN0b3IgKiAoKG4gJiAxKSA/IDEgOiAtMSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJ0cmlhbmdsZVwiOlxuICAgICAgICAgICAgICAgICAgICBpZiAobiAmIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGIgPSAyICogKHBpRmFjdG9yICogcGlGYWN0b3IpICogKCgoKG4gLSAxKSA+PiAxKSAmIDEpID8gLTEgOiAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGIgPSAwO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgICAgICAgICAgICAgICAgYiA9IHRoaXMuX3BhcnRpYWxzW24gLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9zY2lsbGF0b3I6IGludmFsaWQgdHlwZTogXCIgKyB0eXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmVhbFtuXSA9IC1iICogTWF0aC5zaW4ocGhhc2UgKiBuKTtcbiAgICAgICAgICAgICAgICBpbWFnW25dID0gYiAqIE1hdGguY29zKHBoYXNlICogbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWFsW25dID0gMDtcbiAgICAgICAgICAgICAgICBpbWFnW25dID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW3JlYWwsIGltYWddO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb21wdXRlIHRoZSBpbnZlcnNlIEZGVCBmb3IgYSBnaXZlbiBwaGFzZS5cbiAgICAgKi9cbiAgICBfaW52ZXJzZUZGVChyZWFsLCBpbWFnLCBwaGFzZSkge1xuICAgICAgICBsZXQgc3VtID0gMDtcbiAgICAgICAgY29uc3QgbGVuID0gcmVhbC5sZW5ndGg7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHN1bSArPSByZWFsW2ldICogTWF0aC5jb3MoaSAqIHBoYXNlKSArIGltYWdbaV0gKiBNYXRoLnNpbihpICogcGhhc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdW07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIG9zY2lsbGF0b3Igd2hlbiBzdG9wcGVkLlxuICAgICAqIEUuZy4gYSBcInNpbmVcIiBvc2NpbGxhdG9yIHdpdGggcGhhc2UgPSA5MCB3b3VsZCByZXR1cm4gYW4gaW5pdGlhbCB2YWx1ZSBvZiAtMS5cbiAgICAgKi9cbiAgICBnZXRJbml0aWFsVmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IFtyZWFsLCBpbWFnXSA9IHRoaXMuX2dldFJlYWxJbWFnaW5hcnkodGhpcy5fdHlwZSwgMCk7XG4gICAgICAgIGxldCBtYXhWYWx1ZSA9IDA7XG4gICAgICAgIGNvbnN0IHR3b1BpID0gTWF0aC5QSSAqIDI7XG4gICAgICAgIGNvbnN0IHRlc3RQb3NpdGlvbnMgPSAzMjtcbiAgICAgICAgLy8gY2hlY2sgZm9yIHBlYWtzIGluIDE2IHBsYWNlc1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlc3RQb3NpdGlvbnM7IGkrKykge1xuICAgICAgICAgICAgbWF4VmFsdWUgPSBNYXRoLm1heCh0aGlzLl9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIChpIC8gdGVzdFBvc2l0aW9ucykgKiB0d29QaSksIG1heFZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2xhbXAoLXRoaXMuX2ludmVyc2VGRlQocmVhbCwgaW1hZywgdGhpcy5fcGhhc2UpIC8gbWF4VmFsdWUsIC0xLCAxKTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydGlhbHMuc2xpY2UoMCwgdGhpcy5wYXJ0aWFsQ291bnQpO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImN1c3RvbVwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BoYXNlICogKDE4MCAvIE1hdGguUEkpO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBwaGFzZSAqIE1hdGguUEkgLyAxODA7XG4gICAgICAgIC8vIHJlc2V0IHRoZSB0eXBlXG4gICAgICAgIHRoaXMudHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3dhdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIENhY2hlIHRoZSBwZXJpb2RpYyB3YXZlcyB0byBhdm9pZCBoYXZpbmcgdG8gcmVkbyBjb21wdXRhdGlvbnNcbiAqL1xuT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUgPSBbXTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBjb25uZWN0U2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG4vKipcbiAqIEEgc2lnbmFsIG9wZXJhdG9yIGhhcyBhbiBpbnB1dCBhbmQgb3V0cHV0IGFuZCBtb2RpZmllcyB0aGUgc2lnbmFsLlxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsT3BlcmF0b3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWxPcGVyYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNvbnRleHRcIl0pKSk7XG4gICAgfVxuICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bSA9IDAsIGlucHV0TnVtID0gMCkge1xuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2lnbmFsT3BlcmF0b3IuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Z1bmN0aW9uIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBXcmFwcyB0aGUgbmF0aXZlIFdlYiBBdWRpbyBBUElcbiAqIFtXYXZlU2hhcGVyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtd2F2ZXNoYXBlcm5vZGUtaW50ZXJmYWNlKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gbXVsdGlwbHkgdGhlIG91dHB1dCBvZiB0aGUgc2lnbmFsIGJ5IDIgdXNpbmcgdGhlIHdhdmVzaGFwZXIncyBmdW5jdGlvblxuICogY29uc3QgdGltZXNUd28gPSBuZXcgVG9uZS5XYXZlU2hhcGVyKCh2YWwpID0+IHZhbCAqIDIsIDIwNDgpLmNvbm5lY3Qob3NjLmZyZXF1ZW5jeSk7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoNDQwKS5jb25uZWN0KHRpbWVzVHdvKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFdhdmVTaGFwZXIgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZVNoYXBlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1hcHBpbmdcIiwgXCJsZW5ndGhcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiV2F2ZVNoYXBlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHdhdmVzaGFwZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2hhcGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCB0byB0aGUgd2F2ZXNoYXBlciBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3NoYXBlcjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgZnJvbSB0aGUgd2F2ZXNoYXBlciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3NoYXBlcjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFdhdmVTaGFwZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtYXBwaW5nXCIsIFwibGVuZ3RoXCJdKTtcbiAgICAgICAgaWYgKGlzQXJyYXkob3B0aW9ucy5tYXBwaW5nKSB8fCBvcHRpb25zLm1hcHBpbmcgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuY3VydmUgPSBGbG9hdDMyQXJyYXkuZnJvbShvcHRpb25zLm1hcHBpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzRnVuY3Rpb24ob3B0aW9ucy5tYXBwaW5nKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRNYXAob3B0aW9ucy5tYXBwaW5nLCBvcHRpb25zLmxlbmd0aCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbGVuZ3RoOiAxMDI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXNlcyBhIG1hcHBpbmcgZnVuY3Rpb24gdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGUgY3VydmUuXG4gICAgICogQHBhcmFtIG1hcHBpbmcgVGhlIGZ1bmN0aW9uIHVzZWQgdG8gZGVmaW5lIHRoZSB2YWx1ZXMuXG4gICAgICogICAgICAgICAgICAgICAgVGhlIG1hcHBpbmcgZnVuY3Rpb24gdGFrZSB0d28gYXJndW1lbnRzOlxuICAgICAqICAgICAgICAgICAgICAgIHRoZSBmaXJzdCBpcyB0aGUgdmFsdWUgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgKiAgICAgICAgICAgICAgICB3aGljaCBnb2VzIGZyb20gLTEgdG8gMSBvdmVyIHRoZSBudW1iZXIgb2YgZWxlbWVudHNcbiAgICAgKiAgICAgICAgICAgICAgICBpbiB0aGUgY3VydmUgYXJyYXkuIFRoZSBzZWNvbmQgYXJndW1lbnQgaXMgdGhlIGFycmF5IHBvc2l0aW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc2hhcGVyID0gbmV3IFRvbmUuV2F2ZVNoYXBlcigpO1xuICAgICAqIC8vIG1hcCB0aGUgaW5wdXQgc2lnbmFsIGZyb20gWy0xLCAxXSB0byBbMCwgMTBdXG4gICAgICogc2hhcGVyLnNldE1hcCgodmFsLCBpbmRleCkgPT4gKHZhbCArIDEpICogNSk7XG4gICAgICovXG4gICAgc2V0TWFwKG1hcHBpbmcsIGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgY29uc3QgYXJyYXkgPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBsZW4gPSBsZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IChpIC8gKGxlbiAtIDEpKSAqIDIgLSAxO1xuICAgICAgICAgICAgYXJyYXlbaV0gPSBtYXBwaW5nKG5vcm1hbGl6ZWQsIGkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY3VydmUgPSBhcnJheTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhcnJheSB0byBzZXQgYXMgdGhlIHdhdmVzaGFwZXIgY3VydmUuIEZvciBsaW5lYXIgY3VydmVzXG4gICAgICogYXJyYXkgbGVuZ3RoIGRvZXMgbm90IG1ha2UgbXVjaCBkaWZmZXJlbmNlLCBidXQgZm9yIGNvbXBsZXggY3VydmVzXG4gICAgICogbG9uZ2VyIGFycmF5cyB3aWxsIHByb3ZpZGUgc21vb3RoZXIgaW50ZXJwb2xhdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaGFwZXIuY3VydmU7XG4gICAgfVxuICAgIHNldCBjdXJ2ZShtYXBwaW5nKSB7XG4gICAgICAgIHRoaXMuX3NoYXBlci5jdXJ2ZSA9IG1hcHBpbmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNwZWNpZmllcyB3aGF0IHR5cGUgb2Ygb3ZlcnNhbXBsaW5nIChpZiBhbnkpIHNob3VsZCBiZSB1c2VkIHdoZW5cbiAgICAgKiBhcHBseWluZyB0aGUgc2hhcGluZyBjdXJ2ZS4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzZXQgb3ZlcnNhbXBsZShvdmVyc2FtcGxpbmcpIHtcbiAgICAgICAgY29uc3QgaXNPdmVyU2FtcGxlVHlwZSA9IFtcIm5vbmVcIiwgXCIyeFwiLCBcIjR4XCJdLnNvbWUoc3RyID0+IHN0ci5pbmNsdWRlcyhvdmVyc2FtcGxpbmcpKTtcbiAgICAgICAgYXNzZXJ0KGlzT3ZlclNhbXBsZVR5cGUsIFwib3ZlcnNhbXBsaW5nIG11c3QgYmUgZWl0aGVyICdub25lJywgJzJ4Jywgb3IgJzR4J1wiKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9V2F2ZVNoYXBlci5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBBdWRpb1RvR2FpbiBjb252ZXJ0cyBhbiBpbnB1dCBpbiBBdWRpb1JhbmdlIFstMSwxXSB0byBOb3JtYWxSYW5nZSBbMCwxXS5cbiAqIFNlZSBbW0dhaW5Ub0F1ZGlvXV0uXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBBdWRpb1RvR2FpbiBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBdWRpb1RvR2FpblwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbm9ybSA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHggPT4gKHggKyAxKSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2UgaW5wdXQgWy0xLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX25vcm07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgR2FpblJhbmdlIG91dHB1dCBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbm9ybTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vcm0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdWRpb1RvR2Fpbi5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuLyoqXG4gKiBNdWx0aXBseSB0d28gaW5jb21pbmcgc2lnbmFscy4gT3IsIGlmIGEgbnVtYmVyIGlzIGdpdmVuIGluIHRoZSBjb25zdHJ1Y3RvcixcbiAqIG11bHRpcGxpZXMgdGhlIGluY29taW5nIHNpZ25hbCBieSB0aGF0IHZhbHVlLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBtdWx0aXBseSB0d28gc2lnbmFsc1xuICogY29uc3QgbXVsdCA9IG5ldyBUb25lLk11bHRpcGx5KCk7XG4gKiBjb25zdCBzaWdBID0gbmV3IFRvbmUuU2lnbmFsKDMpO1xuICogY29uc3Qgc2lnQiA9IG5ldyBUb25lLlNpZ25hbCg0KTtcbiAqIHNpZ0EuY29ubmVjdChtdWx0KTtcbiAqIHNpZ0IuY29ubmVjdChtdWx0LmZhY3Rvcik7XG4gKiAvLyBvdXRwdXQgb2YgbXVsdCBpcyAxMi5cbiAqIEBleGFtcGxlXG4gKiAvLyBtdWx0aXBseSBhIHNpZ25hbCBhbmQgYSBudW1iZXJcbiAqIGNvbnN0IG11bHQgPSBuZXcgVG9uZS5NdWx0aXBseSgxMCk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoMikuY29ubmVjdChtdWx0KTtcbiAqIC8vIHRoZSBvdXRwdXQgb2YgbXVsdCBpcyAyMC5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpcGx5IGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aXBseS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk11bHRpcGx5XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBvdmVycmlkZGVuIG9uIGNvbm5lY3Rpb25cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpcGx5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0ID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZmFjdG9yID0gdGhpcy5fcGFyYW0gPSB0aGlzLl9tdWx0LmdhaW47XG4gICAgICAgIHRoaXMuZmFjdG9yLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMudmFsdWUsIDApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU11bHRpcGx5LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi8uLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG4vKipcbiAqIEFuIGFtcGxpdHVkZSBtb2R1bGF0ZWQgb3NjaWxsYXRvciBub2RlLiBJdCBpcyBpbXBsZW1lbnRlZCB3aXRoXG4gKiB0d28gb3NjaWxsYXRvcnMsIG9uZSB3aGljaCBtb2R1bGF0b3JzIHRoZSBvdGhlcidzIGFtcGxpdHVkZVxuICogdGhyb3VnaCBhIGdhaW4gbm9kZS5cbiAqIGBgYFxuICogICAgKy0tLS0tLS0tLS0tLS0rICAgICAgICstLS0tLS0tLS0tK1xuICogICAgfCBDYXJyaWVyIE9zYyArPi0tLS0tLT4gR2Fpbk5vZGUgfFxuICogICAgKy0tLS0tLS0tLS0tLS0rICAgICAgIHwgICAgICAgICAgKy0tLT5PdXRwdXRcbiAqICAgICAgICAgICAgICAgICAgICAgICstLS0+IGdhaW4gICAgIHxcbiAqICstLS0tLS0tLS0tLS0tLS0rICAgIHwgICArLS0tLS0tLS0tLStcbiAqIHwgTW9kdWxhdG9yIE9zYyArPi0tLStcbiAqICstLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYW1Pc2MgPSBuZXcgVG9uZS5BTU9zY2lsbGF0b3IoMzAsIFwic2luZVwiLCBcInNxdWFyZVwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIH0sIDAuMiwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBBTU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBTU9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbnZlcnQgdGhlIC0xLDEgb3V0cHV0IHRvIDAsMVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlID0gbmV3IEF1ZGlvVG9HYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG5vZGUgd2hlcmUgdGhlIG1vZHVsYXRpb24gaGFwcGVuc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQU1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKTtcbiAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fY2Fycmllci5kZXR1bmU7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy5tb2R1bGF0aW9uVHlwZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uU2NhbGUsIHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNoYWluKHRoaXMuX21vZHVsYXRpb25Ob2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImhhcm1vbmljaXR5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLFxuICAgICAgICAgICAgbW9kdWxhdGlvblR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5yZXN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgY2FycmllciBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuYmFzZVR5cGUgPSBiYXNlVHlwZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25UeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuLyoqXG4gKiBGTU9zY2lsbGF0b3IgaW1wbGVtZW50cyBhIGZyZXF1ZW5jeSBtb2R1bGF0aW9uIHN5bnRoZXNpc1xuICogYGBgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tLS0tLStcbiAqICstLS0tLS0tLS0tLS0tLS0rICAgICAgICArLS0tLS0tLS0tLS0tLSsgICAgIHwgQ2FycmllciBPc2MgfFxuICogfCBNb2R1bGF0b3IgT3NjICs+LS0tLS0tLT4gR2Fpbk5vZGUgICAgfCAgICAgfCAgICAgICAgICAgICArLS0tPk91dHB1dFxuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgICAgIHwgICAgICAgICAgICAgKz4tLS0tPiBmcmVxdWVuY3kgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgKy0tPiBnYWluICAgICAgICB8ICAgICArLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgICAgICAgICAgICAgICB8ICArLS0tLS0tLS0tLS0tLStcbiAqICstLS0tLS0tLS0tLS0tLS0tLSsgICB8XG4gKiB8IG1vZHVsYXRpb25JbmRleCArPi0tK1xuICogKy0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBmbU9zYyA9IG5ldyBUb25lLkZNT3NjaWxsYXRvcih7XG4gKiBcdFx0ZnJlcXVlbmN5OiAyMDAsXG4gKiBcdFx0dHlwZTogXCJzcXVhcmVcIixcbiAqIFx0XHRtb2R1bGF0aW9uVHlwZTogXCJ0cmlhbmdsZVwiLFxuICogXHRcdGhhcm1vbmljaXR5OiAwLjIsXG4gKiBcdFx0bW9kdWxhdGlvbkluZGV4OiAzXG4gKiBcdH0pLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEZNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZNT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG5vZGUgd2hlcmUgdGhlIG1vZHVsYXRpb24gaGFwcGVuc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLm1vZHVsYXRpb25UeXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubW9kdWxhdGlvbkluZGV4LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMuX21vZHVsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLm1vZHVsYXRpb25JbmRleCwgdGhpcy5fbW9kdWxhdGlvbk5vZGUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY29ubmVjdCh0aGlzLl9tb2R1bGF0aW9uTm9kZS5nYWluKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QodGhpcy5fbW9kdWxhdG9yLmRldHVuZSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm1vZHVsYXRpb25JbmRleFwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImhhcm1vbmljaXR5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAyLFxuICAgICAgICAgICAgbW9kdWxhdGlvblR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuYmFzZVR5cGUgPSBiYXNlVHlwZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25UeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbi8qKlxuICogUHVsc2VPc2NpbGxhdG9yIGlzIGFuIG9zY2lsbGF0b3Igd2l0aCBjb250cm9sIG92ZXIgcHVsc2Ugd2lkdGgsXG4gKiBhbHNvIGtub3duIGFzIHRoZSBkdXR5IGN5Y2xlLiBBdCA1MCUgZHV0eSBjeWNsZSAod2lkdGggPSAwKSB0aGUgd2F2ZSBpc1xuICogYSBzcXVhcmUgd2F2ZS5cbiAqIFtSZWFkIG1vcmVdKGh0dHBzOi8vd2lnZ2xld2F2ZS53b3JkcHJlc3MuY29tLzIwMTQvMDgvMTYvcHVsc2Utd2F2ZWZvcm1zLWFuZC1oYXJtb25pY3MvKS5cbiAqIGBgYFxuICogICAgd2lkdGggPSAtMC4yNSAgICAgICAgd2lkdGggPSAwLjAgICAgICAgICAgd2lkdGggPSAwLjI1XG4gKlxuICogICArLS0tLS0rICAgICAgICAgICAgKy0tLS0tLS0rICAgICAgICsgICAgKy0tLS0tLS0rICAgICArLStcbiAqICAgfCAgICAgfCAgICAgICAgICAgIHwgICAgICAgfCAgICAgICB8ICAgICAgICAgICAgfCAgICAgfFxuICogICB8ICAgICB8ICAgICAgICAgICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgICAgICB8ICAgICB8XG4gKiArLSsgICAgICstLS0tLS0tKyAgICArICAgICAgICstLS0tLS0tKyAgICAgICAgICAgICstLS0tLStcbiAqXG4gKlxuICogICAgd2lkdGggPSAtMC41ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAwLjVcbiAqXG4gKiAgICAgKy0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLSsgICArLS0tK1xuICogICAgIHwgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfFxuICogICAgIHwgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfFxuICogKy0tLSsgICArLS0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tK1xuICpcbiAqXG4gKiAgICB3aWR0aCA9IC0wLjc1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNzVcbiAqXG4gKiAgICAgICArLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLSsgKy0tLS0tK1xuICogICAgICAgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHxcbiAqICAgICAgIHwgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB8XG4gKiArLS0tLS0rICstLS0tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IHB1bHNlID0gbmV3IFRvbmUuUHVsc2VPc2NpbGxhdG9yKDUwLCAwLjQpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFB1bHNlT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFB1bHNlT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIndpZHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUHVsc2VPc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBnYXRlIHRoZSB3aWR0aCBhbW91bnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhyZXNob2xkIHRoZSBzaWduYWwgdG8gdHVybiBpdCBpbnRvIGEgc3F1YXJlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aHJlc2ggPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB2YWwgPT4gdmFsIDw9IDAgPyAtMSA6IDEsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwid2lkdGhcIl0pO1xuICAgICAgICB0aGlzLndpZHRoID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJhdWRpb1JhbmdlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy53aWR0aCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBcInRyaWFuZ2xlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX3RyaWFuZ2xlLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl90cmlhbmdsZS5kZXR1bmU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLmNoYWluKHRoaXMuX3RocmVzaCwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLndpZHRoLmNoYWluKHRoaXMuX3dpZHRoR2F0ZSwgdGhpcy5fdGhyZXNoKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wid2lkdGhcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJwdWxzZVwiLFxuICAgICAgICAgICAgd2lkdGg6IDAuMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgdGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuc3RvcCh0aW1lKTtcbiAgICAgICAgLy8gdGhlIHdpZHRoIGlzIHN0aWxsIGNvbm5lY3RlZCB0byB0aGUgb3V0cHV0LlxuICAgICAgICAvLyB0aGF0IG5lZWRzIHRvIGJlIHN0b3BwZWQgYWxzb1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgdGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwaGFzZSBvZiB0aGUgb3NjaWxsYXRvciBpbiBkZWdyZWVzLlxuICAgICAqL1xuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RyaWFuZ2xlLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHVsc2VcIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHVsc2VcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2VUeXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBBbHdheXMgcmV0dXJucyBcInB1bHNlXCIuXG4gICAgICovXG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwdWxzZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBDYW5ub3Qgc2V0IHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGVcbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTm8gcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogKkludGVybmFsIHVzZSogVGhlIGNhcnJpZXIgb3NjaWxsYXRvciB0eXBlIGlzIGZlZCB0aHJvdWdoIHRoZVxuICAgICAqIHdhdmVzaGFwZXIgbm9kZSB0byBjcmVhdGUgdGhlIHB1bHNlLiBVc2luZyBkaWZmZXJlbnQgY2FycmllciBvc2NpbGxhdG9yc1xuICAgICAqIGNoYW5nZXMgb3NjaWxsYXRvcidzIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIHNldCBjYXJyaWVyVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cCBtZXRob2QuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMud2lkdGguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aHJlc2guZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QdWxzZU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AsIHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBGYXRPc2NpbGxhdG9yIGlzIGFuIGFycmF5IG9mIG9zY2lsbGF0b3JzIHdpdGggZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9yc1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZhdE9zYyA9IG5ldyBUb25lLkZhdE9zY2lsbGF0b3IoXCJBYjNcIiwgXCJzYXd0b290aFwiLCA0MCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBGYXRPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRmF0T3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJzcHJlYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGYXRPc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXJyYXkgb2Ygb3NjaWxsYXRvcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInNwcmVhZFwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuX3BoYXNlID0gb3B0aW9ucy5waGFzZTtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBvcHRpb25zLnBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBvcHRpb25zLnBhcnRpYWxDb3VudDtcbiAgICAgICAgLy8gc2V0IHRoZSBjb3VudCBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5jb3VudCA9IG9wdGlvbnMuY291bnQ7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb3VudDogMyxcbiAgICAgICAgICAgIHNwcmVhZDogMjAsXG4gICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KHRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2Muc3RvcCh0aW1lKSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnJlc3RhcnQodGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgYWxsIG9mIHRoZSBvc2NpbGxhdG9yc1xuICAgICAqL1xuICAgIF9mb3JFYWNoKGl0ZXJhdG9yKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yKHRoaXMuX29zY2lsbGF0b3JzW2ldLCBpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnR5cGUgPSB0eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRldHVuZSBzcHJlYWQgYmV0d2VlbiB0aGUgb3NjaWxsYXRvcnMuIElmIFwiY291bnRcIiBpc1xuICAgICAqIHNldCB0byAzIG9zY2lsbGF0b3JzIGFuZCB0aGUgXCJzcHJlYWRcIiBpcyBzZXQgdG8gNDAsXG4gICAgICogdGhlIHRocmVlIG9zY2lsbGF0b3JzIHdvdWxkIGJlIGRldHVuZWQgbGlrZSB0aGlzOiBbLTIwLCAwLCAyMF1cbiAgICAgKiBmb3IgYSB0b3RhbCBkZXR1bmUgc3ByZWFkIG9mIDQwIGNlbnRzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIGZhdE9zYy5zcHJlYWQgPSA3MDtcbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3ByZWFkO1xuICAgIH1cbiAgICBzZXQgc3ByZWFkKHNwcmVhZCkge1xuICAgICAgICB0aGlzLl9zcHJlYWQgPSBzcHJlYWQ7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydCA9IC1zcHJlYWQgLyAyO1xuICAgICAgICAgICAgY29uc3Qgc3RlcCA9IHNwcmVhZCAvICh0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goKG9zYywgaSkgPT4gb3NjLmRldHVuZS52YWx1ZSA9IHN0YXJ0ICsgc3RlcCAqIGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGV0dW5lZCBvc2NpbGxhdG9ycy4gTXVzdCBiZSBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiAxLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcihcIkMjM1wiLCBcInNhd3Rvb3RoXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIHVzZSA0IHNhd3Rvb3RoIG9zY2lsbGF0b3JzXG4gICAgICogZmF0T3NjLmNvdW50ID0gNDtcbiAgICAgKi9cbiAgICBnZXQgY291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7XG4gICAgfVxuICAgIHNldCBjb3VudChjb3VudCkge1xuICAgICAgICBhc3NlcnRSYW5nZShjb3VudCwgMSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGggIT09IGNvdW50KSB7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIHRoZSBwcmV2aW91cyBvc2NpbGxhdG9yc1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3NjID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIHZvbHVtZTogLTYgLSBjb3VudCAqIDEuMSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgcGhhc2U6IHRoaXMuX3BoYXNlICsgKGkgLyBjb3VudCkgKiAzNjAsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudDogdGhpcy5fcGFydGlhbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBvbnN0b3A6IGkgPT09IDAgPyAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSA6IG5vT3AsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgICAgICAgICBvc2MucGFydGlhbHMgPSB0aGlzLl9wYXJ0aWFscztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KG9zYy5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIG9zYy5kZXR1bmUub3ZlcnJpZGRlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIG9zYy5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yc1tpXSA9IG9zYztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHNldCB0aGUgc3ByZWFkXG4gICAgICAgICAgICB0aGlzLnNwcmVhZCA9IHRoaXMuX3NwcmVhZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5zdGFydCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX3BoYXNlID0gcGhhc2U7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goKG9zYywgaSkgPT4gb3NjLnBoYXNlID0gdGhpcy5fcGhhc2UgKyAoaSAvIHRoaXMuY291bnQpICogMzYwKTtcbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0uYmFzZVR5cGU7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MuYmFzZVR5cGUgPSBiYXNlVHlwZSk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0aGlzLl9vc2NpbGxhdG9yc1swXS50eXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aDtcbiAgICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IFwiY3VzdG9tXCI7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucGFydGlhbHMgPSBwYXJ0aWFscyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50KTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuX29zY2lsbGF0b3JzWzBdLnR5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5kaXNwb3NlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GYXRPc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgUHVsc2VPc2NpbGxhdG9yIH0gZnJvbSBcIi4vUHVsc2VPc2NpbGxhdG9yXCI7XG4vKipcbiAqIFBXTU9zY2lsbGF0b3IgbW9kdWxhdGVzIHRoZSB3aWR0aCBvZiBhIFRvbmUuUHVsc2VPc2NpbGxhdG9yXG4gKiBhdCB0aGUgbW9kdWxhdGlvbkZyZXF1ZW5jeS4gVGhpcyBoYXMgdGhlIGVmZmVjdCBvZiBjb250aW51b3VzbHlcbiAqIGNoYW5naW5nIHRoZSB0aW1icmUgb2YgdGhlIG9zY2lsbGF0b3IgYnkgYWx0ZXJpbmcgdGhlIGhhcm1vbmljc1xuICogZ2VuZXJhdGVkLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBwd20gPSBuZXcgVG9uZS5QV01Pc2NpbGxhdG9yKDYwLCAwLjMpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFBXTU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQV01Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibW9kdWxhdGlvbkZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBXTU9zY2lsbGF0b3JcIjtcbiAgICAgICAgdGhpcy5zb3VyY2VUeXBlID0gXCJwd21cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNjYWxlIHRoZSBvc2NpbGxhdG9yIHNvIGl0IGRvZXNuJ3QgZ28gc2lsZW50XG4gICAgICAgICAqIGF0IHRoZSBleHRyZW1lIHZhbHVlcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NjYWxlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtb2R1bGF0aW9uRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fcHVsc2UgPSBuZXcgUHVsc2VPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5tb2R1bGF0aW9uRnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY2hhbmdlIHRoZSBwdWxzZSBvc2NpbGxhdG9yIHR5cGVcbiAgICAgICAgdGhpcy5fcHVsc2UuY2FycmllclR5cGUgPSBcInNpbmVcIjtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uRnJlcXVlbmN5ID0gdGhpcy5fcHVsc2UuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY2hhaW4odGhpcy5fc2NhbGUsIHRoaXMuX3B1bHNlLndpZHRoKTtcbiAgICAgICAgdGhpcy5fcHVsc2UuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm1vZHVsYXRpb25GcmVxdWVuY3lcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIG1vZHVsYXRpb25GcmVxdWVuY3k6IDAuNCxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJwd21cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX3B1bHNlLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9wdWxzZS5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiByZXN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fcHVsc2UucmVzdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHdtXCIuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB3bVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZVR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHdtXCIuXG4gICAgICovXG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwd21cIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhcnRpYWxzIG9mIHRoZSB3YXZlZm9ybS4gQ2Fubm90IHNldCBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5vIHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwaGFzZSBvZiB0aGUgb3NjaWxsYXRvciBpbiBkZWdyZWVzLlxuICAgICAqL1xuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vZHVsYXRvci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3B1bHNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QV01Pc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc051bWJlciwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IEFNT3NjaWxsYXRvciB9IGZyb20gXCIuL0FNT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgRmF0T3NjaWxsYXRvciB9IGZyb20gXCIuL0ZhdE9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IEZNT3NjaWxsYXRvciB9IGZyb20gXCIuL0ZNT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBQdWxzZU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QdWxzZU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFBXTU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QV01Pc2NpbGxhdG9yXCI7XG5jb25zdCBPbW5pT3NjaWxsYXRvclNvdXJjZU1hcCA9IHtcbiAgICBhbTogQU1Pc2NpbGxhdG9yLFxuICAgIGZhdDogRmF0T3NjaWxsYXRvcixcbiAgICBmbTogRk1Pc2NpbGxhdG9yLFxuICAgIG9zY2lsbGF0b3I6IE9zY2lsbGF0b3IsXG4gICAgcHVsc2U6IFB1bHNlT3NjaWxsYXRvcixcbiAgICBwd206IFBXTU9zY2lsbGF0b3IsXG59O1xuLyoqXG4gKiBPbW5pT3NjaWxsYXRvciBhZ2dyZWdhdGVzIGFsbCBvZiB0aGUgb3NjaWxsYXRvciB0eXBlcyBpbnRvIG9uZS5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKFwiQyM0XCIsIFwicHdtXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE9tbmlPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT21uaU9zY2lsbGF0b3JcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICAgICAgLy8gc2V0IHRoZSBvcHRpb25zXG4gICAgICAgIHRoaXMuc2V0KG9wdGlvbnMpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIEFNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFB1bHNlT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBQV01Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AodGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIENhbiBiZSBhbnkgb2YgdGhlIGJhc2ljIHR5cGVzOiBzaW5lLCBzcXVhcmUsIHRyaWFuZ2xlLCBzYXd0b290aC4gT3JcbiAgICAgKiBwcmVmaXggdGhlIGJhc2ljIHR5cGVzIHdpdGggXCJmbVwiLCBcImFtXCIsIG9yIFwiZmF0XCIgdG8gdXNlIHRoZSBGTU9zY2lsbGF0b3IsIEFNT3NjaWxsYXRvciBvciBGYXRPc2NpbGxhdG9yXG4gICAgICogdHlwZXMuIFRoZSBvc2NpbGxhdG9yIGNvdWxkIGFsc28gYmUgc2V0IHRvIFwicHdtXCIgb3IgXCJwdWxzZVwiLiBBbGwgb2YgdGhlIHBhcmFtZXRlcnMgb2YgdGhlXG4gICAgICogb3NjaWxsYXRvcidzIGNsYXNzIGFyZSBhY2Nlc3NpYmxlIHdoZW4gdGhlIG9zY2lsbGF0b3IgaXMgc2V0IHRvIHRoYXQgdHlwZSwgYnV0IHRocm93cyBhbiBlcnJvclxuICAgICAqIHdoZW4gaXQncyBub3QuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBvbW5pT3NjLnR5cGUgPSBcInB3bVwiO1xuICAgICAqIC8vIG1vZHVsYXRpb25GcmVxdWVuY3kgaXMgcGFyYW1ldGVyIHdoaWNoIGlzIGF2YWlsYWJsZVxuICAgICAqIC8vIG9ubHkgd2hlbiB0aGUgdHlwZSBpcyBcInB3bVwiLlxuICAgICAqIG9tbmlPc2MubW9kdWxhdGlvbkZyZXF1ZW5jeS52YWx1ZSA9IDAuNTtcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgbGV0IHByZWZpeCA9IFwiXCI7XG4gICAgICAgIGlmIChbXCJhbVwiLCBcImZtXCIsIFwiZmF0XCJdLnNvbWUocCA9PiB0aGlzLl9zb3VyY2VUeXBlID09PSBwKSkge1xuICAgICAgICAgICAgcHJlZml4ID0gdGhpcy5fc291cmNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJlZml4ICsgdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGlmICh0eXBlLnN1YnN0cigwLCAyKSA9PT0gXCJmbVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwiZm1cIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGUuc3Vic3RyKDIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUuc3Vic3RyKDAsIDIpID09PSBcImFtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJhbVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZS5zdWJzdHIoMCwgMykgPT09IFwiZmF0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJmYXRcIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGUuc3Vic3RyKDMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFwicHdtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJwd21cIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlID09PSBcInB1bHNlXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJwdWxzZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJvc2NpbGxhdG9yXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSBpcyBhbiBlbXB0eSBhcnJheSB3aGVuIHRoZSB0eXBlIGlzIG5vdCBcImN1c3RvbVwiLlxuICAgICAqIFRoaXMgaXMgbm90IGF2YWlsYWJsZSBvbiBcInB3bVwiIGFuZCBcInB1bHNlXCIgb3NjaWxsYXRvciB0eXBlcy5cbiAgICAgKiBTZWUgW1tPc2NpbGxhdG9yLnBhcnRpYWxzXV1cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiYgIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIGlmICghdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB1bHNlXCIpICYmICF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQocHJvcHMpIHtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSB0eXBlIGlzIHNldCBmaXJzdFxuICAgICAgICBpZiAoUmVmbGVjdC5oYXMocHJvcHMsIFwidHlwZVwiKSAmJiBwcm9wcy50eXBlKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBwcm9wcy50eXBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZW4gc2V0IHRoZSByZXN0XG4gICAgICAgIHN1cGVyLnNldChwcm9wcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjb25uZWN0IHRoZSBvc2NpbGxhdG9yIHRvIHRoZSBmcmVxdWVuY3kgYW5kIGRldHVuZSBzaWduYWxzXG4gICAgICovXG4gICAgX2NyZWF0ZU5ld09zY2lsbGF0b3Iob3NjVHlwZSkge1xuICAgICAgICBpZiAob3NjVHlwZSAhPT0gdGhpcy5fc291cmNlVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlVHlwZSA9IG9zY1R5cGU7XG4gICAgICAgICAgICBjb25zdCBPc2NDb25zdHJ1Y3RvciA9IE9tbmlPc2NpbGxhdG9yU291cmNlTWFwW29zY1R5cGVdO1xuICAgICAgICAgICAgLy8gc2hvcnQgZGVsYXkgdG8gYXZvaWQgY2xpY2tzIG9uIHRoZSBjaGFuZ2VcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9sZE9zYyA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICAgICAgb2xkT3NjLnN0b3Aobm93KTtcbiAgICAgICAgICAgICAgICAvLyBkaXNwb3NlIHRoZSBvbGQgb25lXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoKCkgPT4gb2xkT3NjLmRpc3Bvc2UoKSwgdGhpcy5ibG9ja1RpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG5ldyBPc2NDb25zdHJ1Y3Rvcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5kZXR1bmUpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iub25zdG9wID0gKCkgPT4gdGhpcy5vbnN0b3AodGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KG5vdyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNvdXJjZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKDQ0MCwgXCJmbXNxdWFyZVwiKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvbW5pT3NjLnNvdXJjZVR5cGUpOyAvLyAnZm0nXG4gICAgICovXG4gICAgZ2V0IHNvdXJjZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2VUeXBlO1xuICAgIH1cbiAgICBzZXQgc291cmNlVHlwZShzVHlwZSkge1xuICAgICAgICAvLyB0aGUgYmFzZXR5cGUgZGVmYXVsdHMgdG8gc2luZVxuICAgICAgICBsZXQgYmFzZVR5cGUgPSBcInNpbmVcIjtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IudHlwZSAhPT0gXCJwd21cIiAmJiB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgIT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgYmFzZVR5cGUgPSB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHRoZSB0eXBlXG4gICAgICAgIGlmIChzVHlwZSA9PT0gXCJmbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImZtXCIgKyBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJhbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImFtXCIgKyBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJmYXRcIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJmYXRcIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcIm9zY2lsbGF0b3JcIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJwdWxzZVwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcInB3bVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcInB3bVwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIF9nZXRPc2NUeXBlKG9zYywgc291cmNlVHlwZSkge1xuICAgICAgICByZXR1cm4gb3NjIGluc3RhbmNlb2YgT21uaU9zY2lsbGF0b3JTb3VyY2VNYXBbc291cmNlVHlwZV07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIFNlZSBbW09zY2lsbGF0b3IuYmFzZVR5cGVdXVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKDQ0MCwgXCJmbXNxdWFyZTRcIik7XG4gICAgICogY29uc29sZS5sb2cob21uaU9zYy5zb3VyY2VUeXBlLCBvbW5pT3NjLmJhc2VUeXBlLCBvbW5pT3NjLnBhcnRpYWxDb3VudCk7XG4gICAgICovXG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIGlmICghdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB1bHNlXCIpICYmXG4gICAgICAgICAgICAhdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSAmJlxuICAgICAgICAgICAgYmFzZVR5cGUgIT09IFwicHVsc2VcIiAmJiBiYXNlVHlwZSAhPT0gXCJwd21cIikge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB3aWR0aCBvZiB0aGUgb3NjaWxsYXRvciB3aGVuIHNvdXJjZVR5cGUgPT09IFwicHVsc2VcIi5cbiAgICAgKiBTZWUgW1tQV01Pc2NpbGxhdG9yLndpZHRoXV1cbiAgICAgKi9cbiAgICBnZXQgd2lkdGgoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLndpZHRoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGRldHVuZWQgb3NjaWxsYXRvcnMgd2hlbiBzb3VyY2VUeXBlID09PSBcImZhdFwiLlxuICAgICAqIFNlZSBbW0ZhdE9zY2lsbGF0b3IuY291bnRdXVxuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmNvdW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgY291bnQoY291bnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikgJiYgaXNOdW1iZXIoY291bnQpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvdW50ID0gY291bnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRldHVuZSBzcHJlYWQgYmV0d2VlbiB0aGUgb3NjaWxsYXRvcnMgd2hlbiBzb3VyY2VUeXBlID09PSBcImZhdFwiLlxuICAgICAqIFNlZSBbW0ZhdE9zY2lsbGF0b3IuY291bnRdXVxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZmF0XCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5zcHJlYWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZmF0XCIpICYmIGlzTnVtYmVyKHNwcmVhZCkpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3ByZWFkID0gc3ByZWFkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvci4gT25seSBpZiB0aGUgb3NjaWxsYXRvciBpcyBzZXQgdG8gXCJhbVwiIG9yIFwiZm1cIiB0eXBlcy5cbiAgICAgKiBTZWUgW1tBTU9zY2lsbGF0b3JdXSBvciBbW0ZNT3NjaWxsYXRvcl1dXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25UeXBlKCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpIHx8IHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJhbVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvblR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uVHlwZShtVHlwZSkge1xuICAgICAgICBpZiAoKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSB8fCB0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiYW1cIikpICYmIGlzU3RyaW5nKG1UeXBlKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uVHlwZSA9IG1UeXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtb2R1bGF0aW9uIGluZGV4IHdoZW4gdGhlIHNvdXJjZVR5cGUgPT09IFwiZm1cIlxuICAgICAqIFNlZSBbW0ZNT3NjaWxsYXRvcl1dLlxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uSW5kZXgoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25JbmRleDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSGFybW9uaWNpdHkgaXMgdGhlIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSBjYXJyaWVyIGFuZCB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JzLlxuICAgICAqIFNlZSBbW0FNT3NjaWxsYXRvcl1dIG9yIFtbRk1Pc2NpbGxhdG9yXV1cbiAgICAgKi9cbiAgICBnZXQgaGFybW9uaWNpdHkoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikgfHwgdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImFtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5oYXJtb25pY2l0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb25GcmVxdWVuY3kgU2lnbmFsIG9mIHRoZSBvc2NpbGxhdG9yIHdoZW4gc291cmNlVHlwZSA9PT0gXCJwd21cIlxuICAgICAqIHNlZSBbW1BXTU9zY2lsbGF0b3JdXVxuICAgICAqIEBtaW4gMC4xXG4gICAgICogQG1heCA1XG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25GcmVxdWVuY3koKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uRnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T21uaU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbi8qKlxuICogQWRkIGEgc2lnbmFsIGFuZCBhIG51bWJlciBvciB0d28gc2lnbmFscy4gV2hlbiBubyB2YWx1ZSBpc1xuICogcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLCBUb25lLkFkZCB3aWxsIHN1bSBpbnB1dCBhbmQgYGFkZGVuZGBcbiAqIElmIGEgdmFsdWUgaXMgcGFzc2VkIGludG8gdGhlIGNvbnN0cnVjdG9yLCB0aGUgaXQgd2lsbCBiZSBhZGRlZCB0byB0aGUgaW5wdXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhZGQgPSBuZXcgVG9uZS5BZGQoMikudG9EZXN0aW5hdGlvbigpO1xuICogXHRhZGQuYWRkZW5kLnNldFZhbHVlQXRUaW1lKDEsIDAuMik7XG4gKiBcdGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgyKTtcbiAqIFx0Ly8gYWRkIGEgc2lnbmFsIGFuZCBhIHNjYWxhclxuICogXHRzaWduYWwuY29ubmVjdChhZGQpO1xuICogXHRzaWduYWwuc2V0VmFsdWVBdFRpbWUoMSwgMC4xKTtcbiAqIH0sIDAuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBBZGQgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFkZC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQWRkXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgc3VtbWluZyBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdW0gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9zdW07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgd2hpY2ggaXMgYWRkZWQgdG8gdGhlIGlucHV0IHNpZ25hbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hZGRlbmQgPSB0aGlzLl9wYXJhbTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLl9jb25zdGFudFNvdXJjZSwgdGhpcy5fc3VtKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N1bS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFkZC5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuL0FkZFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBQZXJmb3JtcyBhIGxpbmVhciBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cbiAqIFNjYWxlcyBhIE5vcm1hbFJhbmdlIGlucHV0IHRvIGJldHdlZW5cbiAqIG91dHB1dE1pbiBhbmQgb3V0cHV0TWF4LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzY2FsZSA9IG5ldyBUb25lLlNjYWxlKDUwLCAxMDApO1xuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChzY2FsZSk7XG4gKiAvLyB0aGUgb3V0cHV0IG9mIHNjYWxlIGVxdWFscyA3NVxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgU2NhbGUgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2NhbGVcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCJdKTtcbiAgICAgICAgdGhpcy5fbXVsdCA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubWF4IC0gb3B0aW9ucy5taW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hZGQgPSB0aGlzLm91dHB1dCA9IG5ldyBBZGQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWluID0gb3B0aW9ucy5taW47XG4gICAgICAgIHRoaXMuX21heCA9IG9wdGlvbnMubWF4O1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIG91dHB1dCB2YWx1ZS4gVGhpcyBudW1iZXIgaXMgb3V0cHV0IHdoZW4gdGhlIHZhbHVlIGlucHV0IHZhbHVlIGlzIDAuXG4gICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbjtcbiAgICB9XG4gICAgc2V0IG1pbihtaW4pIHtcbiAgICAgICAgdGhpcy5fbWluID0gbWluO1xuICAgICAgICB0aGlzLl9zZXRSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgbnVtYmVyIGlzIG91dHB1dCB3aGVuIHRoZSB2YWx1ZSBpbnB1dCB2YWx1ZSBpcyAxLlxuICAgICAqL1xuICAgIGdldCBtYXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXg7XG4gICAgfVxuICAgIHNldCBtYXgobWF4KSB7XG4gICAgICAgIHRoaXMuX21heCA9IG1heDtcbiAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc2V0IHRoZSB2YWx1ZXNcbiAgICAgKi9cbiAgICBfc2V0UmFuZ2UoKSB7XG4gICAgICAgIHRoaXMuX2FkZC52YWx1ZSA9IHRoaXMuX21pbjtcbiAgICAgICAgdGhpcy5fbXVsdC52YWx1ZSA9IHRoaXMuX21heCAtIHRoaXMuX21pbjtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hZGQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2NhbGUuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdCwgZGlzY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFRvbmUuWmVybyBvdXRwdXRzIDAncyBhdCBhdWRpby1yYXRlLiBUaGUgcmVhc29uIHRoaXMgaGFzIHRvIGJlXG4gKiBpdCdzIG93biBjbGFzcyBpcyB0aGF0IG1hbnkgYnJvd3NlcnMgb3B0aW1pemUgb3V0IFRvbmUuU2lnbmFsXG4gKiB3aXRoIGEgdmFsdWUgb2YgMCBhbmQgd2lsbCBub3QgcHJvY2VzcyBub2RlcyBmdXJ0aGVyIGRvd24gdGhlIGdyYXBoLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgWmVybyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhaZXJvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJaZXJvXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZ2FpbiBub2RlIHdoaWNoIGNvbm5lY3RzIHRoZSBjb25zdGFudCBzb3VyY2UgdG8gdGhlIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2FpbiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogT25seSBvdXRwdXRzIDBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2FpbjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5vIGlucHV0IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGNvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDApLCB0aGlzLl9nYWluKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGRpc2Nvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDApLCB0aGlzLl9nYWluKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9WmVyby5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgQXVkaW9Ub0dhaW4gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0F1ZGlvVG9HYWluXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwsIFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBaZXJvIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9aZXJvXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuLyoqXG4gKiBMRk8gc3RhbmRzIGZvciBsb3cgZnJlcXVlbmN5IG9zY2lsbGF0b3IuIExGTyBwcm9kdWNlcyBhbiBvdXRwdXQgc2lnbmFsXG4gKiB3aGljaCBjYW4gYmUgYXR0YWNoZWQgdG8gYW4gQXVkaW9QYXJhbSBvciBUb25lLlNpZ25hbFxuICogaW4gb3JkZXIgdG8gbW9kdWxhdGUgdGhhdCBwYXJhbWV0ZXIgd2l0aCBhbiBvc2NpbGxhdG9yLiBUaGUgTEZPIGNhblxuICogYWxzbyBiZSBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydCB0byBzdGFydC9zdG9wIGFuZCBjaGFuZ2Ugd2hlbiB0aGUgdGVtcG8gY2hhbmdlcy5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgbGZvID0gbmV3IFRvbmUuTEZPKFwiNG5cIiwgNDAwLCA0MDAwKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIH0sIDAuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBMRk8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTEZPLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibWluXCIsIFwibWF4XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTEZPXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgdGhhdCB0aGUgTEZPIG91dHB1dHMgd2hlbiBpdCdzIHN0b3BwZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0b3BwZWRWYWx1ZSA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIHByaXZhdGUgcGxhY2Vob2xkZXIgZm9yIHRoZSB1bml0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdW5pdHMgPSBcIm51bWJlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIGlucHV0IHZhbHVlIGlzIGNvbnZlcnRlZCB1c2luZyB0aGUgW1t1bml0c11dXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmNvbnZlcnQgPSB0cnVlO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSBtZXRob2RzIGJvcnJvd2VkIGZyb20gUGFyYW1cbiAgICAgICAgICovXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fZnJvbVR5cGUgPSBQYXJhbS5wcm90b3R5cGUuX2Zyb21UeXBlO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX3RvVHlwZSA9IFBhcmFtLnByb3RvdHlwZS5fdG9UeXBlO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2lzID0gUGFyYW0ucHJvdG90eXBlLl9pcztcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9jbGFtcFZhbHVlID0gUGFyYW0ucHJvdG90eXBlLl9jbGFtcFZhbHVlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTEZPLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibWluXCIsIFwibWF4XCJdKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG5ldyBPc2NpbGxhdG9yKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5hbXBsaXR1ZGUsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hbXBsaXR1ZGUgPSB0aGlzLl9hbXBsaXR1ZGVHYWluLmdhaW47XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImF1ZGlvUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5femVyb3MgPSBuZXcgWmVybyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fYTJnID0gbmV3IEF1ZGlvVG9HYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9zY2FsZXIgPSB0aGlzLm91dHB1dCA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXg6IG9wdGlvbnMubWF4LFxuICAgICAgICAgICAgbWluOiBvcHRpb25zLm1pbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudW5pdHMgPSBvcHRpb25zLnVuaXRzO1xuICAgICAgICB0aGlzLm1pbiA9IG9wdGlvbnMubWluO1xuICAgICAgICB0aGlzLm1heCA9IG9wdGlvbnMubWF4O1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY2hhaW4odGhpcy5fYW1wbGl0dWRlR2FpbiwgdGhpcy5fYTJnLCB0aGlzLl9zY2FsZXIpO1xuICAgICAgICB0aGlzLl96ZXJvcy5jb25uZWN0KHRoaXMuX2EyZyk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuY29ubmVjdCh0aGlzLl9hMmcpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJhbXBsaXR1ZGVcIiwgXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLnBoYXNlID0gb3B0aW9ucy5waGFzZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGFtcGxpdHVkZTogMSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogXCI0blwiLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBMRk8uXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdGhlIExGTyB3aWxsIHN0YXJ0XG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBMRk8uXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRoZSBMRk8gd2lsbCBzdG9wXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5zZXRWYWx1ZUF0VGltZSh0aGlzLl9zdG9wcGVkVmFsdWUsIHRpbWUpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzdGFydC9zdG9wL3BhdXNlIHRvIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBhbmQgdGhlIGZyZXF1ZW5jeSB0byB0aGUgYnBtIG9mIHRoZSB0cmFuc3BvcnRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxmbyA9IG5ldyBUb25lLkxGTyhcIjhuXCIpO1xuICAgICAqIGxmby5zeW5jKCkuc3RhcnQoMCk7XG4gICAgICogLy8gdGhlIHJhdGUgb2YgdGhlIExGTyB3aWxsIGFsd2F5cyBiZSBhbiBlaWdodGggbm90ZSwgZXZlbiBhcyB0aGUgdGVtcG8gY2hhbmdlc1xuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3luYygpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3koKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHVuc3luYyB0aGUgTEZPIGZyb20gdHJhbnNwb3J0IGNvbnRyb2xcbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudW5zeW5jRnJlcXVlbmN5KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZnRlciB0aGUgb3NjaWxsYXRvciB3YXZlZm9ybSBpcyB1cGRhdGVkLCByZXNldCB0aGUgYF9zdG9wcGVkU2lnbmFsYCB2YWx1ZSB0byBtYXRjaCB0aGUgdXBkYXRlZCB3YXZlZm9ybVxuICAgICAqL1xuICAgIF9zZXRTdG9wcGVkVmFsdWUoKSB7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRWYWx1ZSA9IHRoaXMuX29zY2lsbGF0b3IuZ2V0SW5pdGlhbFZhbHVlKCk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwudmFsdWUgPSB0aGlzLl9zdG9wcGVkVmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIG91dHB1dCBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCBtaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fc2NhbGVyLm1pbik7XG4gICAgfVxuICAgIHNldCBtaW4obWluKSB7XG4gICAgICAgIG1pbiA9IHRoaXMuX2Zyb21UeXBlKG1pbik7XG4gICAgICAgIHRoaXMuX3NjYWxlci5taW4gPSBtaW47XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG91dHB1dCBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCBtYXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fc2NhbGVyLm1heCk7XG4gICAgfVxuICAgIHNldCBtYXgobWF4KSB7XG4gICAgICAgIG1heCA9IHRoaXMuX2Zyb21UeXBlKG1heCk7XG4gICAgICAgIHRoaXMuX3NjYWxlci5tYXggPSBtYXg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yOiBTZWUgW1tPc2NpbGxhdG9yLnR5cGVdXVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX3NldFN0b3BwZWRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvcidzIHBhcnRpYWxzIGFycmF5OiBTZWUgW1tPc2NpbGxhdG9yLnBhcnRpYWxzXV1cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9zZXRTdG9wcGVkVmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fc2V0U3RvcHBlZFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvdXRwdXQgdW5pdHMgb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgdW5pdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl91bml0cztcbiAgICB9XG4gICAgc2V0IHVuaXRzKHZhbCkge1xuICAgICAgICBjb25zdCBjdXJyZW50TWluID0gdGhpcy5taW47XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNYXggPSB0aGlzLm1heDtcbiAgICAgICAgLy8gY29udmVydCB0aGUgbWluIGFuZCB0aGUgbWF4XG4gICAgICAgIHRoaXMuX3VuaXRzID0gdmFsO1xuICAgICAgICB0aGlzLm1pbiA9IGN1cnJlbnRNaW47XG4gICAgICAgIHRoaXMubWF4ID0gY3VycmVudE1heDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiIG9yIFwic3RvcHBlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwYXJhbSBub2RlIHRoZSBkZXN0aW5hdGlvbiB0byBjb25uZWN0IHRvXG4gICAgICogQHBhcmFtIG91dHB1dE51bSB0aGUgb3B0aW9uYWwgb3V0cHV0IG51bWJlclxuICAgICAqIEBwYXJhbSBpbnB1dE51bSB0aGUgaW5wdXQgbnVtYmVyXG4gICAgICovXG4gICAgY29ubmVjdChub2RlLCBvdXRwdXROdW0sIGlucHV0TnVtKSB7XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgUGFyYW0gfHwgbm9kZSBpbnN0YW5jZW9mIFNpZ25hbCkge1xuICAgICAgICAgICAgdGhpcy5jb252ZXJ0ID0gbm9kZS5jb252ZXJ0O1xuICAgICAgICAgICAgdGhpcy51bml0cyA9IG5vZGUudW5pdHM7XG4gICAgICAgIH1cbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBub2RlLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl96ZXJvcy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2EyZy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmFtcGxpdHVkZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxGTy5qcy5tYXAiLCJpbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuL0RlYnVnXCI7XG4vKipcbiAqIEFzc2VydCB0aGF0IHRoZSBudW1iZXIgaXMgaW4gdGhlIGdpdmVuIHJhbmdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFuZ2UobWluLCBtYXggPSBJbmZpbml0eSkge1xuICAgIGNvbnN0IHZhbHVlTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlTWFwLmdldCh0aGlzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGFzc2VydFJhbmdlKG5ld1ZhbHVlLCBtaW4sIG1heCk7XG4gICAgICAgICAgICAgICAgdmFsdWVNYXAuc2V0KHRoaXMsIG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbn1cbi8qKlxuICogQ29udmVydCB0aGUgdGltZSB0byBzZWNvbmRzIGFuZCBhc3NlcnQgdGhhdCB0aGUgdGltZSBpcyBpbiBiZXR3ZWVuIHRoZSB0d29cbiAqIHZhbHVlcyB3aGVuIGJlaW5nIHNldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpbWVSYW5nZShtaW4sIG1heCA9IEluZmluaXR5KSB7XG4gICAgY29uc3QgdmFsdWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHMobmV3VmFsdWUpLCBtaW4sIG1heCk7XG4gICAgICAgICAgICAgICAgdmFsdWVNYXAuc2V0KHRoaXMsIG5ld1ZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlY29yYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIsIF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNVbmRlZiB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vVG9uZUJ1ZmZlclNvdXJjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBQbGF5ZXIgaXMgYW4gYXVkaW8gZmlsZSBwbGF5ZXIgd2l0aCBzdGFydCwgbG9vcCwgYW5kIHN0b3AgZnVuY3Rpb25zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2dvbmdfMS5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcGxheSBhcyBzb29uIGFzIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFBsYXllciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsYXllclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBhY3RpdmUgYnVmZmVyIHNvdXJjZSBub2Rlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIoe1xuICAgICAgICAgICAgb25sb2FkOiB0aGlzLl9vbmxvYWQuYmluZCh0aGlzLCBvcHRpb25zLm9ubG9hZCksXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgICAgICByZXZlcnNlOiBvcHRpb25zLnJldmVyc2UsXG4gICAgICAgICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdXRvc3RhcnQgPSBvcHRpb25zLmF1dG9zdGFydDtcbiAgICAgICAgdGhpcy5fbG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLmZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLmZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF1dG9zdGFydDogZmFsc2UsXG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHJldmVyc2U6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9hZCB0aGUgYXVkaW8gZmlsZSBhcyBhbiBhdWRpbyBidWZmZXIuXG4gICAgICogRGVjb2RlcyB0aGUgYXVkaW8gYXN5bmNocm9ub3VzbHkgYW5kIGludm9rZXNcbiAgICAgKiB0aGUgY2FsbGJhY2sgb25jZSB0aGUgYXVkaW8gYnVmZmVyIGxvYWRzLlxuICAgICAqIE5vdGU6IHRoaXMgZG9lcyBub3QgbmVlZCB0byBiZSBjYWxsZWQgaWYgYSB1cmxcbiAgICAgKiB3YXMgcGFzc2VkIGluIHRvIHRoZSBjb25zdHJ1Y3Rvci4gT25seSB1c2UgdGhpc1xuICAgICAqIGlmIHlvdSB3YW50IHRvIG1hbnVhbGx5IGxvYWQgYSBuZXcgdXJsLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuIEZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGUgYnJvd3Nlci5cbiAgICAgKi9cbiAgICBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgeWllbGQgdGhpcy5fYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgICAgIHRoaXMuX29ubG9hZCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBjYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIF9vbmxvYWQoY2FsbGJhY2sgPSBub09wKSB7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIGlmICh0aGlzLmF1dG9zdGFydCkge1xuICAgICAgICAgICAgdGhpcy5zdGFydCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGNhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcyBkb25lIHBsYXlpbmcuXG4gICAgICovXG4gICAgX29uU291cmNlRW5kKHNvdXJjZSkge1xuICAgICAgICAvLyBpbnZva2UgdGhlIG9uc3RvcCBmdW5jdGlvblxuICAgICAgICB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICAgICAgLy8gZGVsZXRlIHRoZSBzb3VyY2UgZnJvbSB0aGUgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5kZWxldGUoc291cmNlKTtcbiAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZVNvdXJjZXMuc2l6ZSA9PT0gMCAmJiAhdGhpcy5fc3luY2VkICYmXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLm5vdygpKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgJ2ltcGxpY2l0RW5kJyBldmVudCBhbmQgcmVwbGFjZSB3aXRoIGFuIGV4cGxpY2l0IGVuZFxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRoaXMubm93KCkpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHRoaXMubm93KCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBsYXkgdGhlIGJ1ZmZlciBhdCB0aGUgZ2l2ZW4gc3RhcnRUaW1lLiBPcHRpb25hbGx5IGFkZCBhbiBvZmZzZXRcbiAgICAgKiBhbmQvb3IgZHVyYXRpb24gd2hpY2ggd2lsbCBwbGF5IHRoZSBidWZmZXIgZnJvbSBhIHBvc2l0aW9uXG4gICAgICogd2l0aGluIHRoZSBidWZmZXIgZm9yIHRoZSBnaXZlbiBkdXJhdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbiwgaXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgc3VwZXIuc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdGFydCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RhcnQoc3RhcnRUaW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIC8vIGlmIGl0J3MgYSBsb29wIHRoZSBkZWZhdWx0IG9mZnNldCBpcyB0aGUgbG9vcFN0YXJ0IHBvaW50XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgdGhpcy5fbG9vcFN0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB0aGUgZGVmYXVsdCBvZmZzZXQgaXMgMFxuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbXB1dGUgdGhlIHZhbHVlcyBpbiBzZWNvbmRzXG4gICAgICAgIGNvbnN0IGNvbXB1dGVkT2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgZHVyYXRpb24gd2hpY2ggaXMgZWl0aGVyIHRoZSBwYXNzZWQgaW4gZHVyYXRpb24gb2YgdGhlIGJ1ZmZlci5kdXJhdGlvbiAtIG9mZnNldFxuICAgICAgICBjb25zdCBvcmlnRHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgZHVyYXRpb24gPSBkZWZhdWx0QXJnKGR1cmF0aW9uLCBNYXRoLm1heCh0aGlzLl9idWZmZXIuZHVyYXRpb24gLSBjb21wdXRlZE9mZnNldCwgMCkpO1xuICAgICAgICBsZXQgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgLy8gc2NhbGUgaXQgYnkgdGhlIHBsYXliYWNrIHJhdGVcbiAgICAgICAgY29tcHV0ZWREdXJhdGlvbiA9IGNvbXB1dGVkRHVyYXRpb24gLyB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgICAgIC8vIGdldCB0aGUgc3RhcnQgdGltZVxuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICAvLyBtYWtlIHRoZSBzb3VyY2VcbiAgICAgICAgY29uc3Qgc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgdXJsOiB0aGlzLl9idWZmZXIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmYWRlSW46IHRoaXMuZmFkZUluLFxuICAgICAgICAgICAgZmFkZU91dDogdGhpcy5mYWRlT3V0LFxuICAgICAgICAgICAgbG9vcDogdGhpcy5fbG9vcCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IHRoaXMuX2xvb3BFbmQsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IHRoaXMuX2xvb3BTdGFydCxcbiAgICAgICAgICAgIG9uZW5kZWQ6IHRoaXMuX29uU291cmNlRW5kLmJpbmQodGhpcyksXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMuX3BsYXliYWNrUmF0ZSxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIC8vIHNldCB0aGUgbG9vcGluZyBwcm9wZXJ0aWVzXG4gICAgICAgIGlmICghdGhpcy5fbG9vcCAmJiAhdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdGFydFRpbWUgKyBjb21wdXRlZER1cmF0aW9uKTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3Mgbm90IGxvb3BpbmcsIHNldCB0aGUgc3RhdGUgY2hhbmdlIGF0IHRoZSBlbmQgb2YgdGhlIHNhbXBsZVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHN0YXJ0VGltZSArIGNvbXB1dGVkRHVyYXRpb24sIHtcbiAgICAgICAgICAgICAgICBpbXBsaWNpdEVuZDogdHJ1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGFkZCBpdCB0byB0aGUgYXJyYXkgb2YgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5hZGQoc291cmNlKTtcbiAgICAgICAgLy8gc3RhcnQgaXRcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgJiYgaXNVbmRlZihvcmlnRHVyYXRpb24pKSB7XG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQoc3RhcnRUaW1lLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBzdWJ0cmFjdCB0aGUgZmFkZSBvdXQgdGltZVxuICAgICAgICAgICAgc291cmNlLnN0YXJ0KHN0YXJ0VGltZSwgY29tcHV0ZWRPZmZzZXQsIGNvbXB1dGVkRHVyYXRpb24gLSB0aGlzLnRvU2Vjb25kcyh0aGlzLmZhZGVPdXQpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHBsYXliYWNrLlxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgYW5kIHRoZW4gcmVzdGFydCB0aGUgcGxheWVyIGZyb20gdGhlIGJlZ2lubmluZyAob3Igb2Zmc2V0KVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbixcbiAgICAgKiBcdFx0XHRcdFx0aXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqL1xuICAgIHJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBzdXBlci5yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VlayB0byBhIHNwZWNpZmljIHRpbWUgaW4gdGhlIHBsYXllcidzIGJ1ZmZlci4gSWYgdGhlXG4gICAgICogc291cmNlIGlzIG5vIGxvbmdlciBwbGF5aW5nIGF0IHRoYXQgdGltZSwgaXQgd2lsbCBzdG9wLlxuICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIHRpbWUgdG8gc2VlayB0by5cbiAgICAgKiBAcGFyYW0gd2hlbiBUaGUgdGltZSBmb3IgdGhlIHNlZWsgZXZlbnQgdG8gb2NjdXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9ndXJnbGluZ190aGVyZW1pbl8xLm1wM1wiLCAoKSA9PiB7XG4gICAgICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAgICAgKiBcdC8vIHNlZWsgdG8gdGhlIG9mZnNldCBpbiAxIHNlY29uZCBmcm9tIG5vd1xuICAgICAqIFx0cGxheWVyLnNlZWsoMC40LCBcIisxXCIpO1xuICAgICAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICBzZWVrKG9mZnNldCwgd2hlbikge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh3aGVuKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZE9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIGN1cnJlbnRseSBwbGF5aW5nLCBzdG9wIGl0XG4gICAgICAgICAgICB0aGlzLl9zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAvLyByZXN0YXJ0IGl0IGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgICAgICB0aGlzLl9zdGFydChjb21wdXRlZFRpbWUsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBsb29wIHN0YXJ0IGFuZCBlbmQuIFdpbGwgb25seSBsb29wIGlmIGxvb3AgaXMgc2V0IHRvIHRydWUuXG4gICAgICogQHBhcmFtIGxvb3BTdGFydCBUaGUgbG9vcCBzdGFydCB0aW1lXG4gICAgICogQHBhcmFtIGxvb3BFbmQgVGhlIGxvb3AgZW5kIHRpbWVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL21hbGV2b2ljZXNfYWEyX0YzLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gbG9vcCBiZXR3ZWVuIHRoZSBnaXZlbiBwb2ludHNcbiAgICAgKiBwbGF5ZXIuc2V0TG9vcFBvaW50cygwLjIsIDAuMyk7XG4gICAgICogcGxheWVyLmxvb3AgPSB0cnVlO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqL1xuICAgIHNldExvb3BQb2ludHMobG9vcFN0YXJ0LCBsb29wRW5kKSB7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gbG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIHN0YXJ0IGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gbG9vcFN0YXJ0O1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhsb29wU3RhcnQpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2V0IHRoZSBjdXJyZW50IHNvdXJjZVxuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgZW5kIGF0IHRoaXMgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhsb29wRW5kKSwgMCwgdGhpcy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdldCB0aGUgY3VycmVudCBzb3VyY2VcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UubG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gYnVmZmVyIGJlbG9uZ2luZyB0byB0aGUgcGxheWVyLlxuICAgICAqL1xuICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBzaG91bGQgbG9vcCBvbmNlIGl0J3Mgb3Zlci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9kcnVtLXNhbXBsZXMvYnJlYWtiZWF0Lm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcGxheWVyLmxvb3AgPSB0cnVlO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICAvLyBpZiBubyBjaGFuZ2UsIGRvIG5vdGhpbmdcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgPT09IGxvb3ApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgLy8gc2V0IHRoZSBsb29wIG9mIGFsbCBvZiB0aGUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wID0gbG9vcDtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChsb29wKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIG5leHQgc3RvcEV2ZW50XG4gICAgICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXROZXh0U3RhdGUoXCJzdG9wcGVkXCIsIHRoaXMubm93KCkpO1xuICAgICAgICAgICAgaWYgKHN0b3BFdmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdG9wRXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTm9ybWFsIHNwZWVkIGlzIDEuIFRoZSBwaXRjaCB3aWxsIGNoYW5nZSB3aXRoIHRoZSBwbGF5YmFjayByYXRlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvZmVtYWxldm9pY2VzX2FhMl9BNS5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHBsYXkgYXQgMS80IHNwZWVkXG4gICAgICogcGxheWVyLnBsYXliYWNrUmF0ZSA9IDAuMjU7XG4gICAgICogLy8gcGxheSBhcyBzb29uIGFzIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgc3RvcCBldmVudCBzaW5jZSBpdCdzIGF0IGEgZGlmZmVyZW50IHRpbWUgbm93XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0b3BwZWRcIiwgbm93KTtcbiAgICAgICAgaWYgKHN0b3BFdmVudCAmJiBzdG9wRXZlbnQuaW1wbGljaXRFbmQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChzdG9wRXZlbnQudGltZSk7XG4gICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5jYW5jZWxTdG9wKCkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNldCBhbGwgdGhlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UucGxheWJhY2tSYXRlLnNldFZhbHVlQXRUaW1lKHJhdGUsIG5vdyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBiZSByZXZlcnNlZFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvY2hpbWVfMS5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqIHBsYXllci5yZXZlcnNlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgcmV2ZXJzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5yZXZlcnNlO1xuICAgIH1cbiAgICBzZXQgcmV2ZXJzZShyZXYpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnJldmVyc2UgPSByZXY7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5sb2FkZWQ7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgLy8gZGlzY29ubmVjdCBhbGwgb2YgdGhlIHBsYXllcnNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5jbGVhcigpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFBsYXllci5wcm90b3R5cGUsIFwiZmFkZUluXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFBsYXllci5wcm90b3R5cGUsIFwiZmFkZU91dFwiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGxheWVyLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi8uLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgUGxheWVyIH0gZnJvbSBcIi4vUGxheWVyXCI7XG4vKipcbiAqIFBsYXllcnMgY29tYmluZXMgbXVsdGlwbGUgW1tQbGF5ZXJdXSBvYmplY3RzLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUGxheWVycyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQbGF5ZXJzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiXSwgXCJ1cmxzXCIpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQbGF5ZXJzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQbGF5ZXJzIGhhcyBubyBpbnB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29udGFpbmVyIG9mIGFsbCBvZiB0aGUgcGxheWVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGxheWVycyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllcnMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCJdLCBcInVybHNcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IHZvbHVtZSBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgVG9uZUF1ZGlvQnVmZmVycyh7XG4gICAgICAgICAgICB1cmxzOiBvcHRpb25zLnVybHMsXG4gICAgICAgICAgICBvbmxvYWQ6IG9wdGlvbnMub25sb2FkLFxuICAgICAgICAgICAgYmFzZVVybDogb3B0aW9ucy5iYXNlVXJsLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtdXRlIGluaXRpYWxseVxuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiYXNlVXJsOiBcIlwiLFxuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHVybHM6IHt9LFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGVudmVsb3BlIGFwcGxpZWQgdG8gdGhlIHNvdXJjZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKGZhZGVJbikge1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBmYWRlSW47XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4ge1xuICAgICAgICAgICAgcGxheWVyLmZhZGVJbiA9IGZhZGVJbjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlT3V0IHRpbWUgb2YgdGhlIGVhY2ggb2YgdGhlIHNvdXJjZXMuXG4gICAgICovXG4gICAgZ2V0IGZhZGVPdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlT3V0O1xuICAgIH1cbiAgICBzZXQgZmFkZU91dChmYWRlT3V0KSB7XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBmYWRlT3V0O1xuICAgICAgICB0aGlzLl9wbGF5ZXJzLmZvckVhY2gocGxheWVyID0+IHtcbiAgICAgICAgICAgIHBsYXllci5mYWRlT3V0ID0gZmFkZU91dDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdGF0ZSBvZiB0aGUgcGxheWVycyBvYmplY3QuIFJldHVybnMgXCJzdGFydGVkXCIgaWYgYW55IG9mIHRoZSBwbGF5ZXJzIGFyZSBwbGF5aW5nLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgY29uc3QgcGxheWluZyA9IEFycmF5LmZyb20odGhpcy5fcGxheWVycykuc29tZSgoW18sIHBsYXllcl0pID0+IHBsYXllci5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpO1xuICAgICAgICByZXR1cm4gcGxheWluZyA/IFwic3RhcnRlZFwiIDogXCJzdG9wcGVkXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRydWUgaWYgdGhlIGJ1ZmZlcnMgb2JqZWN0IGhhcyBhIGJ1ZmZlciBieSB0aGF0IG5hbWUuXG4gICAgICogQHBhcmFtIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5oYXMobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIHBsYXllciBieSBuYW1lLlxuICAgICAqIEBwYXJhbSAgbmFtZSAgVGhlIHBsYXllcnMgbmFtZSBhcyBkZWZpbmVkIGluIHRoZSBjb25zdHJ1Y3RvciBvYmplY3Qgb3IgYGFkZGAgbWV0aG9kLlxuICAgICAqL1xuICAgIHBsYXllcihuYW1lKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLmhhcyhuYW1lKSwgYE5vIFBsYXllciB3aXRoIHRoZSBuYW1lICR7bmFtZX0gZXhpc3RzIG9uIHRoaXMgb2JqZWN0YCk7XG4gICAgICAgIGlmICghdGhpcy5fcGxheWVycy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHBsYXllciA9IG5ldyBQbGF5ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBmYWRlSW46IHRoaXMuX2ZhZGVJbixcbiAgICAgICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9mYWRlT3V0LFxuICAgICAgICAgICAgICAgIHVybDogdGhpcy5fYnVmZmVycy5nZXQobmFtZSksXG4gICAgICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHRoaXMuX3BsYXllcnMuc2V0KG5hbWUsIHBsYXllcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXllcnMuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBhbGwgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5sb2FkZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIHBsYXllciBieSBuYW1lIGFuZCB1cmwgdG8gdGhlIFBsYXllcnNcbiAgICAgKiBAcGFyYW0gIG5hbWUgQSB1bmlxdWUgbmFtZSB0byBnaXZlIHRoZSBwbGF5ZXJcbiAgICAgKiBAcGFyYW0gIHVybCAgRWl0aGVyIHRoZSB1cmwgb2YgdGhlIGJ1ZmVyIG9yIGEgYnVmZmVyIHdoaWNoIHdpbGwgYmUgYWRkZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBhZGQobmFtZSwgdXJsLCBjYWxsYmFjaykge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2J1ZmZlcnMuaGFzKG5hbWUpLCBcIkEgYnVmZmVyIHdpdGggdGhhdCBuYW1lIGFscmVhZHkgZXhpc3RzIG9uIHRoaXMgb2JqZWN0XCIpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChuYW1lLCB1cmwsIGNhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgYWxsIG9mIHRoZSBwbGF5ZXJzIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdG8gc3RvcCBhbGwgb2YgdGhlIHBsYXllcnMuXG4gICAgICovXG4gICAgc3RvcEFsbCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4gcGxheWVyLnN0b3AodGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4gcGxheWVyLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbGF5ZXJzLmpzLm1hcCIsImltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQ2xvY2sgfSBmcm9tIFwiLi4vLi4vY29yZS9jbG9jay9DbG9ja1wiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmltcG9ydCB7IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBHcmFpblBsYXllciBpbXBsZW1lbnRzIFtncmFudWxhciBzeW50aGVzaXNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0dyYW51bGFyX3N5bnRoZXNpcykuXG4gKiBHcmFudWxhciBTeW50aGVzaXMgZW5hYmxlcyB5b3UgdG8gYWRqdXN0IHBpdGNoIGFuZCBwbGF5YmFjayByYXRlIGluZGVwZW5kZW50bHkuIFRoZSBncmFpblNpemUgaXMgdGhlXG4gKiBhbW91bnQgb2YgdGltZSBlYWNoIHNtYWxsIGNodW5rIG9mIGF1ZGlvIGlzIHBsYXllZCBmb3IgYW5kIHRoZSBvdmVybGFwIGlzIHRoZVxuICogYW1vdW50IG9mIGNyb3NzZmFkaW5nIHRyYW5zaXRpb24gdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgZ3JhaW5zLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgR3JhaW5QbGF5ZXIgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmFpblBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyYWluUGxheWVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbnRlcm5hbCBsb29wU3RhcnQgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbnRlcm5hbCBsb29wU3RhcnQgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBjdXJyZW50bHkgcGxheWluZyBCdWZmZXJTb3VyY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmFpblBsYXllci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIHRoaXMuYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcih7XG4gICAgICAgICAgICBvbmxvYWQ6IG9wdGlvbnMub25sb2FkLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yLFxuICAgICAgICAgICAgcmV2ZXJzZTogb3B0aW9ucy5yZXZlcnNlLFxuICAgICAgICAgICAgdXJsOiBvcHRpb25zLnVybCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nsb2NrID0gbmV3IENsb2NrKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEgLyBvcHRpb25zLmdyYWluU2l6ZVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX2dyYWluU2l6ZSA9IG9wdGlvbnMuZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLl9vdmVybGFwID0gb3B0aW9ucy5vdmVybGFwO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG9wdGlvbnMuZGV0dW5lO1xuICAgICAgICAvLyBzZXR1cFxuICAgICAgICB0aGlzLm92ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XG4gICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5ncmFpblNpemUgPSBvcHRpb25zLmdyYWluU2l6ZTtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSBvcHRpb25zLnJldmVyc2U7XG4gICAgICAgIHRoaXMuX2Nsb2NrLm9uKFwic3RvcFwiLCB0aGlzLl9vbnN0b3AuYmluZCh0aGlzKSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBvdmVybGFwOiAwLjEsXG4gICAgICAgICAgICBncmFpblNpemU6IDAuMixcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIHJldmVyc2U6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdGFydCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIG9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgZ3JhaW5TaXplID0gMSAvIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2xvY2suc3RhcnQodGltZSwgb2Zmc2V0IC8gZ3JhaW5TaXplKTtcbiAgICAgICAgaWYgKGR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbmQgdGhlbiByZXN0YXJ0IHRoZSBwbGF5ZXIgZnJvbSB0aGUgYmVnaW5uaW5nIChvciBvZmZzZXQpXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLFxuICAgICAqIFx0XHRcdFx0XHRpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHN1cGVyLnJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdG9wIG1ldGhvZFxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fY2xvY2suc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCB3aGVuIHRoZSBjbG9jayBpcyBzdG9wcGVkXG4gICAgICovXG4gICAgX29uc3RvcCh0aW1lKSB7XG4gICAgICAgIC8vIHN0b3AgdGhlIHBsYXllcnNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKChzb3VyY2UpID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5mYWRlT3V0ID0gMDtcbiAgICAgICAgICAgIHNvdXJjZS5zdG9wKHRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vbnN0b3AodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZWQgb24gZWFjaCBjbG9jayB0aWNrLiBzY2hlZHVsZWQgYSBuZXcgZ3JhaW4gYXQgdGhpcyB0aW1lLlxuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQgc2hvdWxkIHN0b3AgbG9vcGluZ1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aWNrcyAqIHRoaXMuX2dyYWluU2l6ZTtcbiAgICAgICAgdGhpcy5sb2coXCJvZmZzZXRcIiwgb2Zmc2V0KTtcbiAgICAgICAgaWYgKCF0aGlzLmxvb3AgJiYgb2Zmc2V0ID4gdGhpcy5idWZmZXIuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCh0aW1lKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmaWxlLCB0aGUgZmFkZSBpbiBzaG91bGQgYmUgMFxuICAgICAgICBjb25zdCBmYWRlSW4gPSBvZmZzZXQgPCB0aGlzLl9vdmVybGFwID8gMCA6IHRoaXMuX292ZXJsYXA7XG4gICAgICAgIC8vIGNyZWF0ZSBhIGJ1ZmZlciBzb3VyY2VcbiAgICAgICAgY29uc3Qgc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdXJsOiB0aGlzLmJ1ZmZlcixcbiAgICAgICAgICAgIGZhZGVJbjogZmFkZUluLFxuICAgICAgICAgICAgZmFkZU91dDogdGhpcy5fb3ZlcmxhcCxcbiAgICAgICAgICAgIGxvb3A6IHRoaXMubG9vcCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5fbG9vcFN0YXJ0LFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5fbG9vcEVuZCxcbiAgICAgICAgICAgIC8vIGNvbXB1dGUgdGhlIHBsYXliYWNrUmF0ZSBiYXNlZCBvbiB0aGUgZGV0dW5lXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyh0aGlzLmRldHVuZSAvIDEwMClcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHNvdXJjZS5zdGFydCh0aW1lLCB0aGlzLl9ncmFpblNpemUgKiB0aWNrcyk7XG4gICAgICAgIHNvdXJjZS5zdG9wKHRpbWUgKyB0aGlzLl9ncmFpblNpemUgLyB0aGlzLnBsYXliYWNrUmF0ZSk7XG4gICAgICAgIC8vIGFkZCBpdCB0byB0aGUgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5wdXNoKHNvdXJjZSk7XG4gICAgICAgIC8vIHJlbW92ZSBpdCB3aGVuIGl0J3MgZG9uZVxuICAgICAgICBzb3VyY2Uub25lbmRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fYWN0aXZlU291cmNlcy5pbmRleE9mKHNvdXJjZSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgc2FtcGxlXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHJhdGUsIDAuMDAxKTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgdGhpcy5ncmFpblNpemUgPSB0aGlzLl9ncmFpblNpemU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wIHN0YXJ0IHRpbWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wIGVuZCB0aW1lLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQodGltZSkge1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgMCwgdGhpcy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRpcmVjdGlvbiB0aGUgYnVmZmVyIHNob3VsZCBwbGF5IGluXG4gICAgICovXG4gICAgZ2V0IHJldmVyc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5yZXZlcnNlO1xuICAgIH1cbiAgICBzZXQgcmV2ZXJzZShyZXYpIHtcbiAgICAgICAgdGhpcy5idWZmZXIucmV2ZXJzZSA9IHJldjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgZWFjaCBjaHVuayBvZiBhdWRpbyB0aGF0IHRoZVxuICAgICAqIGJ1ZmZlciBpcyBjaG9wcGVkIGludG8gYW5kIHBsYXllZCBiYWNrIGF0LlxuICAgICAqL1xuICAgIGdldCBncmFpblNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ncmFpblNpemU7XG4gICAgfVxuICAgIHNldCBncmFpblNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9ncmFpblNpemUgPSB0aGlzLnRvU2Vjb25kcyhzaXplKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZnJlcXVlbmN5LnNldFZhbHVlQXRUaW1lKHRoaXMuX3BsYXliYWNrUmF0ZSAvIHRoaXMuX2dyYWluU2l6ZSwgdGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBvZiB0aGUgY3Jvc3MtZmFkZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgZ3JhaW5zLlxuICAgICAqL1xuICAgIGdldCBvdmVybGFwKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3ZlcmxhcDtcbiAgICB9XG4gICAgc2V0IG92ZXJsYXAodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0UmFuZ2UoY29tcHV0ZWRUaW1lLCAwKTtcbiAgICAgICAgdGhpcy5fb3ZlcmxhcCA9IGNvbXB1dGVkVGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgYWxsIHRoZSBidWZmZXIgaXMgbG9hZGVkXG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLmxvYWRlZDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmJ1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKChzb3VyY2UpID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmFpblBsYXllci5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9Ob2lzZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVXNlck1lZGlhXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL09zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvQU1Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0ZNT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9QdWxzZU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvRmF0T3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9QV01Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1RvbmVPc2NpbGxhdG9yTm9kZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9MRk9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvUGxheWVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvUGxheWVyc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL0dyYWluUGxheWVyXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBSZXR1cm4gdGhlIGFic29sdXRlIHZhbHVlIG9mIGFuIGluY29taW5nIHNpZ25hbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFicyA9IG5ldyBUb25lLkFicygpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDEpO1xuICogXHRzaWduYWwucmFtcFRvKC0xLCAwLjUpO1xuICogXHRzaWduYWwuY29ubmVjdChhYnMpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEFicyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBYnNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBub2RlIHdoaWNoIGNvbnZlcnRzIHRoZSBhdWRpbyByYW5nZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FicyA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHZhbCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKE1hdGguYWJzKHZhbCkgPCAwLjAwMSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNYXRoLmFicyh2YWwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2UgaW5wdXQgWy0xLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2FicztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgcmFuZ2UgWzAsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2FicztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Ficy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFicy5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBHYWluVG9BdWRpbyBjb252ZXJ0cyBhbiBpbnB1dCBpbiBOb3JtYWxSYW5nZSBbMCwxXSB0byBBdWRpb1JhbmdlIFstMSwxXS5cbiAqIFNlZSBbW0F1ZGlvVG9HYWluXV0uXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBHYWluVG9BdWRpbyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYWluVG9BdWRpb1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbm9ybSA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHggPT4gTWF0aC5hYnMoeCkgKiAyIC0gMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgTm9ybWFsUmFuZ2UgaW5wdXQgWzAsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbm9ybTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBBdWRpb1JhbmdlIG91dHB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX25vcm07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ub3JtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2FpblRvQXVkaW8uanMubWFwIiwiaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBOZWdhdGUgdGhlIGluY29taW5nIHNpZ25hbC4gaS5lLiBhbiBpbnB1dCBzaWduYWwgb2YgMTAgd2lsbCBvdXRwdXQgLTEwXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG5lZyA9IG5ldyBUb25lLk5lZ2F0ZSgpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKC0yKS5jb25uZWN0KG5lZyk7XG4gKiAvLyBvdXRwdXQgb2YgbmVnIGlzIHBvc2l0aXZlIDIuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBOZWdhdGUgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTmVnYXRlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBuZWdhdGlvbiBpcyBkb25lIGJ5IG11bHRpcGx5aW5nIGJ5IC0xXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tdWx0aXBseSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogLTEsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IGFuZCBvdXRwdXQgYXJlIGVxdWFsIHRvIHRoZSBtdWx0aXBseSBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbXVsdGlwbHk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbXVsdGlwbHk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICogQHJldHVybnMge05lZ2F0ZX0gdGhpc1xuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbXVsdGlwbHkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1OZWdhdGUuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOZWdhdGUgfSBmcm9tIFwiLi4vc2lnbmFsL05lZ2F0ZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbi8qKlxuICogU3VidHJhY3QgdGhlIHNpZ25hbCBjb25uZWN0ZWQgdG8gdGhlIGlucHV0IGlzIHN1YnRyYWN0ZWQgZnJvbSB0aGUgc2lnbmFsIGNvbm5lY3RlZFxuICogVGhlIHN1YnRyYWhlbmQuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIHN1YnRyYWN0IGEgc2NhbGFyIGZyb20gYSBzaWduYWxcbiAqIGNvbnN0IHN1YiA9IG5ldyBUb25lLlN1YnRyYWN0KDEpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDQpLmNvbm5lY3Qoc3ViKTtcbiAqIC8vIHRoZSBvdXRwdXQgb2Ygc3ViIGlzIDMuXG4gKiBAZXhhbXBsZVxuICogLy8gc3VidHJhY3QgdHdvIHNpZ25hbHNcbiAqIGNvbnN0IHN1YiA9IG5ldyBUb25lLlN1YnRyYWN0KCk7XG4gKiBjb25zdCBzaWdBID0gbmV3IFRvbmUuU2lnbmFsKDEwKTtcbiAqIGNvbnN0IHNpZ0IgPSBuZXcgVG9uZS5TaWduYWwoMi41KTtcbiAqIHNpZ0EuY29ubmVjdChzdWIpO1xuICogc2lnQi5jb25uZWN0KHN1Yi5zdWJ0cmFoZW5kKTtcbiAqIC8vIG91dHB1dCBvZiBzdWIgaXMgNy41XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJ0cmFjdCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoU3VidHJhY3QuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN1YnRyYWN0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgc3VtbWluZyBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdW0gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9zdW07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBOZWdhdGUgdGhlIGlucHV0IG9mIHRoZSBzZWNvbmQgaW5wdXQgYmVmb3JlIGNvbm5lY3RpbmcgaXQgdG8gdGhlIHN1bW1pbmcgbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX25lZyA9IG5ldyBOZWdhdGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdmFsdWUgd2hpY2ggaXMgc3VidHJhY3RlZCBmcm9tIHRoZSBtYWluIHNpZ25hbFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zdWJ0cmFoZW5kID0gdGhpcy5fcGFyYW07XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5fY29uc3RhbnRTb3VyY2UsIHRoaXMuX25lZywgdGhpcy5fc3VtKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25lZy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N1bS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN1YnRyYWN0LmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4vTXVsdGlwbHlcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogR3JlYXRlclRoYW5aZXJvIG91dHB1dHMgMSB3aGVuIHRoZSBpbnB1dCBpcyBzdHJpY3RseSBncmVhdGVyIHRoYW4gemVyb1xuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBndDAgPSBuZXcgVG9uZS5HcmVhdGVyVGhhblplcm8oKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3QoZ3QwKTtcbiAqIFx0c2lnLnNldFZhbHVlQXRUaW1lKC0xLCAwLjA1KTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmVhdGVyVGhhblplcm8gZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JlYXRlclRoYW5aZXJvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHcmVhdGVyVGhhblplcm9cIjtcbiAgICAgICAgdGhpcy5fdGhyZXNoID0gdGhpcy5vdXRwdXQgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsZW5ndGg6IDEyNyxcbiAgICAgICAgICAgIG1hcHBpbmc6ICh2YWwpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsIDw9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGUgPSB0aGlzLmlucHV0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAxMDAwMFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fc2NhbGUuY29ubmVjdCh0aGlzLl90aHJlc2gpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGhyZXNoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R3JlYXRlclRoYW5aZXJvLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBHcmVhdGVyVGhhblplcm8gfSBmcm9tIFwiLi9HcmVhdGVyVGhhblplcm9cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogT3V0cHV0IDEgaWYgdGhlIHNpZ25hbCBpcyBncmVhdGVyIHRoYW4gdGhlIHZhbHVlLCBvdGhlcndpc2Ugb3V0cHV0cyAwLlxuICogY2FuIGNvbXBhcmUgdHdvIHNpZ25hbHMgb3IgYSBzaWduYWwgYW5kIGEgbnVtYmVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZ3QgPSBuZXcgVG9uZS5HcmVhdGVyVGhhbigyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCg0KS5jb25uZWN0KGd0KTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmVhdGVyVGhhbiBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JlYXRlclRoYW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHcmVhdGVyVGhhblwiO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5fc3VidHJhY3QgPSB0aGlzLmlucHV0ID0gbmV3IFN1YnRyYWN0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnZhbHVlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ndHogPSB0aGlzLm91dHB1dCA9IG5ldyBHcmVhdGVyVGhhblplcm8oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuY29tcGFyYXRvciA9IHRoaXMuX3BhcmFtID0gdGhpcy5fc3VidHJhY3Quc3VidHJhaGVuZDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJjb21wYXJhdG9yXCIpO1xuICAgICAgICAvLyBjb25uZWN0XG4gICAgICAgIHRoaXMuX3N1YnRyYWN0LmNvbm5lY3QodGhpcy5fZ3R6KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2d0ei5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N1YnRyYWN0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jb21wYXJhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R3JlYXRlclRoYW4uanMubWFwIiwiaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBQb3cgYXBwbGllcyBhbiBleHBvbmVudCB0byB0aGUgaW5jb21pbmcgc2lnbmFsLiBUaGUgaW5jb21pbmcgc2lnbmFsIG11c3QgYmUgQXVkaW9SYW5nZSBbLTEsIDFdXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBvdyA9IG5ldyBUb25lLlBvdygyKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3QocG93KTtcbiAqIC8vIG91dHB1dCBvZiBwb3cgaXMgMC4yNS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFBvdyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhQb3cuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQb3dcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvdy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB0aGlzLl9leHBGdW5jKG9wdGlvbnMudmFsdWUpLFxuICAgICAgICAgICAgbGVuZ3RoOiA4MTkyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSBvcHRpb25zLnZhbHVlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogdGhlIGZ1bmN0aW9uIHdoaWNoIG1hcHMgdGhlIHdhdmVzaGFwZXJcbiAgICAgKiBAcGFyYW0gZXhwb25lbnQgZXhwb25lbnQgdmFsdWVcbiAgICAgKi9cbiAgICBfZXhwRnVuYyhleHBvbmVudCkge1xuICAgICAgICByZXR1cm4gKHZhbCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgucG93KE1hdGguYWJzKHZhbCksIGV4cG9uZW50KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHZhbHVlIG9mIHRoZSBleHBvbmVudC5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9leHBvbmVudDtcbiAgICB9XG4gICAgc2V0IHZhbHVlKGV4cG9uZW50KSB7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50ID0gZXhwb25lbnQ7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50U2NhbGVyLnNldE1hcCh0aGlzLl9leHBGdW5jKHRoaXMuX2V4cG9uZW50KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Qb3cuanMubWFwIiwiaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi9TY2FsZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBQb3cgfSBmcm9tIFwiLi9Qb3dcIjtcbi8qKlxuICogUGVyZm9ybXMgYW4gZXhwb25lbnRpYWwgc2NhbGluZyBvbiBhbiBpbnB1dCBzaWduYWwuXG4gKiBTY2FsZXMgYSBOb3JtYWxSYW5nZSB2YWx1ZSBbMCwxXSBleHBvbmVudGlhbGx5XG4gKiB0byB0aGUgb3V0cHV0IHJhbmdlIG9mIG91dHB1dE1pbiB0byBvdXRwdXRNYXguXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc2NhbGVFeHAgPSBuZXcgVG9uZS5TY2FsZUV4cCgwLCAxMDAsIDIpO1xuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChzY2FsZUV4cCk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2FsZUV4cCBleHRlbmRzIFNjYWxlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZUV4cC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiLCBcImV4cG9uZW50XCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNjYWxlRXhwXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZUV4cC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiLCBcImV4cG9uZW50XCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2V4cCA9IG5ldyBQb3coe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZXhwb25lbnQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9leHAuY29ubmVjdCh0aGlzLl9tdWx0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTY2FsZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBleHBvbmVudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc3RlYWQgb2YgaW50ZXJwb2xhdGluZyBsaW5lYXJseSBiZXR3ZWVuIHRoZSBbW21pbl1dIGFuZFxuICAgICAqIFtbbWF4XV0gdmFsdWVzLCBzZXR0aW5nIHRoZSBleHBvbmVudCB3aWxsIGludGVycG9sYXRlIGJldHdlZW5cbiAgICAgKiB0aGUgdHdvIHZhbHVlcyB3aXRoIGFuIGV4cG9uZW50aWFsIGN1cnZlLlxuICAgICAqL1xuICAgIGdldCBleHBvbmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cC52YWx1ZTtcbiAgICB9XG4gICAgc2V0IGV4cG9uZW50KGV4cCkge1xuICAgICAgICB0aGlzLl9leHAudmFsdWUgPSBleHA7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2NhbGVFeHAuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgVG9uZUNvbnN0YW50U291cmNlIH0gZnJvbSBcIi4vVG9uZUNvbnN0YW50U291cmNlXCI7XG4vKipcbiAqIEFkZHMgdGhlIGFiaWxpdHkgdG8gc3luY2hyb25pemUgdGhlIHNpZ25hbCB0byB0aGUgW1tUcmFuc3BvcnRdXVxuICovXG5leHBvcnQgY2xhc3MgU3luY2VkU2lnbmFsIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN5bmNlZFNpZ25hbFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogRG9uJ3Qgb3ZlcnJpZGUgd2hlbiBzb21ldGhpbmcgaXMgY29ubmVjdGVkIHRvIHRoZSBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSk7XG4gICAgICAgIHRoaXMuX2xhc3RWYWwgPSBvcHRpb25zLnZhbHVlO1xuICAgICAgICB0aGlzLl9zeW5jZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KHRoaXMuX29uVGljay5iaW5kKHRoaXMpLCBcIjFpXCIpO1xuICAgICAgICB0aGlzLl9zeW5jZWRDYWxsYmFjayA9IHRoaXMuX2FuY2hvclZhbHVlLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdG9wXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgLy8gZGlzY29ubmVjdCB0aGUgY29uc3RhbnQgc291cmNlIGZyb20gdGhlIG91dHB1dCBhbmQgcmVwbGFjZSBpdCB3aXRoIGFub3RoZXIgb25lXG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uuc3RvcCgwKTtcbiAgICAgICAgLy8gY3JlYXRlIGEgbmV3IG9uZVxuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZSA9IHRoaXMub3V0cHV0ID0gbmV3IFRvbmVDb25zdGFudFNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgfSkuc3RhcnQoMCk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHdoaWNoIGlzIGludm9rZWQgZXZlcnkgdGljay5cbiAgICAgKi9cbiAgICBfb25UaWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdmFsID0gc3VwZXIuZ2V0VmFsdWVBdFRpbWUodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgLy8gYXBwcm94aW1hdGUgcmFtcCBjdXJ2ZXMgd2l0aCBsaW5lYXIgcmFtcHNcbiAgICAgICAgaWYgKHRoaXMuX2xhc3RWYWwgIT09IHZhbCkge1xuICAgICAgICAgICAgdGhpcy5fbGFzdFZhbCA9IHZhbDtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldC5zZXRWYWx1ZUF0VGltZSh2YWwsIHRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFuY2hvciB0aGUgdmFsdWUgYXQgdGhlIHN0YXJ0IGFuZCBzdG9wIG9mIHRoZSBUcmFuc3BvcnRcbiAgICAgKi9cbiAgICBfYW5jaG9yVmFsdWUodGltZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzdXBlci5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICB0aGlzLl9sYXN0VmFsID0gdmFsO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LnNldFZhbHVlQXRUaW1lKHZhbCwgdGltZSk7XG4gICAgfVxuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICByZXR1cm4gc3VwZXIuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHN0YXJ0VGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZykge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIHN1cGVyLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBjb21wdXRlZFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmNhbmNlbEFuZEhvbGRBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFJhbXBQb2ludCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuc2V0UmFtcFBvaW50KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci50YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKHRoaXMuX3N5bmNlZCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdG9wXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TeW5jZWRTaWduYWwuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vQWRkXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BYnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1ZGlvVG9HYWluXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9HYWluVG9BdWRpb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vR3JlYXRlclRoYW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0dyZWF0ZXJUaGFuWmVyb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vTXVsdGlwbHlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL05lZ2F0ZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUG93XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TaWduYWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NjYWxlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TY2FsZUV4cFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3VidHJhY3RcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1N5bmNlZFNpZ25hbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vWmVyb1wiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyLCBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzT2JqZWN0LCBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBjb25uZWN0U2lnbmFsLCBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyByYW5nZSwgdGltZVJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbi8qKlxuICogRW52ZWxvcGUgaXMgYW4gW0FEU1JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bnRoZXNpemVyI0FEU1JfZW52ZWxvcGUpXG4gKiBlbnZlbG9wZSBnZW5lcmF0b3IuIEVudmVsb3BlIG91dHB1dHMgYSBzaWduYWwgd2hpY2hcbiAqIGNhbiBiZSBjb25uZWN0ZWQgdG8gYW4gQXVkaW9QYXJhbSBvciBUb25lLlNpZ25hbC5cbiAqIGBgYFxuICogICAgICAgICAgIC9cXFxuICogICAgICAgICAgLyAgXFxcbiAqICAgICAgICAgLyAgICBcXFxuICogICAgICAgIC8gICAgICBcXFxuICogICAgICAgLyAgICAgICAgXFxfX19fX19fX19fX1xuICogICAgICAvICAgICAgICAgICAgICAgICAgICAgXFxcbiAqICAgICAvICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogICAgLyAgICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogICAvICAgICAgICAgICAgICAgICAgICAgICAgICAgXFxcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG4gKiBcdFx0YXR0YWNrOiAwLjEsXG4gKiBcdFx0ZGVjYXk6IDAuMixcbiAqIFx0XHRzdXN0YWluOiAwLjUsXG4gKiBcdFx0cmVsZWFzZTogMC44LFxuICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZSgwLjUpO1xuICogfSwgMS41LCAxKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEVudmVsb3BlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVudmVsb3BlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgc2lnbmFsIHdoaWNoIGlzIG91dHB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NpZyA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBzaWduYWwgb2YgdGhlIGVudmVsb3BlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3NpZztcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVudmVsb3BlIGhhcyBubyBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSk7XG4gICAgICAgIHRoaXMuYXR0YWNrID0gb3B0aW9ucy5hdHRhY2s7XG4gICAgICAgIHRoaXMuZGVjYXkgPSBvcHRpb25zLmRlY2F5O1xuICAgICAgICB0aGlzLnN1c3RhaW4gPSBvcHRpb25zLnN1c3RhaW47XG4gICAgICAgIHRoaXMucmVsZWFzZSA9IG9wdGlvbnMucmVsZWFzZTtcbiAgICAgICAgdGhpcy5hdHRhY2tDdXJ2ZSA9IG9wdGlvbnMuYXR0YWNrQ3VydmU7XG4gICAgICAgIHRoaXMucmVsZWFzZUN1cnZlID0gb3B0aW9ucy5yZWxlYXNlQ3VydmU7XG4gICAgICAgIHRoaXMuZGVjYXlDdXJ2ZSA9IG9wdGlvbnMuZGVjYXlDdXJ2ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgIGF0dGFja0N1cnZlOiBcImxpbmVhclwiLFxuICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgIGRlY2F5Q3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICByZWxlYXNlQ3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgIHN1c3RhaW46IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlYWQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGVudmVsb3BlLiBVc2VmdWwgZm9yXG4gICAgICogc3luY2hyb25pemluZyB2aXN1YWwgb3V0cHV0IHRvIHRoZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnZlXG4gICAgICogQHBhcmFtICBjdXJ2ZVxuICAgICAqIEBwYXJhbSAgZGlyZWN0aW9uICBJbi9PdXRcbiAgICAgKiBAcmV0dXJuIFRoZSBjdXJ2ZSBuYW1lXG4gICAgICovXG4gICAgX2dldEN1cnZlKGN1cnZlLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGN1cnZlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGN1cnZlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgY3VydmVzIGFycmF5XG4gICAgICAgICAgICBsZXQgY3VydmVOYW1lO1xuICAgICAgICAgICAgZm9yIChjdXJ2ZU5hbWUgaW4gRW52ZWxvcGVDdXJ2ZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoRW52ZWxvcGVDdXJ2ZXNbY3VydmVOYW1lXVtkaXJlY3Rpb25dID09PSBjdXJ2ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VydmVOYW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJldHVybiB0aGUgY3VzdG9tIGN1cnZlXG4gICAgICAgICAgICByZXR1cm4gY3VydmU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQXNzaWduIGEgdGhlIGN1cnZlIHRvIHRoZSBnaXZlbiBuYW1lIHVzaW5nIHRoZSBkaXJlY3Rpb25cbiAgICAgKiBAcGFyYW0gIG5hbWVcbiAgICAgKiBAcGFyYW0gIGRpcmVjdGlvbiBJbi9PdXRcbiAgICAgKiBAcGFyYW0gIGN1cnZlXG4gICAgICovXG4gICAgX3NldEN1cnZlKG5hbWUsIGRpcmVjdGlvbiwgY3VydmUpIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQncyBhIHZhbGlkIHR5cGVcbiAgICAgICAgaWYgKGlzU3RyaW5nKGN1cnZlKSAmJiBSZWZsZWN0LmhhcyhFbnZlbG9wZUN1cnZlcywgY3VydmUpKSB7XG4gICAgICAgICAgICBjb25zdCBjdXJ2ZURlZiA9IEVudmVsb3BlQ3VydmVzW2N1cnZlXTtcbiAgICAgICAgICAgIGlmIChpc09iamVjdChjdXJ2ZURlZikpIHtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSAhPT0gXCJfZGVjYXlDdXJ2ZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbbmFtZV0gPSBjdXJ2ZURlZltkaXJlY3Rpb25dO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXNbbmFtZV0gPSBjdXJ2ZURlZjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0FycmF5KGN1cnZlKSAmJiBuYW1lICE9PSBcIl9kZWNheUN1cnZlXCIpIHtcbiAgICAgICAgICAgIHRoaXNbbmFtZV0gPSBjdXJ2ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkVudmVsb3BlOiBpbnZhbGlkIGN1cnZlOiBcIiArIGN1cnZlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2hhcGUgb2YgdGhlIGF0dGFjay5cbiAgICAgKiBDYW4gYmUgYW55IG9mIHRoZXNlIHN0cmluZ3M6XG4gICAgICogKiBcImxpbmVhclwiXG4gICAgICogKiBcImV4cG9uZW50aWFsXCJcbiAgICAgKiAqIFwic2luZVwiXG4gICAgICogKiBcImNvc2luZVwiXG4gICAgICogKiBcImJvdW5jZVwiXG4gICAgICogKiBcInJpcHBsZVwiXG4gICAgICogKiBcInN0ZXBcIlxuICAgICAqXG4gICAgICogQ2FuIGFsc28gYmUgYW4gYXJyYXkgd2hpY2ggZGVzY3JpYmVzIHRoZSBjdXJ2ZS4gVmFsdWVzXG4gICAgICogaW4gdGhlIGFycmF5IGFyZSBldmVubHkgc3ViZGl2aWRlZCBhbmQgbGluZWFybHlcbiAgICAgKiBpbnRlcnBvbGF0ZWQgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIGF0dGFjay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICAgICAqIFx0Y29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoMC40KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYuYXR0YWNrQ3VydmUgPSBcImxpbmVhclwiO1xuICAgICAqIFx0ZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiB9LCAxLCAxKTtcbiAgICAgKi9cbiAgICBnZXQgYXR0YWNrQ3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDdXJ2ZSh0aGlzLl9hdHRhY2tDdXJ2ZSwgXCJJblwiKTtcbiAgICB9XG4gICAgc2V0IGF0dGFja0N1cnZlKGN1cnZlKSB7XG4gICAgICAgIHRoaXMuX3NldEN1cnZlKFwiX2F0dGFja0N1cnZlXCIsIFwiSW5cIiwgY3VydmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2hhcGUgb2YgdGhlIHJlbGVhc2UuIFNlZSB0aGUgYXR0YWNrIGN1cnZlIHR5cGVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG4gICAgICogXHRcdHJlbGVhc2U6IDAuOFxuICAgICAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIFx0ZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiBcdC8vIHJlbGVhc2UgY3VydmUgY291bGQgYWxzbyBiZSBkZWZpbmVkIGJ5IGFuIGFycmF5XG4gICAgICogXHRlbnYucmVsZWFzZUN1cnZlID0gWzEsIDAuMywgMC40LCAwLjIsIDAuNywgMF07XG4gICAgICogXHRlbnYudHJpZ2dlclJlbGVhc2UoMC4yKTtcbiAgICAgKiB9LCAxLCAxKTtcbiAgICAgKi9cbiAgICBnZXQgcmVsZWFzZUN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q3VydmUodGhpcy5fcmVsZWFzZUN1cnZlLCBcIk91dFwiKTtcbiAgICB9XG4gICAgc2V0IHJlbGVhc2VDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICB0aGlzLl9zZXRDdXJ2ZShcIl9yZWxlYXNlQ3VydmVcIiwgXCJPdXRcIiwgY3VydmUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2hhcGUgb2YgdGhlIGRlY2F5IGVpdGhlciBcImxpbmVhclwiIG9yIFwiZXhwb25lbnRpYWxcIlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSh7XG4gICAgICogXHRcdHN1c3RhaW46IDAuMSxcbiAgICAgKiBcdFx0ZGVjYXk6IDAuNVxuICAgICAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIFx0ZW52LmRlY2F5Q3VydmUgPSBcImxpbmVhclwiO1xuICAgICAqIFx0ZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiB9LCAxLCAxKTtcbiAgICAgKi9cbiAgICBnZXQgZGVjYXlDdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY2F5Q3VydmU7XG4gICAgfVxuICAgIHNldCBkZWNheUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIGFzc2VydChbXCJsaW5lYXJcIiwgXCJleHBvbmVudGlhbFwiXS5zb21lKGMgPT4gYyA9PT0gY3VydmUpLCBgSW52YWxpZCBlbnZlbG9wZSBjdXJ2ZTogJHtjdXJ2ZX1gKTtcbiAgICAgICAgdGhpcy5fZGVjYXlDdXJ2ZSA9IGN1cnZlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2svZGVjYXkgcG9ydGlvbiBvZiB0aGUgQURTUiBlbnZlbG9wZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBlbnZlbG9wZSBzY2FsZXMgdGhlIHZhbGVzLlxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXIgYmV0d2VlbiAwLTFcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGVudikuc3RhcnQoKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSBhdHRhY2sgMC41IHNlY29uZHMgZnJvbSBub3cgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrKFwiKzAuNVwiLCAwLjIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxBdHRhY2sgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmF0dGFjayk7XG4gICAgICAgIGxldCBhdHRhY2sgPSBvcmlnaW5hbEF0dGFjaztcbiAgICAgICAgY29uc3QgZGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmRlY2F5KTtcbiAgICAgICAgLy8gY2hlY2sgaWYgaXQncyBub3QgYSBjb21wbGV0ZSBhdHRhY2tcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA+IDApIHtcbiAgICAgICAgICAgIC8vIHN1YnRyYWN0IHRoZSBjdXJyZW50IHZhbHVlIGZyb20gdGhlIGF0dGFjayB0aW1lXG4gICAgICAgICAgICBjb25zdCBhdHRhY2tSYXRlID0gMSAvIGF0dGFjaztcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ0Rpc3RhbmNlID0gMSAtIGN1cnJlbnRWYWx1ZTtcbiAgICAgICAgICAgIC8vIHRoZSBhdHRhY2sgaXMgbm93IHRoZSByZW1haW5pbmcgdGltZVxuICAgICAgICAgICAgYXR0YWNrID0gcmVtYWluaW5nRGlzdGFuY2UgLyBhdHRhY2tSYXRlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGF0dGFja1xuICAgICAgICBpZiAoYXR0YWNrIDwgdGhpcy5zYW1wbGVUaW1lKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICAgICAgLy8gY2FzZSB3aGVyZSB0aGUgYXR0YWNrIHRpbWUgaXMgMCBzaG91bGQgc2V0IGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQXRUaW1lKHZlbG9jaXR5LCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9hdHRhY2tDdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUbyh2ZWxvY2l0eSwgYXR0YWNrLCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9hdHRhY2tDdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcudGFyZ2V0UmFtcFRvKHZlbG9jaXR5LCBhdHRhY2ssIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2lnLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgICAgICBsZXQgY3VydmUgPSB0aGlzLl9hdHRhY2tDdXJ2ZTtcbiAgICAgICAgICAgIC8vIGZpbmQgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGluIHRoZSBjdXJ2ZVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBjdXJ2ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIC8vIHRoZSBzdGFydGluZyBpbmRleCBpcyBiZXR3ZWVuIHRoZSB0d28gdmFsdWVzXG4gICAgICAgICAgICAgICAgaWYgKGN1cnZlW2kgLSAxXSA8PSBjdXJyZW50VmFsdWUgJiYgY3VycmVudFZhbHVlIDw9IGN1cnZlW2ldKSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnZlID0gdGhpcy5fYXR0YWNrQ3VydmUuc2xpY2UoaSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBpbmRleCBpcyB0aGUgY3VycmVudCB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICBjdXJ2ZVswXSA9IGN1cnJlbnRWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQ3VydmVBdFRpbWUoY3VydmUsIHRpbWUsIGF0dGFjaywgdmVsb2NpdHkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGRlY2F5XG4gICAgICAgIGlmIChkZWNheSAmJiB0aGlzLnN1c3RhaW4gPCAxKSB7XG4gICAgICAgICAgICBjb25zdCBkZWNheVZhbHVlID0gdmVsb2NpdHkgKiB0aGlzLnN1c3RhaW47XG4gICAgICAgICAgICBjb25zdCBkZWNheVN0YXJ0ID0gdGltZSArIGF0dGFjaztcbiAgICAgICAgICAgIHRoaXMubG9nKFwiZGVjYXlcIiwgZGVjYXlTdGFydCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fZGVjYXlDdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShkZWNheVZhbHVlLCBkZWNheSArIGRlY2F5U3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZShkZWNheVZhbHVlLCBkZWNheVN0YXJ0LCBkZWNheSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoZSByZWxlYXNlIG9mIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZSBzaG91bGQgc3RhcnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKHtcbiAgICAgKiBcdHR5cGU6IFwic2F3dG9vdGhcIlxuICAgICAqIH0pLmNvbm5lY3QoZW52KS5zdGFydCgpO1xuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgcmVsZWFzZSBoYWxmIGEgc2Vjb25kIGFmdGVyIHRoZSBhdHRhY2tcbiAgICAgKiBlbnYudHJpZ2dlclJlbGVhc2UoXCIrMC41XCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCB0aW1lKTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID4gMCkge1xuICAgICAgICAgICAgY29uc3QgcmVsZWFzZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMucmVsZWFzZSk7XG4gICAgICAgICAgICBpZiAocmVsZWFzZSA8IHRoaXMuc2FtcGxlVGltZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3JlbGVhc2VDdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5saW5lYXJSYW1wVG8oMCwgcmVsZWFzZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9yZWxlYXNlQ3VydmUgPT09IFwiZXhwb25lbnRpYWxcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy50YXJnZXRSYW1wVG8oMCwgcmVsZWFzZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnQoaXNBcnJheSh0aGlzLl9yZWxlYXNlQ3VydmUpLCBcInJlbGVhc2VDdXJ2ZSBtdXN0IGJlIGVpdGhlciAnbGluZWFyJywgJ2V4cG9uZW50aWFsJyBvciBhbiBhcnJheVwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVDdXJ2ZUF0VGltZSh0aGlzLl9yZWxlYXNlQ3VydmUsIHRpbWUsIHJlbGVhc2UsIGN1cnJlbnRWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgc2NoZWR1bGVkIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLiBUaGlzIHdpbGxcbiAgICAgKiByZXR1cm4gdGhlIHVuY29udmVydGVkIChyYXcpIHZhbHVlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoMC41LCAxLCAwLjQsIDIpO1xuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZSgyKTtcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhlbnYuZ2V0VmFsdWVBdFRpbWUoVG9uZS5ub3coKSkpLCAxMDApO1xuICAgICAqL1xuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NpZy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogdHJpZ2dlckF0dGFja1JlbGVhc2UgaXMgc2hvcnRoYW5kIGZvciB0cmlnZ2VyQXR0YWNrLCB0aGVuIHdhaXRpbmdcbiAgICAgKiBzb21lIGR1cmF0aW9uLCB0aGVuIHRyaWdnZXJSZWxlYXNlLlxuICAgICAqIEBwYXJhbSBkdXJhdGlvbiBUaGUgZHVyYXRpb24gb2YgdGhlIHN1c3RhaW4uXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgZW52ZWxvcGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChlbnYpLnN0YXJ0KCk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgcmVsZWFzZSAwLjUgc2Vjb25kcyBhZnRlciB0aGUgYXR0YWNrXG4gICAgICogZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuNSk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UodGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWxzIGFsbCBzY2hlZHVsZWQgZW52ZWxvcGUgY2hhbmdlcyBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5fc2lnLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aGlzLnRvU2Vjb25kcyhhZnRlcikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgZW52ZWxvcGUgdG8gYSBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqL1xuICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bWJlciA9IDAsIGlucHV0TnVtYmVyID0gMCkge1xuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW1iZXIsIGlucHV0TnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciB0aGUgZW52ZWxvcGUgY3VydmUgdG8gYW4gYXJyYXkgb2YgdGhlIGdpdmVuIGxlbmd0aC5cbiAgICAgKiBHb29kIGZvciB2aXN1YWxpemluZyB0aGUgZW52ZWxvcGUgY3VydmUuIFJlc2NhbGVzIHRoZSBkdXJhdGlvbiBvZiB0aGVcbiAgICAgKiBlbnZlbG9wZSB0byBmaXQgdGhlIGxlbmd0aC5cbiAgICAgKi9cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uID0gbGVuZ3RoIC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDEsIGR1cmF0aW9uLCB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyBub3JtYWxpemUgdGhlIEFEU1IgZm9yIHRoZSBnaXZlbiBkdXJhdGlvbiB3aXRoIDIwJSBzdXN0YWluIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGF0dGFja1BvcnRpb24gPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmRlY2F5KTtcbiAgICAgICAgICAgIGNvbnN0IGVudmVsb3BlRHVyYXRpb24gPSBhdHRhY2tQb3J0aW9uICsgdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKTtcbiAgICAgICAgICAgIGNvbnN0IHN1c3RhaW5UaW1lID0gZW52ZWxvcGVEdXJhdGlvbiAqIDAuMTtcbiAgICAgICAgICAgIGNvbnN0IHRvdGFsRHVyYXRpb24gPSBlbnZlbG9wZUR1cmF0aW9uICsgc3VzdGFpblRpbWU7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBjb25zdCBjbG9uZSA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKE9iamVjdC5hc3NpZ24odGhpcy5nZXQoKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogZHVyYXRpb24gKiB0aGlzLnRvU2Vjb25kcyh0aGlzLmF0dGFjaykgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIGRlY2F5OiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpIC8gdG90YWxEdXJhdGlvbixcbiAgICAgICAgICAgICAgICByZWxlYXNlOiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMucmVsZWFzZSkgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGNsb25lLl9zaWcudG9EZXN0aW5hdGlvbigpO1xuICAgICAgICAgICAgY2xvbmUudHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24gKiAoYXR0YWNrUG9ydGlvbiArIHN1c3RhaW5UaW1lKSAvIHRvdGFsRHVyYXRpb24sIDApO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgY29udGV4dC5yZW5kZXIoKTtcbiAgICAgICAgICAgIHJldHVybiBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgRW52ZWxvcGUucHJvdG90eXBlLCBcImF0dGFja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwiZGVjYXlcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHJhbmdlKDAsIDEpXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwic3VzdGFpblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwicmVsZWFzZVwiLCB2b2lkIDApO1xuLyoqXG4gKiBHZW5lcmF0ZSBzb21lIGNvbXBsZXggZW52ZWxvcGUgY3VydmVzLlxuICovXG5jb25zdCBFbnZlbG9wZUN1cnZlcyA9ICgoKSA9PiB7XG4gICAgY29uc3QgY3VydmVMZW4gPSAxMjg7XG4gICAgbGV0IGk7XG4gICAgbGV0IGs7XG4gICAgLy8gY29zaW5lIGN1cnZlXG4gICAgY29uc3QgY29zaW5lQ3VydmUgPSBbXTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBjb3NpbmVDdXJ2ZVtpXSA9IE1hdGguc2luKChpIC8gKGN1cnZlTGVuIC0gMSkpICogKE1hdGguUEkgLyAyKSk7XG4gICAgfVxuICAgIC8vIHJpcHBsZSBjdXJ2ZVxuICAgIGNvbnN0IHJpcHBsZUN1cnZlID0gW107XG4gICAgY29uc3QgcmlwcGxlQ3VydmVGcmVxID0gNi40O1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbiAtIDE7IGkrKykge1xuICAgICAgICBrID0gKGkgLyAoY3VydmVMZW4gLSAxKSk7XG4gICAgICAgIGNvbnN0IHNpbmVXYXZlID0gTWF0aC5zaW4oayAqIChNYXRoLlBJICogMikgKiByaXBwbGVDdXJ2ZUZyZXEgLSBNYXRoLlBJIC8gMikgKyAxO1xuICAgICAgICByaXBwbGVDdXJ2ZVtpXSA9IHNpbmVXYXZlIC8gMTAgKyBrICogMC44MztcbiAgICB9XG4gICAgcmlwcGxlQ3VydmVbY3VydmVMZW4gLSAxXSA9IDE7XG4gICAgLy8gc3RhaXJzIGN1cnZlXG4gICAgY29uc3Qgc3RhaXJzQ3VydmUgPSBbXTtcbiAgICBjb25zdCBzdGVwcyA9IDU7XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgc3RhaXJzQ3VydmVbaV0gPSBNYXRoLmNlaWwoKGkgLyAoY3VydmVMZW4gLSAxKSkgKiBzdGVwcykgLyBzdGVwcztcbiAgICB9XG4gICAgLy8gaW4tb3V0IGVhc2luZyBjdXJ2ZVxuICAgIGNvbnN0IHNpbmVDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG4gICAgICAgIHNpbmVDdXJ2ZVtpXSA9IDAuNSAqICgxIC0gTWF0aC5jb3MoTWF0aC5QSSAqIGspKTtcbiAgICB9XG4gICAgLy8gYSBib3VuY2UgY3VydmVcbiAgICBjb25zdCBib3VuY2VDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGsgPSBpIC8gKGN1cnZlTGVuIC0gMSk7XG4gICAgICAgIGNvbnN0IGZyZXEgPSBNYXRoLnBvdyhrLCAzKSAqIDQgKyAwLjI7XG4gICAgICAgIGNvbnN0IHZhbCA9IE1hdGguY29zKGZyZXEgKiBNYXRoLlBJICogMiAqIGspO1xuICAgICAgICBib3VuY2VDdXJ2ZVtpXSA9IE1hdGguYWJzKHZhbCAqICgxIC0gaykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZlcnQgYSB2YWx1ZSBjdXJ2ZSB0byBtYWtlIGl0IHdvcmsgZm9yIHRoZSByZWxlYXNlXG4gICAgICovXG4gICAgZnVuY3Rpb24gaW52ZXJ0Q3VydmUoY3VydmUpIHtcbiAgICAgICAgY29uc3Qgb3V0ID0gbmV3IEFycmF5KGN1cnZlLmxlbmd0aCk7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY3VydmUubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIG91dFtqXSA9IDEgLSBjdXJ2ZVtqXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiByZXZlcnNlIHRoZSBjdXJ2ZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIHJldmVyc2VDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICByZXR1cm4gY3VydmUuc2xpY2UoMCkucmV2ZXJzZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBhdHRhY2sgYW5kIHJlbGVhc2UgY3VydmUgYXJyYXlzXG4gICAgICovXG4gICAgcmV0dXJuIHtcbiAgICAgICAgYm91bmNlOiB7XG4gICAgICAgICAgICBJbjogaW52ZXJ0Q3VydmUoYm91bmNlQ3VydmUpLFxuICAgICAgICAgICAgT3V0OiBib3VuY2VDdXJ2ZSxcbiAgICAgICAgfSxcbiAgICAgICAgY29zaW5lOiB7XG4gICAgICAgICAgICBJbjogY29zaW5lQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IHJldmVyc2VDdXJ2ZShjb3NpbmVDdXJ2ZSksXG4gICAgICAgIH0sXG4gICAgICAgIGV4cG9uZW50aWFsOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgIGxpbmVhcjogXCJsaW5lYXJcIixcbiAgICAgICAgcmlwcGxlOiB7XG4gICAgICAgICAgICBJbjogcmlwcGxlQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IGludmVydEN1cnZlKHJpcHBsZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgc2luZToge1xuICAgICAgICAgICAgSW46IHNpbmVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUoc2luZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgc3RlcDoge1xuICAgICAgICAgICAgSW46IHN0YWlyc0N1cnZlLFxuICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShzdGFpcnNDdXJ2ZSksXG4gICAgICAgIH0sXG4gICAgfTtcbn0pKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FbnZlbG9wZS5qcy5tYXAiLCJpbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQmFzZS1jbGFzcyBmb3IgYWxsIGluc3RydW1lbnRzXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnN0cnVtZW50IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIGFsbCBldmVudHMgc2NoZWR1bGVkIHRvIHRoZSB0cmFuc3BvcnRcbiAgICAgICAgICogd2hlbiB0aGUgaW5zdHJ1bWVudCBpcyAnc3luY2VkJ1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgaW5zdHJ1bWVudCBpcyBjdXJyZW50bHkgc3luY2VkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fb3JpZ2luYWxfdHJpZ2dlckF0dGFjayA9IHRoaXMudHJpZ2dlckF0dGFjaztcbiAgICAgICAgdGhpcy5fb3JpZ2luYWxfdHJpZ2dlclJlbGVhc2UgPSB0aGlzLnRyaWdnZXJSZWxlYXNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBpbnN0cnVtZW50IHRvIHRoZSBUcmFuc3BvcnQuIEFsbCBzdWJzZXF1ZW50IGNhbGxzIG9mXG4gICAgICogW1t0cmlnZ2VyQXR0YWNrXV0gYW5kIFtbdHJpZ2dlclJlbGVhc2VdXSB3aWxsIGJlIHNjaGVkdWxlZCBhbG9uZyB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZm1TeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogZm1TeW50aC52b2x1bWUudmFsdWUgPSAtNjtcbiAgICAgKiBmbVN5bnRoLnN5bmMoKTtcbiAgICAgKiAvLyBzY2hlZHVsZSAzIG5vdGVzIHdoZW4gdGhlIHRyYW5zcG9ydCBmaXJzdCBzdGFydHNcbiAgICAgKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiLCAwKTtcbiAgICAgKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiRTRcIiwgXCI4blwiLCBcIjhuXCIpO1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJHNFwiLCBcIjhuXCIsIFwiNG5cIik7XG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydCB0byBoZWFyIHRoZSBub3Rlc1xuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAxKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogc2V0IF9zeW5jXG4gICAgICovXG4gICAgX3N5bmNTdGF0ZSgpIHtcbiAgICAgICAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZCA9IHRydWU7XG4gICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hhbmdlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV3JhcCB0aGUgZ2l2ZW4gbWV0aG9kIHNvIHRoYXQgaXQgY2FuIGJlIHN5bmNocm9uaXplZFxuICAgICAqIEBwYXJhbSBtZXRob2QgV2hpY2ggbWV0aG9kIHRvIHdyYXAgYW5kIHN5bmNcbiAgICAgKiBAcGFyYW0gIHRpbWVQb3NpdGlvbiBXaGF0IHBvc2l0aW9uIHRoZSB0aW1lIGFyZ3VtZW50IGFwcGVhcnMgaW5cbiAgICAgKi9cbiAgICBfc3luY01ldGhvZChtZXRob2QsIHRpbWVQb3NpdGlvbikge1xuICAgICAgICBjb25zdCBvcmlnaW5hbE1ldGhvZCA9IHRoaXNbXCJfb3JpZ2luYWxfXCIgKyBtZXRob2RdID0gdGhpc1ttZXRob2RdO1xuICAgICAgICB0aGlzW21ldGhvZF0gPSAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGltZSA9IGFyZ3NbdGltZVBvc2l0aW9uXTtcbiAgICAgICAgICAgIGNvbnN0IGlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSgodCkgPT4ge1xuICAgICAgICAgICAgICAgIGFyZ3NbdGltZVBvc2l0aW9uXSA9IHQ7XG4gICAgICAgICAgICAgICAgb3JpZ2luYWxNZXRob2QuYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICB9LCB0aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cy5wdXNoKGlkKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBpbnN0cnVtZW50IGZyb20gdGhlIFRyYW5zcG9ydFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzLmZvckVhY2goaWQgPT4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihpZCkpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sgPSB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyQXR0YWNrO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSA9IHRoaXMuX29yaWdpbmFsX3RyaWdnZXJSZWxlYXNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgYW5kIHRoZW4gdGhlIHJlbGVhc2UgYWZ0ZXIgdGhlIGR1cmF0aW9uLlxuICAgICAqIEBwYXJhbSAgbm90ZSAgICAgVGhlIG5vdGUgdG8gdHJpZ2dlci5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBub3RlIHNob3VsZCBiZSBoZWxkIGZvciBiZWZvcmVcbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyaW5nIHRoZSByZWxlYXNlLiBUaGlzIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAuXG4gICAgICogQHBhcmFtIHRpbWUgIFdoZW4gdGhlIG5vdGUgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkIGF0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIFwiQzRcIiBmb3IgdGhlIGR1cmF0aW9uIG9mIGFuIDh0aCBub3RlXG4gICAgICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGUsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWREdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKG5vdGUsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKGNvbXB1dGVkVGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKiBAcmV0dXJucyB7SW5zdHJ1bWVudH0gdGhpc1xuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUluc3RydW1lbnQuanMubWFwIiwiaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi4vaW5zdHJ1bWVudC9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBBYnN0cmFjdCBiYXNlIGNsYXNzIGZvciBvdGhlciBtb25vcGhvbmljIGluc3RydW1lbnRzIHRvIGV4dGVuZC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm9waG9uaWMgZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5wb3J0YW1lbnRvID0gb3B0aW9ucy5wb3J0YW1lbnRvO1xuICAgICAgICB0aGlzLm9uc2lsZW5jZSA9IG9wdGlvbnMub25zaWxlbmNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgb25zaWxlbmNlOiBub09wLFxuICAgICAgICAgICAgcG9ydGFtZW50bzogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBvZiB0aGUgbm90ZSBvcHRpb25hbGx5IHdpdGggYSBnaXZlbiB2ZWxvY2l0eS5cbiAgICAgKiBAcGFyYW0gIG5vdGUgVGhlIG5vdGUgdG8gdHJpZ2dlci5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgbm90ZSBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgc2NhbGVyIGRldGVybWluZXMgaG93IFwibG91ZFwiIHRoZSBub3RlIHdpbGwgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSBub3RlIGEgaGFsZiBzZWNvbmQgZnJvbSBub3cgYXQgaGFsZiB2ZWxvY2l0eVxuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soXCJDNFwiLCBcIiswLjVcIiwgMC41KTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZSwgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayhzZWNvbmRzLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMuc2V0Tm90ZShub3RlLCBzZWNvbmRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gIHRpbWUgSWYgbm8gdGltZSBpcyBnaXZlbiwgdGhlIHJlbGVhc2UgaGFwcGVucyBpbW1lZGlhdGx5XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soXCJDNFwiKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIGEgc2Vjb25kIGZyb20gbm93XG4gICAgICogc3ludGgudHJpZ2dlclJlbGVhc2UoXCIrMVwiKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlclJlbGVhc2VcIiwgdGltZSk7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZShzZWNvbmRzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgbm90ZSBhdCB0aGUgZ2l2ZW4gdGltZS4gSWYgbm8gdGltZSBpcyBnaXZlbiwgdGhlIG5vdGVcbiAgICAgKiB3aWxsIHNldCBpbW1lZGlhdGVseS5cbiAgICAgKiBAcGFyYW0gbm90ZSBUaGUgbm90ZSB0byBjaGFuZ2UgdG8uXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIG5vdGUgc2hvdWxkIGJlIHNldC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIpO1xuICAgICAqIC8vIGNoYW5nZSB0byBGIzYgaW4gb25lIHF1YXJ0ZXIgbm90ZSBmcm9tIG5vdy5cbiAgICAgKiBzeW50aC5zZXROb3RlKFwiRiM2XCIsIFwiKzRuXCIpO1xuICAgICAqL1xuICAgIHNldE5vdGUobm90ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRGcmVxdWVuY3kgPSBub3RlIGluc3RhbmNlb2YgRnJlcXVlbmN5Q2xhc3MgPyBub3RlLnRvRnJlcXVlbmN5KCkgOiBub3RlO1xuICAgICAgICBpZiAodGhpcy5wb3J0YW1lbnRvID4gMCAmJiB0aGlzLmdldExldmVsQXRUaW1lKGNvbXB1dGVkVGltZSkgPiAwLjA1KSB7XG4gICAgICAgICAgICBjb25zdCBwb3J0VGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMucG9ydGFtZW50byk7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5leHBvbmVudGlhbFJhbXBUbyhjb21wdXRlZEZyZXF1ZW5jeSwgcG9ydFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShjb21wdXRlZEZyZXF1ZW5jeSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIE1vbm9waG9uaWMucHJvdG90eXBlLCBcInBvcnRhbWVudG9cIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vbm9waG9uaWMuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuL0VudmVsb3BlXCI7XG4vKipcbiAqIEFtcGxpdHVkZUVudmVsb3BlIGlzIGEgVG9uZS5FbnZlbG9wZSBjb25uZWN0ZWQgdG8gYSBnYWluIG5vZGUuXG4gKiBVbmxpa2UgVG9uZS5FbnZlbG9wZSwgd2hpY2ggb3V0cHV0cyB0aGUgZW52ZWxvcGUncyB2YWx1ZSwgQW1wbGl0dWRlRW52ZWxvcGUgYWNjZXB0c1xuICogYW4gYXVkaW8gc2lnbmFsIGFzIHRoZSBpbnB1dCBhbmQgd2lsbCBhcHBseSB0aGUgZW52ZWxvcGUgdG8gdGhlIGFtcGxpdHVkZVxuICogb2YgdGhlIHNpZ25hbC5cbiAqIFJlYWQgbW9yZSBhYm91dCBBRFNSIEVudmVsb3BlcyBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TeW50aGVzaXplciNBRFNSX2VudmVsb3BlKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFtcEVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKHtcbiAqIFx0XHRhdHRhY2s6IDAuMSxcbiAqIFx0XHRkZWNheTogMC4yLFxuICogXHRcdHN1c3RhaW46IDEuMCxcbiAqIFx0XHRyZWxlYXNlOiAwLjhcbiAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBjcmVhdGUgYW4gb3NjaWxsYXRvciBhbmQgY29ubmVjdCBpdFxuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhbXBFbnYpLnN0YXJ0KCk7XG4gKiBcdC8vIHRyaWdnZXIgdGhlIGVudmVsb3BlcyBhdHRhY2sgYW5kIHJlbGVhc2UgXCI4dFwiIGFwYXJ0XG4gKiBcdGFtcEVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIjh0XCIpO1xuICogfSwgMS41LCAxKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFtcGxpdHVkZUVudmVsb3BlIGV4dGVuZHMgRW52ZWxvcGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBbXBsaXR1ZGVFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBbXBsaXR1ZGVFbnZlbG9wZVwiO1xuICAgICAgICB0aGlzLl9nYWluTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuX3NpZy5jb25uZWN0KHRoaXMuX2dhaW5Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFtcGxpdHVkZUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG4vKipcbiAqIFN5bnRoIGlzIGNvbXBvc2VkIHNpbXBseSBvZiBhIFtbT21uaU9zY2lsbGF0b3JdXSByb3V0ZWQgdGhyb3VnaCBhbiBbW0FtcGxpdHVkZUVudmVsb3BlXV0uXG4gKiBgYGBcbiAqICstLS0tLS0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCBPbW5pT3NjaWxsYXRvciArPi0tPiBBbXBsaXR1ZGVFbnZlbG9wZSArPi0tPiBPdXRwdXRcbiAqICstLS0tLS0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gbmV3IE9tbmlPc2NpbGxhdG9yKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcyksXG4gICAgICAgIH0sIG9wdGlvbnMub3NjaWxsYXRvcikpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5vc2NpbGxhdG9yLmRldHVuZTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBBbXBsaXR1ZGVFbnZlbG9wZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5lbnZlbG9wZSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBvc2NpbGxhdG9ycyB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5jaGFpbih0aGlzLmVudmVsb3BlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm9zY2lsbGF0b3JcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJlbnZlbG9wZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDUsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuMyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBbLi4uT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInRyaWFuZ2xlXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgYXR0YWNrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSB0aGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUgKDAtMSlcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIHRoZSBlbnZlbG9wZXNcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyByZWxlYXNlIHBvcnRpb24sIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRBdHRhY2sgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjayk7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZERlY2F5ID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5kZWNheSk7XG4gICAgICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgY29tcHV0ZWRBdHRhY2sgKyBjb21wdXRlZERlY2F5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSByZWxlYXNlIHNob3VsZCBzdGFydFxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3ludGguanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuaW1wb3J0IHsgT21uaU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGJvdGggQU0gYW5kIEZNIHN5bnRoc1xuICovXG5leHBvcnQgY2xhc3MgTW9kdWxhdGlvblN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb2R1bGF0aW9uU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IFN5bnRoKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IG9wdGlvbnMub3NjaWxsYXRvcixcbiAgICAgICAgICAgIGVudmVsb3BlOiBvcHRpb25zLmVudmVsb3BlLFxuICAgICAgICAgICAgb25zaWxlbmNlOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgICAgIHZvbHVtZTogLTEwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IFN5bnRoKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IG9wdGlvbnMubW9kdWxhdGlvbixcbiAgICAgICAgICAgIGVudmVsb3BlOiBvcHRpb25zLm1vZHVsYXRpb25FbnZlbG9wZSxcbiAgICAgICAgICAgIHZvbHVtZTogLTEwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gdGhpcy5fY2Fycmllci5vc2NpbGxhdG9yO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gdGhpcy5fY2Fycmllci5lbnZlbG9wZTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uID0gdGhpcy5fbW9kdWxhdG9yLm9zY2lsbGF0b3I7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkVudmVsb3BlID0gdGhpcy5fbW9kdWxhdG9yLmVudmVsb3BlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgICAgIG1pblZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiaGFybW9uaWNpdHlcIiwgXCJvc2NpbGxhdG9yXCIsIFwiZW52ZWxvcGVcIiwgXCJtb2R1bGF0aW9uXCIsIFwibW9kdWxhdGlvbkVudmVsb3BlXCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAzLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBbXG4gICAgICAgICAgICAgICAgLi4uT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpLFxuICAgICAgICAgICAgICAgIFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICAgICAgXCJkZXR1bmVcIlxuICAgICAgICAgICAgXSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNpbmVcIlxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4wMSxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtb2R1bGF0aW9uOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFtcbiAgICAgICAgICAgICAgICAuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksXG4gICAgICAgICAgICAgICAgXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgICAgICBcImRldHVuZVwiXG4gICAgICAgICAgICBdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic3F1YXJlXCJcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjUsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2NhcnJpZXIuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fY2Fycmllci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb2R1bGF0aW9uU3ludGguanMubWFwIiwiaW1wb3J0IHsgQXVkaW9Ub0dhaW4gfSBmcm9tIFwiLi4vc2lnbmFsL0F1ZGlvVG9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1vZHVsYXRpb25TeW50aCB9IGZyb20gXCIuL01vZHVsYXRpb25TeW50aFwiO1xuLyoqXG4gKiBBTVN5bnRoIHVzZXMgdGhlIG91dHB1dCBvZiBvbmUgVG9uZS5TeW50aCB0byBtb2R1bGF0ZSB0aGVcbiAqIGFtcGxpdHVkZSBvZiBhbm90aGVyIFRvbmUuU3ludGguIFRoZSBoYXJtb25pY2l0eSAodGhlIHJhdGlvIGJldHdlZW5cbiAqIHRoZSB0d28gc2lnbmFscykgYWZmZWN0cyB0aGUgdGltYnJlIG9mIHRoZSBvdXRwdXQgc2lnbmFsIGdyZWF0bHkuXG4gKiBSZWFkIG1vcmUgYWJvdXQgQW1wbGl0dWRlIE1vZHVsYXRpb24gU3ludGhlc2lzIG9uXG4gKiBbU291bmRPblNvdW5kXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDQxMDM2NTMvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tOjgwL3Nvcy9tYXIwMC9hcnRpY2xlcy9zeW50aHNlY3JldHMuaHRtKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5BTVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjRuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBTVN5bnRoIGV4dGVuZHMgTW9kdWxhdGlvblN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQU1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBTVN5bnRoXCI7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZSA9IG5ldyBBdWRpb1RvR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLl9jYXJyaWVyLmRldHVuZSwgdGhpcy5fbW9kdWxhdG9yLmRldHVuZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uU2NhbGUsIHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNoYWluKHRoaXMuX21vZHVsYXRpb25Ob2RlLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QU1TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBUaGluIHdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgV2ViIEF1ZGlvIFtCaXF1YWRGaWx0ZXJOb2RlXShodHRwczovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNiaXF1YWRmaWx0ZXJub2RlKS5cbiAqIEJpcXVhZEZpbHRlciBpcyBzaW1pbGFyIHRvIFtbRmlsdGVyXV0gYnV0IGRvZXNuJ3QgaGF2ZSB0aGUgb3B0aW9uIHRvIHNldCB0aGUgXCJyb2xsb2ZmXCIgdmFsdWUuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBCaXF1YWRGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQmlxdWFkRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkJpcXVhZEZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQmlxdWFkRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fZmlsdGVyO1xuICAgICAgICB0aGlzLlEgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2ZpbHRlci5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5nYWluLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2ZpbHRlci5nYWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAzNTAsXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhpcyBCaXF1YWRGaWx0ZXJOb2RlLiBGb3IgYSBjb21wbGV0ZSBsaXN0IG9mIHR5cGVzIGFuZCB0aGVpciBhdHRyaWJ1dGVzLCBzZWUgdGhlXG4gICAgICogW1dlYiBBdWRpbyBBUEldKGh0dHBzOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI2RvbS1iaXF1YWRmaWx0ZXJ0eXBlLWxvd3Bhc3MpXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBjb25zdCB0eXBlcyA9IFtcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLCBcImJhbmRwYXNzXCIsXG4gICAgICAgICAgICBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIFwicGVha2luZ1wiXTtcbiAgICAgICAgYXNzZXJ0KHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xLCBgSW52YWxpZCBmaWx0ZXIgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl9maWx0ZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIC8vIHN0YXJ0IHdpdGggYWxsIDFzXG4gICAgICAgIGNvbnN0IGZyZXFWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm0gPSBNYXRoLnBvdyhpIC8gbGVuLCAyKTtcbiAgICAgICAgICAgIGNvbnN0IGZyZXEgPSBub3JtICogKDIwMDAwIC0gMjApICsgMjA7XG4gICAgICAgICAgICBmcmVxVmFsdWVzW2ldID0gZnJlcTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYWdWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGNvbnN0IHBoYXNlVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICAvLyBjbG9uZSB0aGUgZmlsdGVyIHRvIHJlbW92ZSBhbnkgY29ubmVjdGlvbnMgd2hpY2ggbWF5IGJlIGNoYW5naW5nIHRoZSB2YWx1ZVxuICAgICAgICBjb25zdCBmaWx0ZXJDbG9uZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgZmlsdGVyQ2xvbmUudHlwZSA9IHRoaXMudHlwZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuUS52YWx1ZSA9IHRoaXMuUS52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZnJlcXVlbmN5LnZhbHVlID0gdGhpcy5mcmVxdWVuY3kudmFsdWU7XG4gICAgICAgIGZpbHRlckNsb25lLmdhaW4udmFsdWUgPSB0aGlzLmdhaW4udmFsdWU7XG4gICAgICAgIGZpbHRlckNsb25lLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXFWYWx1ZXMsIG1hZ1ZhbHVlcywgcGhhc2VWYWx1ZXMpO1xuICAgICAgICByZXR1cm4gbWFnVmFsdWVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1CaXF1YWRGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSwgd3JpdGFibGUgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNOdW1iZXIgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IEJpcXVhZEZpbHRlciB9IGZyb20gXCIuL0JpcXVhZEZpbHRlclwiO1xuLyoqXG4gKiBUb25lLkZpbHRlciBpcyBhIGZpbHRlciB3aGljaCBhbGxvd3MgZm9yIGFsbCBvZiB0aGUgc2FtZSBuYXRpdmUgbWV0aG9kc1xuICogYXMgdGhlIFtCaXF1YWRGaWx0ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1iaXF1YWRmaWx0ZXJub2RlLWludGVyZmFjZSkuXG4gKiBUb25lLkZpbHRlciBoYXMgdGhlIGFkZGVkIGFiaWxpdHkgdG8gc2V0IHRoZSBmaWx0ZXIgcm9sbG9mZiBhdCAtMTJcbiAqIChkZWZhdWx0KSwgLTI0IGFuZCAtNDguXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmlsdGVyID0gbmV3IFRvbmUuRmlsdGVyKDE1MDAsIFwiaGlnaHBhc3NcIikudG9EZXN0aW5hdGlvbigpO1xuICogZmlsdGVyLmZyZXF1ZW5jeS5yYW1wVG8oMjAwMDAsIDEwKTtcbiAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS5jb25uZWN0KGZpbHRlcikuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwicm9sbG9mZlwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZpbHRlclwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJyb2xsb2ZmXCJdKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycyA9IFtdO1xuICAgICAgICB0aGlzLlEgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdhaW4gPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLnJvbGxvZmYgPSBvcHRpb25zLnJvbGxvZmY7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImRldHVuZVwiLCBcImZyZXF1ZW5jeVwiLCBcImdhaW5cIiwgXCJRXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgICAgICByb2xsb2ZmOiAtMTIsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBmaWx0ZXIuIFR5cGVzOiBcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLFxuICAgICAqIFwiYmFuZHBhc3NcIiwgXCJsb3dzaGVsZlwiLCBcImhpZ2hzaGVsZlwiLCBcIm5vdGNoXCIsIFwiYWxscGFzc1wiLCBvciBcInBlYWtpbmdcIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgY29uc3QgdHlwZXMgPSBbXCJsb3dwYXNzXCIsIFwiaGlnaHBhc3NcIiwgXCJiYW5kcGFzc1wiLFxuICAgICAgICAgICAgXCJsb3dzaGVsZlwiLCBcImhpZ2hzaGVsZlwiLCBcIm5vdGNoXCIsIFwiYWxscGFzc1wiLCBcInBlYWtpbmdcIl07XG4gICAgICAgIGFzc2VydCh0eXBlcy5pbmRleE9mKHR5cGUpICE9PSAtMSwgYEludmFsaWQgZmlsdGVyIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4gZmlsdGVyLnR5cGUgPSB0eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHJvbGxvZmYgb2YgdGhlIGZpbHRlciB3aGljaCBpcyB0aGUgZHJvcCBpbiBkYlxuICAgICAqIHBlciBvY3RhdmUuIEltcGxlbWVudGVkIGludGVybmFsbHkgYnkgY2FzY2FkaW5nIGZpbHRlcnMuXG4gICAgICogT25seSBhY2NlcHRzIHRoZSB2YWx1ZXMgLTEyLCAtMjQsIC00OCBhbmQgLTk2LlxuICAgICAqL1xuICAgIGdldCByb2xsb2ZmKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcm9sbG9mZjtcbiAgICB9XG4gICAgc2V0IHJvbGxvZmYocm9sbG9mZikge1xuICAgICAgICBjb25zdCByb2xsb2ZmTnVtID0gaXNOdW1iZXIocm9sbG9mZikgPyByb2xsb2ZmIDogcGFyc2VJbnQocm9sbG9mZiwgMTApO1xuICAgICAgICBjb25zdCBwb3NzaWJpbGl0aWVzID0gWy0xMiwgLTI0LCAtNDgsIC05Nl07XG4gICAgICAgIGxldCBjYXNjYWRpbmdDb3VudCA9IHBvc3NpYmlsaXRpZXMuaW5kZXhPZihyb2xsb2ZmTnVtKTtcbiAgICAgICAgLy8gY2hlY2sgdGhlIHJvbGxvZmYgaXMgdmFsaWRcbiAgICAgICAgYXNzZXJ0KGNhc2NhZGluZ0NvdW50ICE9PSAtMSwgYHJvbGxvZmYgY2FuIG9ubHkgYmUgJHtwb3NzaWJpbGl0aWVzLmpvaW4oXCIsIFwiKX1gKTtcbiAgICAgICAgY2FzY2FkaW5nQ291bnQgKz0gMTtcbiAgICAgICAgdGhpcy5fcm9sbG9mZiA9IHJvbGxvZmZOdW07XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IGZpbHRlci5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzID0gbmV3IEFycmF5KGNhc2NhZGluZ0NvdW50KTtcbiAgICAgICAgZm9yIChsZXQgY291bnQgPSAwOyBjb3VudCA8IGNhc2NhZGluZ0NvdW50OyBjb3VudCsrKSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBuZXcgQmlxdWFkRmlsdGVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGZpbHRlci50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QoZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KGZpbHRlci5kZXR1bmUpO1xuICAgICAgICAgICAgdGhpcy5RLmNvbm5lY3QoZmlsdGVyLlEpO1xuICAgICAgICAgICAgdGhpcy5nYWluLmNvbm5lY3QoZmlsdGVyLmdhaW4pO1xuICAgICAgICAgICAgdGhpcy5fZmlsdGVyc1tjb3VudF0gPSBmaWx0ZXI7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IHRoaXMuX2ZpbHRlcnM7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgLi4udGhpcy5faW50ZXJuYWxDaGFubmVscywgdGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZS4gVGhpcyBjdXJ2ZSByZXByZXNlbnRzIGhvdyB0aGUgZmlsdGVyXG4gICAgICogcmVzcG9uc2VzIHRvIGZyZXF1ZW5jaWVzIGJldHdlZW4gMjBoei0yMGtoei5cbiAgICAgKiBAcGFyYW0gIGxlbiBUaGUgbnVtYmVyIG9mIHZhbHVlcyB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUgYmV0d2VlbiAyMC0yMGtIelxuICAgICAqL1xuICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGxlbiA9IDEyOCkge1xuICAgICAgICBjb25zdCBmaWx0ZXJDbG9uZSA9IG5ldyBCaXF1YWRGaWx0ZXIoe1xuICAgICAgICAgICAgZnJlcXVlbmN5OiB0aGlzLmZyZXF1ZW5jeS52YWx1ZSxcbiAgICAgICAgICAgIGdhaW46IHRoaXMuZ2Fpbi52YWx1ZSxcbiAgICAgICAgICAgIFE6IHRoaXMuUS52YWx1ZSxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMuX3R5cGUsXG4gICAgICAgICAgICBkZXR1bmU6IHRoaXMuZGV0dW5lLnZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhbGwgMXNcbiAgICAgICAgY29uc3QgdG90YWxSZXNwb25zZSA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKS5tYXAoKCkgPT4gMSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaCgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGZpbHRlckNsb25lLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGxlbik7XG4gICAgICAgICAgICByZXNwb25zZS5mb3JFYWNoKCh2YWwsIGkpID0+IHRvdGFsUmVzcG9uc2VbaV0gKj0gdmFsKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGZpbHRlckNsb25lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRvdGFsUmVzcG9uc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICAgICAgICBmaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgW1wiZGV0dW5lXCIsIFwiZnJlcXVlbmN5XCIsIFwiZ2FpblwiLCBcIlFcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NjYWxlXCI7XG5pbXBvcnQgeyBQb3cgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1Bvd1wiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEZyZXF1ZW5jeUVudmVsb3BlIGlzIGFuIFtbRW52ZWxvcGVdXSB3aGljaCByYW1wcyBiZXR3ZWVuIFtbYmFzZUZyZXF1ZW5jeV1dXG4gKiBhbmQgW1tvY3RhdmVzXV0uIEl0IGNhbiBhbHNvIGhhdmUgYW4gb3B0aW9uYWwgW1tleHBvbmVudF1dIHRvIGFkanVzdCB0aGUgY3VydmVcbiAqIHdoaWNoIGl0IHJhbXBzLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBjb25zdCBmcmVxRW52ID0gbmV3IFRvbmUuRnJlcXVlbmN5RW52ZWxvcGUoe1xuICogXHRhdHRhY2s6IDAuMixcbiAqIFx0YmFzZUZyZXF1ZW5jeTogXCJDMlwiLFxuICogXHRvY3RhdmVzOiA0XG4gKiB9KTtcbiAqIGZyZXFFbnYuY29ubmVjdChvc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG4gKiBmcmVxRW52LnRyaWdnZXJBdHRhY2soKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZXF1ZW5jeUVudmVsb3BlIGV4dGVuZHMgRW52ZWxvcGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lFbnZlbG9wZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5RW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSB0aGlzLmlucHV0ID0gbmV3IFBvdyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5leHBvbmVudFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGUgPSB0aGlzLm91dHB1dCA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IHRoaXMuX2Jhc2VGcmVxdWVuY3ksXG4gICAgICAgICAgICBtYXg6IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCB0aGlzLl9vY3RhdmVzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpZy5jaGFpbih0aGlzLl9leHBvbmVudCwgdGhpcy5fc2NhbGUpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVudmVsb3BlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAgICAgICAgICAgIGV4cG9uZW50OiAxLFxuICAgICAgICAgICAgb2N0YXZlczogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBlbnZlbG9wZSdzIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIGlzIHRoZSB2YWx1ZSB3aGljaCBpdFxuICAgICAqIHN0YXJ0cyBhdC5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KG1pbikge1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeShtaW4pO1xuICAgICAgICBhc3NlcnRSYW5nZShmcmVxLCAwKTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IGZyZXE7XG4gICAgICAgIHRoaXMuX3NjYWxlLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgbWF4IHZhbHVlIHdoZW4gdGhlIG1pbiBjaGFuZ2VzXG4gICAgICAgIHRoaXMub2N0YXZlcyA9IHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeSB0aGF0IHRoZVxuICAgICAqIGVudmVsb3BlIHdpbGwgc2NhbGUgdG8uXG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyhvY3RhdmVzKSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3RhdmVzO1xuICAgICAgICB0aGlzLl9zY2FsZS5tYXggPSB0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgb2N0YXZlcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBlbnZlbG9wZSdzIGV4cG9uZW50IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBleHBvbmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cG9uZW50LnZhbHVlO1xuICAgIH1cbiAgICBzZXQgZXhwb25lbnQoZXhwb25lbnQpIHtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQudmFsdWUgPSBleHBvbmVudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3lFbnZlbG9wZS5qcy5tYXAiLCJpbXBvcnQgeyBBbXBsaXR1ZGVFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGVcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4uL2luc3RydW1lbnQvTW9ub3Bob25pY1wiO1xuaW1wb3J0IHsgT21uaU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRnJlcXVlbmN5RW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogTW9ub1N5bnRoIGlzIGNvbXBvc2VkIG9mIG9uZSBgb3NjaWxsYXRvcmAsIG9uZSBgZmlsdGVyYCwgYW5kIHR3byBgZW52ZWxvcGVzYC5cbiAqIFRoZSBhbXBsaXR1ZGUgb2YgdGhlIE9zY2lsbGF0b3IgYW5kIHRoZSBjdXRvZmYgZnJlcXVlbmN5IG9mIHRoZVxuICogRmlsdGVyIGFyZSBjb250cm9sbGVkIGJ5IEVudmVsb3Blcy5cbiAqIDxpbWcgc3JjPVwiaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZHJhd2luZ3MvZC8xZ2FZMURGOV9IemtvZHFmOEpJMUNnMlZaZndTRWxwRlFmSTk0SVF3YWQzOC9wdWI/dz05MjQmaD0yNDBcIj5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1vbm9TeW50aCh7XG4gKiBcdG9zY2lsbGF0b3I6IHtcbiAqIFx0XHR0eXBlOiBcInNxdWFyZVwiXG4gKiBcdH0sXG4gKiBcdGVudmVsb3BlOiB7XG4gKiBcdFx0YXR0YWNrOiAwLjFcbiAqIFx0fVxuICogfSkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm9TeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTW9ub1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yID0gbmV3IE9tbmlPc2NpbGxhdG9yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5vc2NpbGxhdG9yLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5vc2NpbGxhdG9yLmRldHVuZTtcbiAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXIsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZSA9IG5ldyBGcmVxdWVuY3lFbnZlbG9wZShPYmplY3QuYXNzaWduKG9wdGlvbnMuZmlsdGVyRW52ZWxvcGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBBbXBsaXR1ZGVFbnZlbG9wZShPYmplY3QuYXNzaWduKG9wdGlvbnMuZW52ZWxvcGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgb3NjaWxsYXRvcnMgdG8gdGhlIG91dHB1dFxuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuY2hhaW4odGhpcy5maWx0ZXIsIHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgZmlsdGVyIGVudmVsb3BlXG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUuY29ubmVjdCh0aGlzLmZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJvc2NpbGxhdG9yXCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiZmlsdGVyXCIsIFwiZmlsdGVyRW52ZWxvcGVcIiwgXCJlbnZlbG9wZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDUsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuOSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZmlsdGVyOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEZpbHRlci5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICAgICAgcm9sbG9mZjogLTEyLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC42LFxuICAgICAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4yLFxuICAgICAgICAgICAgICAgIGV4cG9uZW50OiAyLFxuICAgICAgICAgICAgICAgIG9jdGF2ZXM6IDMsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMixcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZSAoMC0xKVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkRGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KTtcbiAgICAgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyBjb21wdXRlZEF0dGFjayArIGNvbXB1dGVkRGVjYXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9ub1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBNb25vU3ludGggfSBmcm9tIFwiLi9Nb25vU3ludGhcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBHYWluLCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogRHVvU3ludGggaXMgYSBtb25vcGhvbmljIHN5bnRoIGNvbXBvc2VkIG9mIHR3byBbW01vbm9TeW50aHNdXSBydW4gaW4gcGFyYWxsZWwgd2l0aCBjb250cm9sIG92ZXIgdGhlXG4gKiBmcmVxdWVuY3kgcmF0aW8gYmV0d2VlbiB0aGUgdHdvIHZvaWNlcyBhbmQgdmlicmF0byBlZmZlY3QuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZHVvU3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGR1b1N5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCIyblwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBEdW9TeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEdW9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEdW9TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRHVvU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy52b2ljZTAgPSBuZXcgTW9ub1N5bnRoKE9iamVjdC5hc3NpZ24ob3B0aW9ucy52b2ljZTAsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9uc2lsZW5jZTogKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcylcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLnZvaWNlMSA9IG5ldyBNb25vU3ludGgoT2JqZWN0LmFzc2lnbihvcHRpb25zLnZvaWNlMSwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdmlicmF0byA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLnZpYnJhdG9SYXRlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAtNTAsXG4gICAgICAgICAgICBtYXg6IDUwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB0aGUgdmlicmF0byBpbW1lZGlhdGVseVxuICAgICAgICB0aGlzLl92aWJyYXRvLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMudmlicmF0b1JhdGUgPSB0aGlzLl92aWJyYXRvLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fdmlicmF0b0dhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy52aWJyYXRvQW1vdW50XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZpYnJhdG9BbW91bnQgPSB0aGlzLl92aWJyYXRvR2Fpbi5nYWluO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogNDQwXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29udHJvbCB0aGUgdHdvIHZvaWNlcyBmcmVxdWVuY3lcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLnZvaWNlMC5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLnZvaWNlMS5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl92aWJyYXRvLmNvbm5lY3QodGhpcy5fdmlicmF0b0dhaW4pO1xuICAgICAgICB0aGlzLl92aWJyYXRvR2Fpbi5mYW4odGhpcy52b2ljZTAuZGV0dW5lLCB0aGlzLnZvaWNlMS5kZXR1bmUpO1xuICAgICAgICB0aGlzLmRldHVuZS5mYW4odGhpcy52b2ljZTAuZGV0dW5lLCB0aGlzLnZvaWNlMS5kZXR1bmUpO1xuICAgICAgICB0aGlzLnZvaWNlMC5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy52b2ljZTEuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInZvaWNlMFwiLCBcInZvaWNlMVwiLCBcImZyZXF1ZW5jeVwiLCBcInZpYnJhdG9BbW91bnRcIiwgXCJ2aWJyYXRvUmF0ZVwiXSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy52b2ljZTAuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgKyB0aGlzLnZvaWNlMS5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmlicmF0b0Ftb3VudDogMC41LFxuICAgICAgICAgICAgdmlicmF0b1JhdGU6IDUsXG4gICAgICAgICAgICBoYXJtb25pY2l0eTogMS41LFxuICAgICAgICAgICAgdm9pY2UwOiBkZWVwTWVyZ2Uob21pdEZyb21PYmplY3QoTW9ub1N5bnRoLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgZmlsdGVyRW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB2b2ljZTE6IGRlZXBNZXJnZShvbWl0RnJvbU9iamVjdChNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMudm9pY2UwLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMudm9pY2UxLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTAuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTEuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9pY2UwLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2ljZTEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdmlicmF0by5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudmlicmF0b1JhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92aWJyYXRvR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EdW9TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgTW9kdWxhdGlvblN5bnRoIH0gZnJvbSBcIi4vTW9kdWxhdGlvblN5bnRoXCI7XG4vKipcbiAqIEZNU3ludGggaXMgY29tcG9zZWQgb2YgdHdvIFRvbmUuU3ludGhzIHdoZXJlIG9uZSBUb25lLlN5bnRoIG1vZHVsYXRlc1xuICogdGhlIGZyZXF1ZW5jeSBvZiBhIHNlY29uZCBUb25lLlN5bnRoLiBBIGxvdCBvZiBzcGVjdHJhbCBjb250ZW50XG4gKiBjYW4gYmUgZXhwbG9yZWQgdXNpbmcgdGhlIG1vZHVsYXRpb25JbmRleCBwYXJhbWV0ZXIuIFJlYWQgbW9yZSBhYm91dFxuICogZnJlcXVlbmN5IG1vZHVsYXRpb24gc3ludGhlc2lzIG9uIFNvdW5kIE9uIFNvdW5kOiBbUGFydCAxXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDMxMjM3MDQvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9hcHIwMC9hcnRpY2xlcy9zeW50aHNlY3JldHMuaHRtKSwgW1BhcnQgMl0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDAzMTE1ODM1L2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvbWF5MDAvYXJ0aWNsZXMvc3ludGguaHRtKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZm1TeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzVcIiwgXCI0blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgRk1TeW50aCBleHRlbmRzIE1vZHVsYXRpb25TeW50aCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRk1TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMubW9kdWxhdGlvbkluZGV4LCB0aGlzLl9tb2R1bGF0aW9uTm9kZSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLl9jYXJyaWVyLmRldHVuZSwgdGhpcy5fbW9kdWxhdG9yLmRldHVuZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb2R1bGF0aW9uU3ludGguZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAxMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GTVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBGTU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvRk1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuLyoqXG4gKiBJbmhhcm1vbmljIHJhdGlvIG9mIGZyZXF1ZW5jaWVzIGJhc2VkIG9uIHRoZSBSb2xhbmQgVFItODA4XG4gKiBUYWtlbiBmcm9tIGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L3BhcGVycy90ci04MDgtY3ltYmFsLXBoeXNpY2FsbHktaW5mb3JtZWQtY2lyY3VpdC1iZW5kYWJsZS1kaWdpdGFsLW1vZGVsXG4gKi9cbmNvbnN0IGluaGFybVJhdGlvcyA9IFsxLjAsIDEuNDgzLCAxLjkzMiwgMi41NDYsIDIuNjMwLCAzLjg5N107XG4vKipcbiAqIEEgaGlnaGx5IGluaGFybW9uaWMgYW5kIHNwZWN0cmFsbHkgY29tcGxleCBzb3VyY2Ugd2l0aCBhIGhpZ2hwYXNzIGZpbHRlclxuICogYW5kIGFtcGxpdHVkZSBlbnZlbG9wZSB3aGljaCBpcyBnb29kIGZvciBtYWtpbmcgbWV0YWxsb3Bob25lIHNvdW5kcy5cbiAqIEJhc2VkIG9uIEN5bWJhbFN5bnRoIGJ5IFtAcG9seXJoeXRobWF0aWNdKGh0dHBzOi8vZ2l0aHViLmNvbS9wb2x5cmh5dGhtYXRpYykuXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtTb3VuZCBvbiBTb3VuZF0oaHR0cHM6Ly9zaG9ydHVybC5hdC9yU1oxMikuXG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTWV0YWxTeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRhbFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGFsU3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhcnJheSBvZiBGTU9zY2lsbGF0b3JzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGZyZXF1ZW5jeSBtdWx0aXBsaWVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRhbFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX2hpZ2hwYXNzID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICAvLyBROiAtMy4wMTAyOTk5NTY2Mzk4MTI1LFxuICAgICAgICAgICAgUTogMCxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IFwiaGlnaHBhc3NcIixcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluaGFybVJhdGlvcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgb3NjID0gbmV3IEZNT3NjaWxsYXRvcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGhhcm1vbmljaXR5OiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICAgICAgICAgIG1vZHVsYXRpb25JbmRleDogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgICAgICAgICAgbW9kdWxhdGlvblR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgICAgICAgICAgb25zdG9wOiBpID09PSAwID8gKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcykgOiBub09wLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwic3F1YXJlXCIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG9zYy5jb25uZWN0KHRoaXMuX2hpZ2hwYXNzKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldID0gb3NjO1xuICAgICAgICAgICAgY29uc3QgbXVsdCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIHZhbHVlOiBpbmhhcm1SYXRpb3NbaV0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVyc1tpXSA9IG11bHQ7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbihtdWx0LCBvc2MuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3Qob3NjLmRldHVuZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlciA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXg6IDcwMDAsXG4gICAgICAgICAgICBtaW46IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5yZXNvbmFuY2UpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBFbnZlbG9wZSh7XG4gICAgICAgICAgICBhdHRhY2s6IG9wdGlvbnMuZW52ZWxvcGUuYXR0YWNrLFxuICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwibGluZWFyXCIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZWNheTogb3B0aW9ucy5lbnZlbG9wZS5kZWNheSxcbiAgICAgICAgICAgIHJlbGVhc2U6IG9wdGlvbnMuZW52ZWxvcGUucmVsZWFzZSxcbiAgICAgICAgICAgIHN1c3RhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmNoYWluKHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIsIHRoaXMuX2hpZ2hwYXNzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGUuZ2Fpbik7XG4gICAgICAgIC8vIHNldCB0aGUgb2N0YXZlc1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBNZXJnZShNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwMSxcbiAgICAgICAgICAgICAgICBkZWNheTogMS40LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDUuMSxcbiAgICAgICAgICAgIG1vZHVsYXRpb25JbmRleDogMzIsXG4gICAgICAgICAgICBvY3RhdmVzOiAxLjUsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDQwMDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2suXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgYXR0YWNrIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0aGF0IHRoZSBlbnZlbG9wZSBzaG91bGQgYmUgdHJpZ2dlcmVkIGF0LlxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IG9zYy5zdGFydCh0aW1lKSk7XG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IHtcbiAgICAgICAgICAgICAgICBvc2Muc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5kZWNheSkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdGhlIHJlbGVhc2Ugc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IG9zYy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtb2R1bGF0aW9uSW5kZXggb2YgdGhlIG9zY2lsbGF0b3JzIHdoaWNoIG1ha2UgdXAgdGhlIHNvdXJjZS5cbiAgICAgKiBzZWUgW1tGTU9zY2lsbGF0b3IubW9kdWxhdGlvbkluZGV4XV1cbiAgICAgKiBAbWluIDFcbiAgICAgKiBAbWF4IDEwMFxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uSW5kZXgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5tb2R1bGF0aW9uSW5kZXgudmFsdWU7XG4gICAgfVxuICAgIHNldCBtb2R1bGF0aW9uSW5kZXgodmFsKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IChvc2MubW9kdWxhdGlvbkluZGV4LnZhbHVlID0gdmFsKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBoYXJtb25pY2l0eSBvZiB0aGUgb3NjaWxsYXRvcnMgd2hpY2ggbWFrZSB1cCB0aGUgc291cmNlLlxuICAgICAqIHNlZSBUb25lLkZNT3NjaWxsYXRvci5oYXJtb25pY2l0eVxuICAgICAqIEBtaW4gMC4xXG4gICAgICogQG1heCAxMFxuICAgICAqL1xuICAgIGdldCBoYXJtb25pY2l0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLmhhcm1vbmljaXR5LnZhbHVlO1xuICAgIH1cbiAgICBzZXQgaGFybW9uaWNpdHkodmFsKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IChvc2MuaGFybW9uaWNpdHkudmFsdWUgPSB2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvd2VyIGxldmVsIG9mIHRoZSBoaWdocGFzcyBmaWx0ZXIgd2hpY2ggaXMgYXR0YWNoZWQgdG8gdGhlIGVudmVsb3BlLlxuICAgICAqIFRoaXMgdmFsdWUgc2hvdWxkIGJlIGJldHdlZW4gWzAsIDcwMDBdXG4gICAgICogQG1pbiAwXG4gICAgICogQG1heCA3MDAwXG4gICAgICovXG4gICAgZ2V0IHJlc29uYW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluO1xuICAgIH1cbiAgICBzZXQgcmVzb25hbmNlKHZhbCkge1xuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbiA9IHRoaXMudG9GcmVxdWVuY3kodmFsKTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIGFib3ZlIHRoZSBcInJlc29uYW5jZVwiIGZyZXF1ZW5jeVxuICAgICAqIHRoYXQgdGhlIGZpbHRlciByYW1wcyBkdXJpbmcgdGhlIGF0dGFjay9kZWNheSBlbnZlbG9wZVxuICAgICAqIEBtaW4gMFxuICAgICAqIEBtYXggOFxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXModmFsKSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSB2YWw7XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWF4ID0gdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5taW4gKiBNYXRoLnBvdygyLCB2YWwpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzLmZvckVhY2gob3NjID0+IG9zYy5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9mcmVxTXVsdGlwbGllcnMuZm9yRWFjaChmcmVxTXVsdCA9PiBmcmVxTXVsdC5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9oaWdocGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1ldGFsU3ludGguanMubWFwIiwiaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyByYW5nZSwgdGltZVJhbmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbi8qKlxuICogTWVtYnJhbmVTeW50aCBtYWtlcyBraWNrIGFuZCB0b20gc291bmRzIHVzaW5nIGEgc2luZ2xlIG9zY2lsbGF0b3JcbiAqIHdpdGggYW4gYW1wbGl0dWRlIGVudmVsb3BlIGFuZCBmcmVxdWVuY3kgcmFtcC4gQSBUb25lLk9tbmlPc2NpbGxhdG9yXG4gKiBpcyByb3V0ZWQgdGhyb3VnaCBhIFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUgdG8gdGhlIG91dHB1dC4gVGhlIGRydW1cbiAqIHF1YWxpdHkgb2YgdGhlIHNvdW5kIGNvbWVzIGZyb20gdGhlIGZyZXF1ZW5jeSBlbnZlbG9wZSBhcHBsaWVkXG4gKiBkdXJpbmcgTWVtYnJhbmVTeW50aC50cmlnZ2VyQXR0YWNrKG5vdGUpLiBUaGUgZnJlcXVlbmN5IGVudmVsb3BlXG4gKiBzdGFydHMgYXQgPGNvZGU+bm90ZSAqIC5vY3RhdmVzPC9jb2RlPiBhbmQgcmFtcHMgdG8gPGNvZGU+bm90ZTwvY29kZT5cbiAqIG92ZXIgdGhlIGR1cmF0aW9uIG9mIDxjb2RlPi5waXRjaERlY2F5PC9jb2RlPi5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1lbWJyYW5lU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkMyXCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTWVtYnJhbmVTeW50aCBleHRlbmRzIFN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVtYnJhbmVTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZW1icmFuZVN5bnRoXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQb3J0YW1lbnRvIGlzIGlnbm9yZWQgaW4gdGhpcyBzeW50aC4gdXNlIHBpdGNoIGRlY2F5IGluc3RlYWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBvcnRhbWVudG8gPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVtYnJhbmVTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnBpdGNoRGVjYXkgPSBvcHRpb25zLnBpdGNoRGVjYXk7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wib3NjaWxsYXRvclwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwgU3ludGguZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDAxLFxuICAgICAgICAgICAgICAgIGF0dGFja0N1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAxLjQsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4wMSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBvY3RhdmVzOiAxMCxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwaXRjaERlY2F5OiAwLjA1LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2V0Tm90ZShub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgaGVydHogPSB0aGlzLnRvRnJlcXVlbmN5KG5vdGUgaW5zdGFuY2VvZiBGcmVxdWVuY3lDbGFzcyA/IG5vdGUudG9GcmVxdWVuY3koKSA6IG5vdGUpO1xuICAgICAgICBjb25zdCBtYXhOb3RlID0gaGVydHogKiB0aGlzLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUobWF4Tm90ZSwgc2Vjb25kcyk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5mcmVxdWVuY3kuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZShoZXJ0eiwgc2Vjb25kcyArIHRoaXMudG9TZWNvbmRzKHRoaXMucGl0Y2hEZWNheSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICByYW5nZSgwKVxuXSwgTWVtYnJhbmVTeW50aC5wcm90b3R5cGUsIFwib2N0YXZlc1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBNZW1icmFuZVN5bnRoLnByb3RvdHlwZSwgXCJwaXRjaERlY2F5XCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NZW1icmFuZVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4vSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuLyoqXG4gKiBUb25lLk5vaXNlU3ludGggaXMgY29tcG9zZWQgb2YgW1tOb2lzZV1dIHRocm91Z2ggYW4gW1tBbXBsaXR1ZGVFbnZlbG9wZV1dLlxuICogYGBgXG4gKiArLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIHwgTm9pc2UgKz4tLT4gQW1wbGl0dWRlRW52ZWxvcGUgKz4tLT4gT3V0cHV0XG4gKiArLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG5vaXNlU3ludGggPSBuZXcgVG9uZS5Ob2lzZVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogbm9pc2VTeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIjhuXCIsIDAuMDUpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE5vaXNlU3ludGggZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTm9pc2VTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOb2lzZVN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubm9pc2UgPSBuZXcgTm9pc2UoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0sIG9wdGlvbnMubm9pc2UpKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IG5ldyBBbXBsaXR1ZGVFbnZlbG9wZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5lbnZlbG9wZSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBub2lzZSB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMubm9pc2UuY2hhaW4odGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuMCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbm9pc2U6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoTm9pc2UuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwid2hpdGVcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZXMuIFVubGlrZSBvdGhlclxuICAgICAqIGluc3RydW1lbnRzLCBUb25lLk5vaXNlU3ludGggZG9lc24ndCBoYXZlIGEgbm90ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vaXNlU3ludGggPSBuZXcgVG9uZS5Ob2lzZVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIG5vaXNlU3ludGgudHJpZ2dlckF0dGFjaygpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gdGhlIGVudmVsb3Blc1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbm9pc2VcbiAgICAgICAgdGhpcy5ub2lzZS5zdGFydCh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5ub2lzZS5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blcy5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5ub2lzZS5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jU3RhdGUoKSkge1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJBdHRhY2tcIiwgMCk7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlclJlbGVhc2VcIiwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSh0aW1lICsgZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm5vaXNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5vaXNlU3ludGguanMubWFwIiwiLyoqXG4gKiBBbGwgb2YgdGhlIGNsYXNzZXMgb3IgZnVuY3Rpb25zIHdoaWNoIGFyZSBsb2FkZWQgaW50byB0aGUgQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGVcbiAqL1xuY29uc3Qgd29ya2xldENvbnRleHQgPSBuZXcgU2V0KCk7XG4vKipcbiAqIEFkZCBhIGNsYXNzIHRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkVG9Xb3JrbGV0KGNsYXNzT3JGdW5jdGlvbikge1xuICAgIHdvcmtsZXRDb250ZXh0LmFkZChjbGFzc09yRnVuY3Rpb24pO1xufVxuLyoqXG4gKiBSZWdpc3RlciBhIHByb2Nlc3NvciBpbiB0aGUgQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUgd2l0aCB0aGUgZ2l2ZW4gbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJQcm9jZXNzb3IobmFtZSwgY2xhc3NEZXNjKSB7XG4gICAgY29uc3QgcHJvY2Vzc29yID0gLyogamF2YXNjcmlwdCAqLyBgcmVnaXN0ZXJQcm9jZXNzb3IoXCIke25hbWV9XCIsICR7Y2xhc3NEZXNjfSlgO1xuICAgIHdvcmtsZXRDb250ZXh0LmFkZChwcm9jZXNzb3IpO1xufVxuLyoqXG4gKiBHZXQgYWxsIG9mIHRoZSBtb2R1bGVzIHdoaWNoIGhhdmUgYmVlbiByZWdpc3RlcmVkIHRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V29ya2xldEdsb2JhbFNjb3BlKCkge1xuICAgIHJldHVybiBBcnJheS5mcm9tKHdvcmtsZXRDb250ZXh0KS5qb2luKFwiXFxuXCIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9V29ya2xldEdsb2JhbFNjb3BlLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBnZXRXb3JrbGV0R2xvYmFsU2NvcGUgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9Xb3JrbGV0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9Xb3JrbGV0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY29uc3RydWN0b3Igb3B0aW9ucyBmb3IgdGhlIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMud29ya2xldE9wdGlvbnMgPSB7fTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxiYWNrIHdoaWNoIGlzIGludm9rZWQgd2hlbiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgcHJvY2Vzc2luZ1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbnByb2Nlc3NvcmVycm9yID0gbm9PcDtcbiAgICAgICAgY29uc3QgYmxvYlVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW2dldFdvcmtsZXRHbG9iYWxTY29wZSgpXSwgeyB0eXBlOiBcInRleHQvamF2YXNjcmlwdFwiIH0pKTtcbiAgICAgICAgY29uc3QgbmFtZSA9IHRoaXMuX2F1ZGlvV29ya2xldE5hbWUoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlHYWluID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgdGhpcy5fZHVtbXlQYXJhbSA9IHRoaXMuX2R1bW15R2Fpbi5nYWluO1xuICAgICAgICAvLyBSZWdpc3RlciB0aGUgcHJvY2Vzc29yXG4gICAgICAgIHRoaXMuY29udGV4dC5hZGRBdWRpb1dvcmtsZXRNb2R1bGUoYmxvYlVybCwgbmFtZSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgdGhlIHdvcmtsZXQgd2hlbiBpdCdzIHJlYWRcbiAgICAgICAgICAgIGlmICghdGhpcy5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShuYW1lLCB0aGlzLndvcmtsZXRPcHRpb25zKTtcbiAgICAgICAgICAgICAgICB0aGlzLl93b3JrbGV0Lm9ucHJvY2Vzc29yZXJyb3IgPSB0aGlzLm9ucHJvY2Vzc29yZXJyb3IuYmluZCh0aGlzKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uUmVhZHkodGhpcy5fd29ya2xldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2R1bW15R2Fpbi5kaXNjb25uZWN0KCk7XG4gICAgICAgIGlmICh0aGlzLl93b3JrbGV0KSB7XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0LnBvcnQucG9zdE1lc3NhZ2UoXCJkaXNwb3NlXCIpO1xuICAgICAgICAgICAgdGhpcy5fd29ya2xldC5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvV29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmNvbnN0IHRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0LyoqXG5cdCAqIFRoZSBiYXNlIEF1ZGlvV29ya2xldFByb2Nlc3NvciBmb3IgdXNlIGluIFRvbmUuanMuIFdvcmtzIHdpdGggdGhlIFtbVG9uZUF1ZGlvV29ya2xldF1dLiBcblx0ICovXG5cdGNsYXNzIFRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0XG5cdFx0XHRzdXBlcihvcHRpb25zKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogSWYgdGhlIHByb2Nlc3NvciB3YXMgZGlzcG9zZWQgb3Igbm90LiBLZWVwIGFsaXZlIHVudGlsIGl0J3MgZGlzcG9zZWQuXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuZGlzcG9zZWQgPSBmYWxzZTtcblx0XHQgICBcdC8qKiBcblx0XHRcdCAqIFRoZSBudW1iZXIgb2Ygc2FtcGxlcyBpbiB0aGUgcHJvY2Vzc2luZyBibG9ja1xuXHRcdFx0ICovXG5cdFx0XHR0aGlzLmJsb2NrU2l6ZSA9IDEyODtcblx0XHRcdC8qKlxuXHRcdFx0ICogdGhlIHNhbXBsZSByYXRlXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuc2FtcGxlUmF0ZSA9IHNhbXBsZVJhdGU7XG5cblx0XHRcdHRoaXMucG9ydC5vbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHtcblx0XHRcdFx0Ly8gd2hlbiBpdCByZWNlaXZlcyBhIGRpc3Bvc2UgXG5cdFx0XHRcdGlmIChldmVudC5kYXRhID09PSBcImRpc3Bvc2VcIikge1xuXHRcdFx0XHRcdHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH1cblx0fVxuYDtcbmFkZFRvV29ya2xldCh0b25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Iud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgXCIuL1RvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IHsgYWRkVG9Xb3JrbGV0IH0gZnJvbSBcIi4vV29ya2xldEdsb2JhbFNjb3BlXCI7XG5leHBvcnQgY29uc3Qgc2luZ2xlSU9Qcm9jZXNzID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdC8qKlxuXHQgKiBBYnN0cmFjdCBjbGFzcyBmb3IgYSBzaW5nbGUgaW5wdXQvb3V0cHV0IHByb2Nlc3Nvci4gXG5cdCAqIGhhcyBhICdnZW5lcmF0ZScgZnVuY3Rpb24gd2hpY2ggcHJvY2Vzc2VzIG9uZSBzYW1wbGUgYXQgYSB0aW1lXG5cdCAqL1xuXHRjbGFzcyBTaW5nbGVJT1Byb2Nlc3NvciBleHRlbmRzIFRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0c3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7XG5cdFx0XHRcdG51bWJlck9mSW5wdXRzOiAxLFxuXHRcdFx0XHRudW1iZXJPZk91dHB1dHM6IDFcblx0XHRcdH0pKTtcblx0XHRcdC8qKlxuXHRcdFx0ICogSG9sZHMgdGhlIG5hbWUgb2YgdGhlIHBhcmFtZXRlciBhbmQgYSBzaW5nbGUgdmFsdWUgb2YgdGhhdFxuXHRcdFx0ICogcGFyYW1ldGVyIGF0IHRoZSBjdXJyZW50IHNhbXBsZVxuXHRcdFx0ICogQHR5cGUgeyBbbmFtZTogc3RyaW5nXTogbnVtYmVyIH1cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5wYXJhbXMgPSB7fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIEdlbmVyYXRlIGFuIG91dHB1dCBzYW1wbGUgZnJvbSB0aGUgaW5wdXQgc2FtcGxlIGFuZCBwYXJhbWV0ZXJzXG5cdFx0ICogQGFic3RyYWN0XG5cdFx0ICogQHBhcmFtIGlucHV0IG51bWJlclxuXHRcdCAqIEBwYXJhbSBjaGFubmVsIG51bWJlclxuXHRcdCAqIEBwYXJhbSBwYXJhbWV0ZXJzIHsgW25hbWU6IHN0cmluZ106IG51bWJlciB9XG5cdFx0ICogQHJldHVybnMgbnVtYmVyXG5cdFx0ICovXG5cdFx0Z2VuZXJhdGUoKXt9XG5cblx0XHQvKipcblx0XHQgKiBVcGRhdGUgdGhlIHByaXZhdGUgcGFyYW1zIG9iamVjdCB3aXRoIHRoZSBcblx0XHQgKiB2YWx1ZXMgb2YgdGhlIHBhcmFtZXRlcnMgYXQgdGhlIGdpdmVuIGluZGV4XG5cdFx0ICogQHBhcmFtIHBhcmFtZXRlcnMgeyBbbmFtZTogc3RyaW5nXTogRmxvYXQzMkFycmF5IH0sXG5cdFx0ICogQHBhcmFtIGluZGV4IG51bWJlclxuXHRcdCAqL1xuXHRcdHVwZGF0ZVBhcmFtcyhwYXJhbWV0ZXJzLCBpbmRleCkge1xuXHRcdFx0Zm9yIChjb25zdCBwYXJhbU5hbWUgaW4gcGFyYW1ldGVycykge1xuXHRcdFx0XHRjb25zdCBwYXJhbSA9IHBhcmFtZXRlcnNbcGFyYW1OYW1lXTtcblx0XHRcdFx0aWYgKHBhcmFtLmxlbmd0aCA+IDEpIHtcblx0XHRcdFx0XHR0aGlzLnBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdW2luZGV4XTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR0aGlzLnBhcmFtc1twYXJhbU5hbWVdID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdWzBdO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogUHJvY2VzcyBhIHNpbmdsZSBmcmFtZSBvZiB0aGUgYXVkaW9cblx0XHQgKiBAcGFyYW0gaW5wdXRzIEZsb2F0MzJBcnJheVtdW11cblx0XHQgKiBAcGFyYW0gb3V0cHV0cyBGbG9hdDMyQXJyYXlbXVtdXG5cdFx0ICovXG5cdFx0cHJvY2VzcyhpbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IGlucHV0ID0gaW5wdXRzWzBdO1xuXHRcdFx0Y29uc3Qgb3V0cHV0ID0gb3V0cHV0c1swXTtcblx0XHRcdC8vIGdldCB0aGUgcGFyYW1ldGVyIHZhbHVlc1xuXHRcdFx0Y29uc3QgY2hhbm5lbENvdW50ID0gTWF0aC5tYXgoaW5wdXQgJiYgaW5wdXQubGVuZ3RoIHx8IDAsIG91dHB1dC5sZW5ndGgpO1xuXHRcdFx0Zm9yIChsZXQgc2FtcGxlID0gMDsgc2FtcGxlIDwgdGhpcy5ibG9ja1NpemU7IHNhbXBsZSsrKSB7XG5cdFx0XHRcdHRoaXMudXBkYXRlUGFyYW1zKHBhcmFtZXRlcnMsIHNhbXBsZSk7XG5cdFx0XHRcdGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgY2hhbm5lbENvdW50OyBjaGFubmVsKyspIHtcblx0XHRcdFx0XHRjb25zdCBpbnB1dFNhbXBsZSA9IGlucHV0ICYmIGlucHV0Lmxlbmd0aCA/IGlucHV0W2NoYW5uZWxdW3NhbXBsZV0gOiAwO1xuXHRcdFx0XHRcdG91dHB1dFtjaGFubmVsXVtzYW1wbGVdID0gdGhpcy5nZW5lcmF0ZShpbnB1dFNhbXBsZSwgY2hhbm5lbCwgdGhpcy5wYXJhbXMpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gIXRoaXMuZGlzcG9zZWQ7XG5cdFx0fVxuXHR9O1xuYDtcbmFkZFRvV29ya2xldChzaW5nbGVJT1Byb2Nlc3MpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmNvbnN0IGRlbGF5TGluZSA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHQvKipcblx0ICogQSBtdWx0aWNoYW5uZWwgYnVmZmVyIGZvciB1c2Ugd2l0aGluIGFuIEF1ZGlvV29ya2xldFByb2Nlc3NvciBhcyBhIGRlbGF5IGxpbmVcblx0ICovXG5cdGNsYXNzIERlbGF5TGluZSB7XG5cdFx0XG5cdFx0Y29uc3RydWN0b3Ioc2l6ZSwgY2hhbm5lbHMpIHtcblx0XHRcdHRoaXMuYnVmZmVyID0gW107XG5cdFx0XHR0aGlzLndyaXRlSGVhZCA9IFtdXG5cdFx0XHR0aGlzLnNpemUgPSBzaXplO1xuXG5cdFx0XHQvLyBjcmVhdGUgdGhlIGVtcHR5IGNoYW5uZWxzXG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5uZWxzOyBpKyspIHtcblx0XHRcdFx0dGhpcy5idWZmZXJbaV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuc2l6ZSk7XG5cdFx0XHRcdHRoaXMud3JpdGVIZWFkW2ldID0gMDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBQdXNoIGEgdmFsdWUgb250byB0aGUgZW5kXG5cdFx0ICogQHBhcmFtIGNoYW5uZWwgbnVtYmVyXG5cdFx0ICogQHBhcmFtIHZhbHVlIG51bWJlclxuXHRcdCAqL1xuXHRcdHB1c2goY2hhbm5lbCwgdmFsdWUpIHtcblx0XHRcdHRoaXMud3JpdGVIZWFkW2NoYW5uZWxdICs9IDE7XG5cdFx0XHRpZiAodGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gPiB0aGlzLnNpemUpIHtcblx0XHRcdFx0dGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gPSAwO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy5idWZmZXJbY2hhbm5lbF1bdGhpcy53cml0ZUhlYWRbY2hhbm5lbF1dID0gdmFsdWU7XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogR2V0IHRoZSByZWNvcmRlZCB2YWx1ZSBvZiB0aGUgY2hhbm5lbCBnaXZlbiB0aGUgZGVsYXlcblx0XHQgKiBAcGFyYW0gY2hhbm5lbCBudW1iZXJcblx0XHQgKiBAcGFyYW0gZGVsYXkgbnVtYmVyIGRlbGF5IHNhbXBsZXNcblx0XHQgKi9cblx0XHRnZXQoY2hhbm5lbCwgZGVsYXkpIHtcblx0XHRcdGxldCByZWFkSGVhZCA9IHRoaXMud3JpdGVIZWFkW2NoYW5uZWxdIC0gTWF0aC5mbG9vcihkZWxheSk7XG5cdFx0XHRpZiAocmVhZEhlYWQgPCAwKSB7XG5cdFx0XHRcdHJlYWRIZWFkICs9IHRoaXMuc2l6ZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzLmJ1ZmZlcltjaGFubmVsXVtyZWFkSGVhZF07XG5cdFx0fVxuXHR9XG5gO1xuYWRkVG9Xb3JrbGV0KGRlbGF5TGluZSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWxheUxpbmUud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgXCIuLi8uLi9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IFwiLi4vLi4vY29yZS93b3JrbGV0L0RlbGF5TGluZS53b3JrbGV0XCI7XG5pbXBvcnQgeyByZWdpc3RlclByb2Nlc3NvciB9IGZyb20gXCIuLi8uLi9jb3JlL3dvcmtsZXQvV29ya2xldEdsb2JhbFNjb3BlXCI7XG5leHBvcnQgY29uc3Qgd29ya2xldE5hbWUgPSBcImZlZWRiYWNrLWNvbWItZmlsdGVyXCI7XG5jb25zdCBmZWVkYmFja0NvbWJGaWx0ZXIgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0Y2xhc3MgRmVlZGJhY2tDb21iRmlsdGVyV29ya2xldCBleHRlbmRzIFNpbmdsZUlPUHJvY2Vzc29yIHtcblxuXHRcdGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcblx0XHRcdHN1cGVyKG9wdGlvbnMpO1xuXHRcdFx0dGhpcy5kZWxheUxpbmUgPSBuZXcgRGVsYXlMaW5lKHRoaXMuc2FtcGxlUmF0ZSwgb3B0aW9ucy5jaGFubmVsQ291bnQgfHwgMik7XG5cdFx0fVxuXG5cdFx0c3RhdGljIGdldCBwYXJhbWV0ZXJEZXNjcmlwdG9ycygpIHtcblx0XHRcdHJldHVybiBbe1xuXHRcdFx0XHRuYW1lOiBcImRlbGF5VGltZVwiLFxuXHRcdFx0XHRkZWZhdWx0VmFsdWU6IDAuMSxcblx0XHRcdFx0bWluVmFsdWU6IDAsXG5cdFx0XHRcdG1heFZhbHVlOiAxLFxuXHRcdFx0XHRhdXRvbWF0aW9uUmF0ZTogXCJrLXJhdGVcIlxuXHRcdFx0fSwge1xuXHRcdFx0XHRuYW1lOiBcImZlZWRiYWNrXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMC41LFxuXHRcdFx0XHRtaW5WYWx1ZTogMCxcblx0XHRcdFx0bWF4VmFsdWU6IDAuOTk5OSxcblx0XHRcdFx0YXV0b21hdGlvblJhdGU6IFwiay1yYXRlXCJcblx0XHRcdH1dO1xuXHRcdH1cblxuXHRcdGdlbmVyYXRlKGlucHV0LCBjaGFubmVsLCBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRjb25zdCBkZWxheWVkU2FtcGxlID0gdGhpcy5kZWxheUxpbmUuZ2V0KGNoYW5uZWwsIHBhcmFtZXRlcnMuZGVsYXlUaW1lICogdGhpcy5zYW1wbGVSYXRlKTtcblx0XHRcdHRoaXMuZGVsYXlMaW5lLnB1c2goY2hhbm5lbCwgaW5wdXQgKyBkZWxheWVkU2FtcGxlICogcGFyYW1ldGVycy5mZWVkYmFjayk7XG5cdFx0XHRyZXR1cm4gZGVsYXllZFNhbXBsZTtcblx0XHR9XG5cdH1cbmA7XG5yZWdpc3RlclByb2Nlc3Nvcih3b3JrbGV0TmFtZSwgZmVlZGJhY2tDb21iRmlsdGVyKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZlZWRiYWNrQ29tYkZpbHRlci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Xb3JrbGV0IH0gZnJvbSBcIi4uLy4uL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0XCI7XG5pbXBvcnQgeyB3b3JrbGV0TmFtZSB9IGZyb20gXCIuL0ZlZWRiYWNrQ29tYkZpbHRlci53b3JrbGV0XCI7XG4vKipcbiAqIENvbWIgZmlsdGVycyBhcmUgYmFzaWMgYnVpbGRpbmcgYmxvY2tzIGZvciBwaHlzaWNhbCBtb2RlbGluZy4gUmVhZCBtb3JlXG4gKiBhYm91dCBjb21iIGZpbHRlcnMgb24gW0NDUk1BJ3Mgd2Vic2l0ZV0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL0ZlZWRiYWNrX0NvbWJfRmlsdGVycy5odG1sKS5cbiAqXG4gKiBUaGlzIGNvbWIgZmlsdGVyIGlzIGltcGxlbWVudGVkIHdpdGggdGhlIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggYWxsb3dzIGl0IHRvIGhhdmUgZmVlZGJhY2sgZGVsYXlzIGxlc3MgdGhhbiB0aGVcbiAqIFdlYiBBdWRpbyBwcm9jZXNzaW5nIGJsb2NrIG9mIDEyOCBzYW1wbGVzLiBUaGVyZSBpcyBhIHBvbHlmaWxsIGZvciBicm93c2VycyB0aGF0IGRvbid0IHlldCBzdXBwb3J0IHRoZVxuICogQXVkaW9Xb3JrbGV0Tm9kZSwgYnV0IGl0IHdpbGwgYWRkIHNvbWUgbGF0ZW5jeSBhbmQgaGF2ZSBzbG93ZXIgcGVyZm9ybWFuY2UgdGhhbiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZlZWRiYWNrQ29tYkZpbHRlciBleHRlbmRzIFRvbmVBdWRpb1dvcmtsZXQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0NvbWJGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgbWluVmFsdWU6IDAsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9kdW1teVBhcmFtLFxuICAgICAgICAgICAgc3dhcHBhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9kdW1teVBhcmFtLFxuICAgICAgICAgICAgc3dhcHBhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicmVzb25hbmNlXCIsIFwiZGVsYXlUaW1lXCJdKTtcbiAgICB9XG4gICAgX2F1ZGlvV29ya2xldE5hbWUoKSB7XG4gICAgICAgIHJldHVybiB3b3JrbGV0TmFtZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgcGFyYW1ldGVyc1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgb25SZWFkeShub2RlKSB7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgbm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25zdCBkZWxheVRpbWUgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiZGVsYXlUaW1lXCIpO1xuICAgICAgICA7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLnNldFBhcmFtKGRlbGF5VGltZSk7XG4gICAgICAgIGNvbnN0IGZlZWRiYWNrID0gbm9kZS5wYXJhbWV0ZXJzLmdldChcImZlZWRiYWNrXCIpO1xuICAgICAgICA7XG4gICAgICAgIHRoaXMucmVzb25hbmNlLnNldFBhcmFtKGZlZWRiYWNrKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmVzb25hbmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tDb21iRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBBIG9uZSBwb2xlIGZpbHRlciB3aXRoIDZkYi1wZXItb2N0YXZlIHJvbGxvZmYuIEVpdGhlciBcImhpZ2hwYXNzXCIgb3IgXCJsb3dwYXNzXCIuXG4gKiBOb3RlIHRoYXQgY2hhbmdpbmcgdGhlIHR5cGUgb3IgZnJlcXVlbmN5IG1heSByZXN1bHQgaW4gYSBkaXNjb250aW51aXR5IHdoaWNoXG4gKiBjYW4gc291bmQgbGlrZSBhIGNsaWNrIG9yIHBvcC5cbiAqIFJlZmVyZW5jZXM6XG4gKiAqIGh0dHA6Ly93d3cuZWFybGV2ZWwuY29tL21haW4vMjAxMi8xMi8xNS9hLW9uZS1wb2xlLWZpbHRlci9cbiAqICogaHR0cDovL3d3dy5kc3BndWlkZS5jb20vY2gxOS8yLmh0bVxuICogKiBodHRwczovL2dpdGh1Yi5jb20vdml0YWxpeS1ib2Jyb3YvanMtcm9ja3MvYmxvYi9tYXN0ZXIvc3JjL2FwcC9hdWRpby9lZmZlY3RzL29uZS1wb2xlLWZpbHRlcnMudHNcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE9uZVBvbGVGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoT25lUG9sZUZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPbmVQb2xlRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhPbmVQb2xlRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IG9wdGlvbnMuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUZpbHRlcigpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiA4ODAsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgZmlsdGVyIGFuZCBkaXNwb3NlIHRoZSBvbGQgb25lXG4gICAgICovXG4gICAgX2NyZWF0ZUZpbHRlcigpIHtcbiAgICAgICAgY29uc3Qgb2xkRmlsdGVyID0gdGhpcy5fZmlsdGVyO1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeSh0aGlzLl9mcmVxdWVuY3kpO1xuICAgICAgICBjb25zdCB0ID0gMSAvICgyICogTWF0aC5QSSAqIGZyZXEpO1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJsb3dwYXNzXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGEwID0gMSAvICh0ICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3QgYjEgPSBhMCAtIDE7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFthMCwgMF0sIFsxLCBiMV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYjEgPSAxIC8gKHQgKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSkgLSAxO1xuICAgICAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihbMSwgLTFdLCBbMSwgYjFdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2ZpbHRlciwgdGhpcy5vdXRwdXQpO1xuICAgICAgICBpZiAob2xkRmlsdGVyKSB7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIGl0IG9uIHRoZSBuZXh0IGJsb2NrXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdChvbGRGaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgICBvbGRGaWx0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sIHRoaXMuYmxvY2tUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBmcmVxdWVuY3koZnEpIHtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gZnE7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUZpbHRlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgT25lUG9sZSBGaWx0ZXIgdHlwZSwgZWl0aGVyIFwiaGlnaHBhc3NcIiBvciBcImxvd3Bhc3NcIlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodCkge1xuICAgICAgICB0aGlzLl90eXBlID0gdDtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIGNvbnN0IGZyZXFWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm0gPSBNYXRoLnBvdyhpIC8gbGVuLCAyKTtcbiAgICAgICAgICAgIGNvbnN0IGZyZXEgPSBub3JtICogKDIwMDAwIC0gMjApICsgMjA7XG4gICAgICAgICAgICBmcmVxVmFsdWVzW2ldID0gZnJlcTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYWdWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIGNvbnN0IHBoYXNlVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICB0aGlzLl9maWx0ZXIuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcVZhbHVlcywgbWFnVmFsdWVzLCBwaGFzZVZhbHVlcyk7XG4gICAgICAgIHJldHVybiBtYWdWYWx1ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T25lUG9sZUZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEZlZWRiYWNrQ29tYkZpbHRlciB9IGZyb20gXCIuL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgT25lUG9sZUZpbHRlciB9IGZyb20gXCIuL09uZVBvbGVGaWx0ZXJcIjtcbi8qKlxuICogQSBsb3dwYXNzIGZlZWRiYWNrIGNvbWIgZmlsdGVyLiBJdCBpcyBzaW1pbGFyIHRvXG4gKiBbW0ZlZWRiYWNrQ29tYkZpbHRlcl1dLCBidXQgaW5jbHVkZXMgYSBsb3dwYXNzIGZpbHRlci5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIExvd3Bhc3NDb21iRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKExvd3Bhc3NDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCIsIFwiZGFtcGVuaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTG93cGFzc0NvbWJGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKExvd3Bhc3NDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCIsIFwiZGFtcGVuaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlciA9IHRoaXMub3V0cHV0ID0gbmV3IEZlZWRiYWNrQ29tYkZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZWxheVRpbWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgcmVzb25hbmNlOiBvcHRpb25zLnJlc29uYW5jZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gdGhpcy5fY29tYkZpbHRlci5kZWxheVRpbWU7XG4gICAgICAgIHRoaXMucmVzb25hbmNlID0gdGhpcy5fY29tYkZpbHRlci5yZXNvbmFuY2U7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MgPSB0aGlzLmlucHV0ID0gbmV3IE9uZVBvbGVGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmRhbXBlbmluZyxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fbG93cGFzcy5jb25uZWN0KHRoaXMuX2NvbWJGaWx0ZXIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGFtcGVuaW5nOiAzMDAwLFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjEsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkYW1wZW5pbmcgY29udHJvbCBvZiB0aGUgZmVlZGJhY2tcbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG93cGFzcy5mcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBkYW1wZW5pbmcoZnEpIHtcbiAgICAgICAgdGhpcy5fbG93cGFzcy5mcmVxdWVuY3kgPSBmcTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93cGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxvd3Bhc3NDb21iRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IExvd3Bhc3NDb21iRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXJcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4vSW5zdHJ1bWVudFwiO1xuLyoqXG4gKiBLYXJwbHVzLVN0cmluZyBzdHJpbmcgc3ludGhlc2lzLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBsdWNreSA9IG5ldyBUb25lLlBsdWNrU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkM0XCIsIFwiKzAuNVwiKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzNcIiwgXCIrMVwiKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzJcIiwgXCIrMS41XCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDMVwiLCBcIisyXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBsdWNrU3ludGggZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGx1Y2tTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQbHVja1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQbHVja1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX25vaXNlID0gbmV3IE5vaXNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IFwicGlua1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFja05vaXNlID0gb3B0aW9ucy5hdHRhY2tOb2lzZTtcbiAgICAgICAgdGhpcy5fbGZjZiA9IG5ldyBMb3dwYXNzQ29tYkZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkYW1wZW5pbmc6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgcmVzb25hbmNlOiBvcHRpb25zLnJlc29uYW5jZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVzb25hbmNlID0gb3B0aW9ucy5yZXNvbmFuY2U7XG4gICAgICAgIHRoaXMucmVsZWFzZSA9IG9wdGlvbnMucmVsZWFzZTtcbiAgICAgICAgdGhpcy5fbm9pc2UuY29ubmVjdCh0aGlzLl9sZmNmKTtcbiAgICAgICAgdGhpcy5fbGZjZi5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrTm9pc2U6IDEsXG4gICAgICAgICAgICBkYW1wZW5pbmc6IDQwMDAsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDAuNyxcbiAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGFtcGVuaW5nIGNvbnRyb2wuIGkuZS4gdGhlIGxvd3Bhc3MgZmlsdGVyIGZyZXF1ZW5jeSBvZiB0aGUgY29tYiBmaWx0ZXJcbiAgICAgKiBAbWluIDBcbiAgICAgKiBAbWF4IDcwMDBcbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZjZi5kYW1wZW5pbmc7XG4gICAgfVxuICAgIHNldCBkYW1wZW5pbmcoZnEpIHtcbiAgICAgICAgdGhpcy5fbGZjZi5kYW1wZW5pbmcgPSBmcTtcbiAgICB9XG4gICAgdHJpZ2dlckF0dGFjayhub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KG5vdGUpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGRlbGF5QW1vdW50ID0gMSAvIGZyZXE7XG4gICAgICAgIHRoaXMuX2xmY2YuZGVsYXlUaW1lLnNldFZhbHVlQXRUaW1lKGRlbGF5QW1vdW50LCB0aW1lKTtcbiAgICAgICAgdGhpcy5fbm9pc2Uuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX25vaXNlLnN0b3AodGltZSArIGRlbGF5QW1vdW50ICogdGhpcy5hdHRhY2tOb2lzZSk7XG4gICAgICAgIHRoaXMuX2xmY2YucmVzb25hbmNlLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2Uuc2V0VmFsdWVBdFRpbWUodGhpcy5yZXNvbmFuY2UsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmFtcCBkb3duIHRoZSBbW3Jlc29uYW5jZV1dIHRvIDAgb3ZlciB0aGUgZHVyYXRpb24gb2YgdGhlIHJlbGVhc2UgdGltZS5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmY2YucmVzb25hbmNlLmxpbmVhclJhbXBUbygwLCB0aGlzLnJlbGVhc2UsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ub2lzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmY2YuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbHVja1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IE1pZGlDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvTWlkaVwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlLCBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4vSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgU3ludGggfSBmcm9tIFwiLi9TeW50aFwiO1xuaW1wb3J0IHsgYXNzZXJ0LCB3YXJuIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQb2x5U3ludGggaGFuZGxlcyB2b2ljZSBjcmVhdGlvbiBhbmQgYWxsb2NhdGlvbiBmb3IgYW55XG4gKiBpbnN0cnVtZW50cyBwYXNzZWQgaW4gYXMgdGhlIHNlY29uZCBwYXJhbXRlci4gUG9seVN5bnRoIGlzXG4gKiBub3QgYSBzeW50aGVzaXplciBieSBpdHNlbGYsIGl0IG1lcmVseSBtYW5hZ2VzIHZvaWNlcyBvZlxuICogb25lIG9mIHRoZSBvdGhlciB0eXBlcyBvZiBzeW50aHMsIGFsbG93aW5nIGFueSBvZiB0aGVcbiAqIG1vbm9waG9uaWMgc3ludGhlc2l6ZXJzIHRvIGJlIHBvbHlwaG9uaWMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gc2V0IHRoZSBhdHRyaWJ1dGVzIGFjcm9zcyBhbGwgdGhlIHZvaWNlcyB1c2luZyAnc2V0J1xuICogc3ludGguc2V0KHsgZGV0dW5lOiAtMTIwMCB9KTtcbiAqIC8vIHBsYXkgYSBjaG9yZFxuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiQzRcIiwgXCJFNFwiLCBcIkE0XCJdLCAxKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQb2x5U3ludGggZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUG9seVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9pY2VcIiwgXCJvcHRpb25zXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUG9seVN5bnRoXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdm9pY2VzIHdoaWNoIGFyZSBub3QgY3VycmVudGx5IGluIHVzZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYXZhaWxhYmxlVm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY3VycmVudGx5IGFjdGl2ZSB2b2ljZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBhbGxvY2F0ZWQgdm9pY2VzIGZvciB0aGlzIHN5bnRoLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgR0MgdGltZW91dC4gSGVsZCBzbyB0aGF0IGl0IGNvdWxkIGJlIGNhbmNlbGxlZCB3aGVuIHRoZSBub2RlIGlzIGRpc3Bvc2VkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2NUaW1lb3V0ID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIG1vdmluZyBhdmVyYWdlIG9mIHRoZSBudW1iZXIgb2YgYWN0aXZlIHZvaWNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYXZlcmFnZUFjdGl2ZVZvaWNlcyA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQb2x5U3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2ljZVwiLCBcIm9wdGlvbnNcIl0pO1xuICAgICAgICAvLyBjaGVjayBhZ2FpbnN0IHRoZSBvbGQgQVBJIChwcmUgMTQuMy4wKVxuICAgICAgICBhc3NlcnQoIWlzTnVtYmVyKG9wdGlvbnMudm9pY2UpLCBcIkRFUFJFQ0FURUQ6IFRoZSBwb2x5cGhvbnkgY291bnQgaXMgbm8gbG9uZ2VyIHRoZSBmaXJzdCBhcmd1bWVudC5cIik7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0gb3B0aW9ucy52b2ljZS5nZXREZWZhdWx0cygpO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBPYmplY3QuYXNzaWduKGRlZmF1bHRzLCBvcHRpb25zLm9wdGlvbnMpO1xuICAgICAgICB0aGlzLnZvaWNlID0gb3B0aW9ucy52b2ljZTtcbiAgICAgICAgdGhpcy5tYXhQb2x5cGhvbnkgPSBvcHRpb25zLm1heFBvbHlwaG9ueTtcbiAgICAgICAgLy8gY3JlYXRlIHRoZSBmaXJzdCB2b2ljZVxuICAgICAgICB0aGlzLl9kdW1teVZvaWNlID0gdGhpcy5fZ2V0TmV4dEF2YWlsYWJsZVZvaWNlKCk7XG4gICAgICAgIC8vIHJlbW92ZSBpdCBmcm9tIHRoZSB2b2ljZXMgbGlzdFxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3ZvaWNlcy5pbmRleE9mKHRoaXMuX2R1bW15Vm9pY2UpO1xuICAgICAgICB0aGlzLl92b2ljZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgLy8ga2ljayBvZmYgdGhlIEdDIGludGVydmFsXG4gICAgICAgIHRoaXMuX2djVGltZW91dCA9IHRoaXMuY29udGV4dC5zZXRJbnRlcnZhbCh0aGlzLl9jb2xsZWN0R2FyYmFnZS5iaW5kKHRoaXMpLCAxKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1heFBvbHlwaG9ueTogMzIsXG4gICAgICAgICAgICBvcHRpb25zOiB7fSxcbiAgICAgICAgICAgIHZvaWNlOiBTeW50aCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgYWN0aXZlIHZvaWNlcy5cbiAgICAgKi9cbiAgICBnZXQgYWN0aXZlVm9pY2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYWN0aXZlVm9pY2VzLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCB3aGVuIHRoZSBzb3VyY2UgaXMgZG9uZSBtYWtpbmcgc291bmQsIHNvIHRoYXQgaXQgY2FuIGJlXG4gICAgICogcmVhZGRlZCB0byB0aGUgcG9vbCBvZiBhdmFpbGFibGUgdm9pY2VzXG4gICAgICovXG4gICAgX21ha2VWb2ljZUF2YWlsYWJsZSh2b2ljZSkge1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMucHVzaCh2b2ljZSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgbWlkaSBub3RlIGZyb20gJ2FjdGl2ZSB2b2ljZXMnXG4gICAgICAgIGNvbnN0IGFjdGl2ZVZvaWNlSW5kZXggPSB0aGlzLl9hY3RpdmVWb2ljZXMuZmluZEluZGV4KChlKSA9PiBlLnZvaWNlID09PSB2b2ljZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcy5zcGxpY2UoYWN0aXZlVm9pY2VJbmRleCwgMSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbiBhdmFpbGFibGUgdm9pY2UgZnJvbSB0aGUgcG9vbCBvZiBhdmFpbGFibGUgdm9pY2VzLlxuICAgICAqIElmIG9uZSBpcyBub3QgYXZhaWxhYmxlIGFuZCB0aGUgbWF4UG9seXBob255IGxpbWl0IGlzIHJlYWNoZWQsXG4gICAgICogc3RlYWwgYSB2b2ljZSwgb3RoZXJ3aXNlIHJldHVybiBudWxsLlxuICAgICAqL1xuICAgIF9nZXROZXh0QXZhaWxhYmxlVm9pY2UoKSB7XG4gICAgICAgIC8vIGlmIHRoZXJlIGFyZSBhdmFpbGFibGUgdm9pY2VzLCByZXR1cm4gdGhlIGZpcnN0IG9uZVxuICAgICAgICBpZiAodGhpcy5fYXZhaWxhYmxlVm9pY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5zaGlmdCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3ZvaWNlcy5sZW5ndGggPCB0aGlzLm1heFBvbHlwaG9ueSkge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIHRoZXJlIGlzIHN0aWxsIG1vcmUgbWF4UG9seXBob255LCBtYWtlIGEgbmV3IHZvaWNlXG4gICAgICAgICAgICBjb25zdCB2b2ljZSA9IG5ldyB0aGlzLnZvaWNlKE9iamVjdC5hc3NpZ24odGhpcy5vcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIG9uc2lsZW5jZTogdGhpcy5fbWFrZVZvaWNlQXZhaWxhYmxlLmJpbmQodGhpcyksXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICB2b2ljZS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHRoaXMuX3ZvaWNlcy5wdXNoKHZvaWNlKTtcbiAgICAgICAgICAgIHJldHVybiB2b2ljZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHdhcm4oXCJNYXggcG9seXBob255IGV4Y2VlZGVkLiBOb3RlIGRyb3BwZWQuXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE9jY2FzaW9uYWxseSBjaGVjayBpZiB0aGVyZSBhcmUgYW55IGFsbG9jYXRlZCB2b2ljZXMgd2hpY2ggY2FuIGJlIGNsZWFuZWQgdXAuXG4gICAgICovXG4gICAgX2NvbGxlY3RHYXJiYWdlKCkge1xuICAgICAgICB0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzID0gTWF0aC5tYXgodGhpcy5fYXZlcmFnZUFjdGl2ZVZvaWNlcyAqIDAuOTUsIHRoaXMuYWN0aXZlVm9pY2VzKTtcbiAgICAgICAgaWYgKHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5sZW5ndGggJiYgdGhpcy5fdm9pY2VzLmxlbmd0aCA+IE1hdGguY2VpbCh0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzICsgMSkpIHtcbiAgICAgICAgICAgIC8vIHRha2Ugb2ZmIGFuIGF2YWlsYWJsZSBub3RlXG4gICAgICAgICAgICBjb25zdCBmaXJzdEF2YWlsID0gdGhpcy5fYXZhaWxhYmxlVm9pY2VzLnNoaWZ0KCk7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3ZvaWNlcy5pbmRleE9mKGZpcnN0QXZhaWwpO1xuICAgICAgICAgICAgdGhpcy5fdm9pY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuY29udGV4dC5pc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBmaXJzdEF2YWlsLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtZXRob2Qgd2hpY2ggdHJpZ2dlcnMgdGhlIGF0dGFja1xuICAgICAqL1xuICAgIF90cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaU5vdGUgPSBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICBjb25zdCB2b2ljZSA9IHRoaXMuX2dldE5leHRBdmFpbGFibGVWb2ljZSgpO1xuICAgICAgICAgICAgaWYgKHZvaWNlKSB7XG4gICAgICAgICAgICAgICAgdm9pY2UudHJpZ2dlckF0dGFjayhub3RlLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBtaWRpOiBtaWRpTm90ZSwgdm9pY2UsIHJlbGVhc2VkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtZXRob2Qgd2hpY2ggdHJpZ2dlcnMgdGhlIHJlbGVhc2VcbiAgICAgKi9cbiAgICBfdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgbm90ZXMuZm9yRWFjaChub3RlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1pZGlOb3RlID0gbmV3IE1pZGlDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9hY3RpdmVWb2ljZXMuZmluZCgoeyBtaWRpLCByZWxlYXNlZCB9KSA9PiBtaWRpID09PSBtaWRpTm90ZSAmJiAhcmVsZWFzZWQpO1xuICAgICAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gdHJpZ2dlciByZWxlYXNlIG9uIHRoYXQgbm90ZVxuICAgICAgICAgICAgICAgIGV2ZW50LnZvaWNlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICAgICAgICAgIC8vIG1hcmsgaXQgYXMgcmVsZWFzZWRcbiAgICAgICAgICAgICAgICBldmVudC5yZWxlYXNlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCBub3RlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIHRoZSBhdHRhY2svcmVsZWFzZSBldmVudHMuIElmIHRoZSB0aW1lIGlzIGluIHRoZSBmdXR1cmUsIHRoZW4gaXQgc2hvdWxkIHNldCBhIHRpbWVvdXRcbiAgICAgKiB0byB3YWl0IGZvciBqdXN0LWluLXRpbWUgc2NoZWR1bGluZ1xuICAgICAqL1xuICAgIF9zY2hlZHVsZUV2ZW50KHR5cGUsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuZGlzcG9zZWQsIFwiU3ludGggd2FzIGFscmVhZHkgZGlzcG9zZWRcIik7XG4gICAgICAgIC8vIGlmIHRoZSBub3RlcyBhcmUgZ3JlYXRlciB0aGFuIHRoaXMgYW1vdW50IG9mIHRpbWUgaW4gdGhlIGZ1dHVyZSwgdGhleSBzaG91bGQgYmUgc2NoZWR1bGVkIHdpdGggc2V0VGltZW91dFxuICAgICAgICBpZiAodGltZSA8PSB0aGlzLm5vdygpKSB7XG4gICAgICAgICAgICAvLyBkbyBpdCBpbW1lZGlhdGVseVxuICAgICAgICAgICAgaWYgKHR5cGUgPT09IFwiYXR0YWNrXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBzY2hlZHVsZSBpdCB0byBzdGFydCBpbiB0aGUgZnV0dXJlXG4gICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVFdmVudCh0eXBlLCBub3RlcywgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAgICAgfSwgdGltZSAtIHRoaXMubm93KCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgc3RhcnQgdGltZSBvZiB0aGUgbm90ZS5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoVG9uZS5GTVN5bnRoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gdHJpZ2dlciBhIGNob3JkIGltbWVkaWF0ZWx5IHdpdGggYSB2ZWxvY2l0eSBvZiAwLjJcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFtcIkFiM1wiLCBcIkM0XCIsIFwiRjVcIl0sIFRvbmUubm93KCksIDAuMik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayhub3RlcywgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KFwiYXR0YWNrXCIsIG5vdGVzLCBjb21wdXRlZFRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIG5vdGUuIFVubGlrZSBtb25vcGhvbmljIGluc3RydW1lbnRzLFxuICAgICAqIGEgbm90ZSAob3IgYXJyYXkgb2Ygbm90ZXMpIG5lZWRzIHRvIGJlIHBhc3NlZCBpbiBhcyB0aGUgZmlyc3QgYXJndW1lbnQuXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRoZSByZWxlYXNlIHdpbGwgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKFRvbmUuQU1TeW50aCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBvbHkudHJpZ2dlckF0dGFjayhbXCJBYjNcIiwgXCJDNFwiLCBcIkY1XCJdKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIG9mIHRoZSBnaXZlbiBub3Rlcy5cbiAgICAgKiBwb2x5LnRyaWdnZXJSZWxlYXNlKFtcIkFiM1wiLCBcIkM0XCJdLCBcIisxXCIpO1xuICAgICAqIHBvbHkudHJpZ2dlclJlbGVhc2UoXCJGNVwiLCBcIiszXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVFdmVudChcInJlbGVhc2VcIiwgbm90ZXMsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgYW5kIHJlbGVhc2UgYWZ0ZXIgdGhlIHNwZWNpZmllZCBkdXJhdGlvblxuICAgICAqIEBwYXJhbSAgbm90ZXMgVGhlIG5vdGVzIHRvIHBsYXkuIEFjY2VwdHMgYSBzaW5nbGUgIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIHRoZSBkdXJhdGlvbiBvZiB0aGUgbm90ZVxuICAgICAqIEBwYXJhbSAgdGltZSAgaWYgbm8gdGltZSBpcyBnaXZlbiwgZGVmYXVsdHMgdG8gbm93XG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSB0aGUgdmVsb2NpdHkgb2YgdGhlIGF0dGFjayAoMC0xKVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcG9seSA9IG5ldyBUb25lLlBvbHlTeW50aChUb25lLkFNU3ludGgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBjYW4gcGFzcyBpbiBhbiBhcnJheSBvZiBkdXJhdGlvbnMgYXMgd2VsbFxuICAgICAqIHBvbHkudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiRWIzXCIsIFwiRzRcIiwgXCJCYjRcIiwgXCJENVwiXSwgWzQsIDMsIDIsIDFdKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShub3RlcywgZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBpZiAoaXNBcnJheShkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGFzc2VydChpc0FycmF5KG5vdGVzKSwgXCJJZiB0aGUgZHVyYXRpb24gaXMgYW4gYXJyYXksIHRoZSBub3RlcyBtdXN0IGFsc28gYmUgYW4gYXJyYXlcIik7XG4gICAgICAgICAgICBub3RlcyA9IG5vdGVzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub3Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGQgPSBkdXJhdGlvbltNYXRoLm1pbihpLCBkdXJhdGlvbi5sZW5ndGggLSAxKV07XG4gICAgICAgICAgICAgICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gdGhpcy50b1NlY29uZHMoZCk7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGR1cmF0aW9uU2Vjb25kcyA+IDAsIFwiVGhlIGR1cmF0aW9uIG11c3QgYmUgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3Rlc1tpXSwgY29tcHV0ZWRUaW1lICsgZHVyYXRpb25TZWNvbmRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uU2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgICAgIGFzc2VydChkdXJhdGlvblNlY29uZHMgPiAwLCBcIlRoZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwXCIpO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3RlcywgY29tcHV0ZWRUaW1lICsgZHVyYXRpb25TZWNvbmRzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAxKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IGEgbWVtYmVyL2F0dHJpYnV0ZSBvZiB0aGUgdm9pY2VzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHNldCBhbGwgb2YgdGhlIHZvaWNlcyB1c2luZyBhbiBvcHRpb25zIG9iamVjdCBmb3IgdGhlIHN5bnRoIHR5cGVcbiAgICAgKiBwb2x5LnNldCh7XG4gICAgICogXHRlbnZlbG9wZToge1xuICAgICAqIFx0XHRhdHRhY2s6IDAuMjVcbiAgICAgKiBcdH1cbiAgICAgKiB9KTtcbiAgICAgKiBwb2x5LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQmIzXCIsIDAuMik7XG4gICAgICovXG4gICAgc2V0KG9wdGlvbnMpIHtcbiAgICAgICAgLy8gcmVtb3ZlIG9wdGlvbnMgd2hpY2ggYXJlIGNvbnRyb2xsZWQgYnkgdGhlIFBvbHlTeW50aFxuICAgICAgICBjb25zdCBzYW5pdGl6ZWRPcHRpb25zID0gb21pdEZyb21PYmplY3Qob3B0aW9ucywgW1wib25zaWxlbmNlXCIsIFwiY29udGV4dFwiXSk7XG4gICAgICAgIC8vIHN0b3JlIGFsbCBvZiB0aGUgb3B0aW9uc1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBkZWVwTWVyZ2UodGhpcy5vcHRpb25zLCBzYW5pdGl6ZWRPcHRpb25zKTtcbiAgICAgICAgdGhpcy5fdm9pY2VzLmZvckVhY2godm9pY2UgPT4gdm9pY2Uuc2V0KHNhbml0aXplZE9wdGlvbnMpKTtcbiAgICAgICAgdGhpcy5fZHVtbXlWb2ljZS5zZXQoc2FuaXRpemVkT3B0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kdW1teVZvaWNlLmdldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgYWxsIHRoZSBjdXJyZW50bHkgYWN0aXZlIHZvaWNlcyBpbW1lZGlhdGVseS5cbiAgICAgKiBVc2VmdWwgZm9yIHNpbGVuY2luZyB0aGUgc3ludGguXG4gICAgICovXG4gICAgcmVsZWFzZUFsbCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMuZm9yRWFjaCgoeyB2b2ljZSB9KSA9PiB7XG4gICAgICAgICAgICB2b2ljZS50cmlnZ2VyUmVsZWFzZShjb21wdXRlZFRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlWb2ljZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvaWNlcy5mb3JFYWNoKHYgPT4gdi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMgPSBbXTtcbiAgICAgICAgdGhpcy5fYXZhaWxhYmxlVm9pY2VzID0gW107XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhckludGVydmFsKHRoaXMuX2djVGltZW91dCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBvbHlTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXJzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5pbXBvcnQgeyBmdG9tZiwgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzTm90ZSwgaXNOdW1iZXIgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuLi9pbnN0cnVtZW50L0luc3RydW1lbnRcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5pbXBvcnQgeyB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQYXNzIGluIGFuIG9iamVjdCB3aGljaCBtYXBzIHRoZSBub3RlJ3MgcGl0Y2ggb3IgbWlkaSB2YWx1ZSB0byB0aGUgdXJsLFxuICogdGhlbiB5b3UgY2FuIHRyaWdnZXIgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSBvZiB0aGF0IG5vdGUgbGlrZSBvdGhlciBpbnN0cnVtZW50cy5cbiAqIEJ5IGF1dG9tYXRpY2FsbHkgcmVwaXRjaGluZyB0aGUgc2FtcGxlcywgaXQgaXMgcG9zc2libGUgdG8gcGxheSBwaXRjaGVzIHdoaWNoXG4gKiB3ZXJlIG5vdCBleHBsaWNpdGx5IGluY2x1ZGVkIHdoaWNoIGNhbiBzYXZlIGxvYWRpbmcgdGltZS5cbiAqXG4gKiBGb3Igc2FtcGxlIG9yIGJ1ZmZlciBwbGF5YmFjayB3aGVyZSByZXBpdGNoaW5nIGlzIG5vdCBuZWNlc3NhcnksXG4gKiB1c2UgW1tQbGF5ZXJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzYW1wbGVyID0gbmV3IFRvbmUuU2FtcGxlcih7XG4gKiBcdHVybHM6IHtcbiAqIFx0XHRBMTogXCJBMS5tcDNcIixcbiAqIFx0XHRBMjogXCJBMi5tcDNcIixcbiAqIFx0fSxcbiAqIFx0YmFzZVVybDogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vXCIsXG4gKiBcdG9ubG9hZDogKCkgPT4ge1xuICogXHRcdHNhbXBsZXIudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiQzFcIiwgXCJFMVwiLCBcIkcxXCIsIFwiQjFcIl0sIDAuNSk7XG4gKiBcdH1cbiAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTYW1wbGVyIGV4dGVuZHMgSW5zdHJ1bWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNhbXBsZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCIsIFwiYmFzZVVybFwiXSwgXCJ1cmxzXCIpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTYW1wbGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2JqZWN0IG9mIGFsbCBjdXJyZW50bHkgcGxheWluZyBCdWZmZXJTb3VyY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2FtcGxlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIik7XG4gICAgICAgIGNvbnN0IHVybE1hcCA9IHt9O1xuICAgICAgICBPYmplY3Qua2V5cyhvcHRpb25zLnVybHMpLmZvckVhY2goKG5vdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdGVOdW1iZXIgPSBwYXJzZUludChub3RlLCAxMCk7XG4gICAgICAgICAgICBhc3NlcnQoaXNOb3RlKG5vdGUpXG4gICAgICAgICAgICAgICAgfHwgKGlzTnVtYmVyKG5vdGVOdW1iZXIpICYmIGlzRmluaXRlKG5vdGVOdW1iZXIpKSwgYHVybCBrZXkgaXMgbmVpdGhlciBhIG5vdGUgb3IgbWlkaSBwaXRjaDogJHtub3RlfWApO1xuICAgICAgICAgICAgaWYgKGlzTm90ZShub3RlKSkge1xuICAgICAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIG5vdGUgbmFtZSB0byBNSURJXG4gICAgICAgICAgICAgICAgY29uc3QgbWlkID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICAgICAgdXJsTWFwW21pZF0gPSBvcHRpb25zLnVybHNbbm90ZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc051bWJlcihub3RlTnVtYmVyKSAmJiBpc0Zpbml0ZShub3RlTnVtYmVyKSkge1xuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBpZiBpdCdzIG51bWJlcnMgYXNzdW1lIGl0J3MgbWlkaVxuICAgICAgICAgICAgICAgIHVybE1hcFtub3RlTnVtYmVyXSA9IG9wdGlvbnMudXJsc1tub3RlTnVtYmVyXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgVG9uZUF1ZGlvQnVmZmVycyh7XG4gICAgICAgICAgICB1cmxzOiB1cmxNYXAsXG4gICAgICAgICAgICBvbmxvYWQ6IG9wdGlvbnMub25sb2FkLFxuICAgICAgICAgICAgYmFzZVVybDogb3B0aW9ucy5iYXNlVXJsLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjaztcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLmN1cnZlID0gb3B0aW9ucy5jdXJ2ZTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFjayBpZiBpdCdzIGFscmVhZHkgbG9hZGVkXG4gICAgICAgIGlmICh0aGlzLl9idWZmZXJzLmxvYWRlZCkge1xuICAgICAgICAgICAgLy8gaW52b2tlIG9ubG9hZCBkZWZlcnJlZFxuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihvcHRpb25zLm9ubG9hZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF0dGFjazogMCxcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBjdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHJlbGVhc2U6IDAuMSxcbiAgICAgICAgICAgIHVybHM6IHt9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZGlmZmVyZW5jZSBpbiBzdGVwcyBiZXR3ZWVuIHRoZSBnaXZlbiBtaWRpIG5vdGUgYXQgdGhlIGNsb3NldHMgc2FtcGxlLlxuICAgICAqL1xuICAgIF9maW5kQ2xvc2VzdChtaWRpKSB7XG4gICAgICAgIC8vIHNlYXJjaGVzIHdpdGhpbiA4IG9jdGF2ZXMgb2YgdGhlIGdpdmVuIG1pZGkgbm90ZVxuICAgICAgICBjb25zdCBNQVhfSU5URVJWQUwgPSA5NjtcbiAgICAgICAgbGV0IGludGVydmFsID0gMDtcbiAgICAgICAgd2hpbGUgKGludGVydmFsIDwgTUFYX0lOVEVSVkFMKSB7XG4gICAgICAgICAgICAvLyBjaGVjayBhYm92ZSBhbmQgYmVsb3dcbiAgICAgICAgICAgIGlmICh0aGlzLl9idWZmZXJzLmhhcyhtaWRpICsgaW50ZXJ2YWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC1pbnRlcnZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2J1ZmZlcnMuaGFzKG1pZGkgLSBpbnRlcnZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnRlcnZhbCsrO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gYXZhaWxhYmxlIGJ1ZmZlcnMgZm9yIG5vdGU6ICR7bWlkaX1gKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcGxheSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBXaGVuIHRvIHBsYXkgdGhlIG5vdGVcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSB0byBwbGF5IHRoZSBzYW1wbGUgYmFjay5cbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaUZsb2F0ID0gZnRvbWYobmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9GcmVxdWVuY3koKSk7XG4gICAgICAgICAgICBjb25zdCBtaWRpID0gTWF0aC5yb3VuZChtaWRpRmxvYXQpO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluZGVyID0gbWlkaUZsb2F0IC0gbWlkaTtcbiAgICAgICAgICAgIC8vIGZpbmQgdGhlIGNsb3Nlc3Qgbm90ZSBwaXRjaFxuICAgICAgICAgICAgY29uc3QgZGlmZmVyZW5jZSA9IHRoaXMuX2ZpbmRDbG9zZXN0KG1pZGkpO1xuICAgICAgICAgICAgY29uc3QgY2xvc2VzdE5vdGUgPSBtaWRpIC0gZGlmZmVyZW5jZTtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuX2J1ZmZlcnMuZ2V0KGNsb3Nlc3ROb3RlKTtcbiAgICAgICAgICAgIGNvbnN0IHBsYXliYWNrUmF0ZSA9IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhkaWZmZXJlbmNlICsgcmVtYWluZGVyKTtcbiAgICAgICAgICAgIC8vIHBsYXkgdGhhdCBub3RlXG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICAgICAgdXJsOiBidWZmZXIsXG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGN1cnZlOiB0aGlzLmN1cnZlLFxuICAgICAgICAgICAgICAgIGZhZGVJbjogdGhpcy5hdHRhY2ssXG4gICAgICAgICAgICAgICAgZmFkZU91dDogdGhpcy5yZWxlYXNlLFxuICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgc291cmNlLnN0YXJ0KHRpbWUsIDAsIGJ1ZmZlci5kdXJhdGlvbiAvIHBsYXliYWNrUmF0ZSwgdmVsb2NpdHkpO1xuICAgICAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICAgICAgaWYgKCFpc0FycmF5KHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuc2V0KG1pZGksIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpLnB1c2goc291cmNlKTtcbiAgICAgICAgICAgIC8vIHJlbW92ZSBpdCB3aGVuIGl0J3MgZG9uZVxuICAgICAgICAgICAgc291cmNlLm9uZW5kZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZVNvdXJjZXMgJiYgdGhpcy5fYWN0aXZlU291cmNlcy5oYXMobWlkaSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlcyA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHNvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwYXJhbSAgbm90ZXNcdFRoZSBub3RlIHRvIHJlbGVhc2UsIG9yIGFuIGFycmF5IG9mIG5vdGVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgXHRXaGVuIHRvIHJlbGVhc2UgdGhlIG5vdGUuXG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCBub3RlcywgdGltZSk7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaSA9IG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgbm90ZVxuICAgICAgICAgICAgaWYgKHRoaXMuX2FjdGl2ZVNvdXJjZXMuaGFzKG1pZGkpICYmIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLl9hY3RpdmVTb3VyY2VzLmdldChtaWRpKTtcbiAgICAgICAgICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgICAgICAgICAgc291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZS5zdG9wKHRpbWUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuc2V0KG1pZGksIFtdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWxlYXNlIGFsbCBjdXJyZW50bHkgYWN0aXZlIG5vdGVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgXHRXaGVuIHRvIHJlbGVhc2UgdGhlIG5vdGVzLlxuICAgICAqL1xuICAgIHJlbGVhc2VBbGwodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZXMgPT4ge1xuICAgICAgICAgICAgd2hpbGUgKHNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gc291cmNlcy5zaGlmdCgpO1xuICAgICAgICAgICAgICAgIHNvdXJjZS5zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAxKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBhdHRhY2sgcGhhc2UsIHRoZW4gYWZ0ZXIgdGhlIGR1cmF0aW9uLCBpbnZva2UgdGhlIHJlbGVhc2UuXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcGxheSBhbmQgcmVsZWFzZSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBUaGUgdGltZSB0aGUgbm90ZSBzaG91bGQgYmUgaGVsZFxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgV2hlbiB0byBzdGFydCB0aGUgYXR0YWNrXG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIGF0dGFja1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGVzLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBpZiAoaXNBcnJheShkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGFzc2VydChpc0FycmF5KG5vdGVzKSwgXCJub3RlcyBtdXN0IGJlIGFuIGFycmF5IHdoZW4gZHVyYXRpb24gaXMgYXJyYXlcIik7XG4gICAgICAgICAgICBub3Rlcy5mb3JFYWNoKChub3RlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGQgPSBkdXJhdGlvbltNYXRoLm1pbihpbmRleCwgZHVyYXRpb24ubGVuZ3RoIC0gMSldO1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZSwgY29tcHV0ZWRUaW1lICsgdGhpcy50b1NlY29uZHMoZCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzLCBjb21wdXRlZFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBub3RlIHRvIHRoZSBzYW1wbGVyLlxuICAgICAqIEBwYXJhbSAgbm90ZSAgICAgIFRoZSBidWZmZXIncyBwaXRjaC5cbiAgICAgKiBAcGFyYW0gIHVybCAgRWl0aGVyIHRoZSB1cmwgb2YgdGhlIGJ1ZmZlciwgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBhZGQobm90ZSwgdXJsLCBjYWxsYmFjaykge1xuICAgICAgICBhc3NlcnQoaXNOb3RlKG5vdGUpIHx8IGlzRmluaXRlKG5vdGUpLCBgbm90ZSBtdXN0IGJlIGEgcGl0Y2ggb3IgbWlkaTogJHtub3RlfWApO1xuICAgICAgICBpZiAoaXNOb3RlKG5vdGUpKSB7XG4gICAgICAgICAgICAvLyBjb252ZXJ0IHRoZSBub3RlIG5hbWUgdG8gTUlESVxuICAgICAgICAgICAgY29uc3QgbWlkID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChtaWQsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLmFkZChub3RlLCB1cmwsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5sb2FkZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZXMgPT4ge1xuICAgICAgICAgICAgc291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UuZGlzcG9zZSgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBTYW1wbGVyLnByb3RvdHlwZSwgXCJhdHRhY2tcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgU2FtcGxlci5wcm90b3R5cGUsIFwicmVsZWFzZVwiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2FtcGxlci5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BTVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EdW9TeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRk1TeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTWV0YWxTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTWVtYnJhbmVTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTW9ub1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Ob2lzZVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QbHVja1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Qb2x5U3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NhbXBsZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1N5bnRoXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgXCIuLi9jb3JlL2Nsb2NrL1RyYW5zcG9ydFwiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNCb29sZWFuLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRvbmVFdmVudCBhYnN0cmFjdHMgYXdheSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlIGFuZCBwcm92aWRlcyBhIHNjaGVkdWxhYmxlXG4gKiBjYWxsYmFjayBmb3IgYSBzaW5nbGUgb3IgcmVwZWF0YWJsZSBldmVudHMgYWxvbmcgdGhlIHRpbWVsaW5lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGNob3JkRXZlbnQgPSBuZXcgVG9uZS5Ub25lRXZlbnQoKCh0aW1lLCBjaG9yZCkgPT4ge1xuICogXHQvLyB0aGUgY2hvcmQgYXMgd2VsbCBhcyB0aGUgZXhhY3QgdGltZSBvZiB0aGUgZXZlbnRcbiAqIFx0Ly8gYXJlIHBhc3NlZCBpbiBhcyBhcmd1bWVudHMgdG8gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uXG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKGNob3JkLCAwLjUsIHRpbWUpO1xuICogfSksIFtcIkQ0XCIsIFwiRTRcIiwgXCJGNFwiXSk7XG4gKiAvLyBzdGFydCB0aGUgY2hvcmQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgdHJhbnNwb3J0IHRpbWVsaW5lXG4gKiBjaG9yZEV2ZW50LnN0YXJ0KCk7XG4gKiAvLyBsb29wIGl0IGV2ZXJ5IG1lYXN1cmUgZm9yIDggbWVhc3VyZXNcbiAqIGNob3JkRXZlbnQubG9vcCA9IDg7XG4gKiBjaG9yZEV2ZW50Lmxvb3BFbmQgPSBcIjFtXCI7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVFdmVudCBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lRXZlbnRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYWNrcyB0aGUgc2NoZWR1bGVkIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIGRlbGF5IHRpbWUgZnJvbSB3aGVuIHRoZSBldmVudCBpcyBzY2hlZHVsZWQgdG8gc3RhcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy52YWx1ZSA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhvcHRpb25zLmxvb3BTdGFydCk7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5sb29wRW5kKTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gb3B0aW9ucy5wcm9iYWJpbGl0eTtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSBvcHRpb25zLmh1bWFuaXplO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIGV2ZW50cyBmb3IgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIGh1bWFuaXplOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogXCIxbVwiLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogMSxcbiAgICAgICAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzY2hlZHVsZSBhbGwgb2YgdGhlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmVcbiAgICAgKiB3aXRoIHRoZSB1cGRhdGVkIHZhbHVlcy5cbiAgICAgKiBAcGFyYW0gYWZ0ZXIgT25seSByZXNjaGVkdWxlcyBldmVudHMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgX3Jlc2NoZWR1bGVFdmVudHMoYWZ0ZXIgPSAtMSkge1xuICAgICAgICAvLyBpZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgc2NoZWR1bGVzIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hGcm9tKGFmdGVyLCBldmVudCA9PiB7XG4gICAgICAgICAgICBsZXQgZHVyYXRpb247XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LmlkICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRUaWNrID0gZXZlbnQudGltZSArIE1hdGgucm91bmQodGhpcy5zdGFydE9mZnNldCAvIHRoaXMuX3BsYXliYWNrUmF0ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2xvb3AgPT09IHRydWUgfHwgaXNOdW1iZXIodGhpcy5fbG9vcCkgJiYgdGhpcy5fbG9vcCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBJbmZpbml0eTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTnVtYmVyKHRoaXMuX2xvb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9ICh0aGlzLl9sb29wKSAqIHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHRFdmVudCA9IHRoaXMuX3N0YXRlLmdldEFmdGVyKHN0YXJ0VGljayk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0RXZlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gTWF0aC5taW4oZHVyYXRpb24sIG5leHRFdmVudC50aW1lIC0gc3RhcnRUaWNrKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZHVyYXRpb24gIT09IEluZmluaXR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzY2hlZHVsZSBhIHN0b3Agc2luY2UgaXQncyBmaW5pdGUgZHVyYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBzdGFydFRpY2sgKyBkdXJhdGlvbiArIDEsIHsgaWQ6IC0xIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbCA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCkpO1xuICAgICAgICAgICAgICAgICAgICBldmVudC5pZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGhpcy5fdGljay5iaW5kKHRoaXMpLCBpbnRlcnZhbCwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpY2spLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5pZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUodGhpcy5fdGljay5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGljaykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBub3RlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdGFydCBmcm9tIHRoZSBzY2hlZHVsZWQgc3RhcnQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGFydE9mZnNldDtcbiAgICB9XG4gICAgc2V0IHN0YXJ0T2Zmc2V0KG9mZnNldCkge1xuICAgICAgICB0aGlzLl9zdGFydE9mZnNldCA9IG9mZnNldDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHByb2JhYmlsaXR5IG9mIHRoZSBub3RlcyBiZWluZyB0cmlnZ2VyZWQuXG4gICAgICovXG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgc2V0IHRvIHRydWUsIHdpbGwgYXBwbHkgc21hbGwgcmFuZG9tIHZhcmlhdGlvblxuICAgICAqIHRvIHRoZSBjYWxsYmFjayB0aW1lLiBJZiB0aGUgdmFsdWUgaXMgZ2l2ZW4gYXMgYSB0aW1lLCBpdCB3aWxsIHJhbmRvbWl6ZVxuICAgICAqIGJ5IHRoYXQgYW1vdW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZXZlbnQgPSBuZXcgVG9uZS5Ub25lRXZlbnQoKTtcbiAgICAgKiBldmVudC5odW1hbml6ZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0aGUgZXZlbnQgc2hvdWxkIHN0YXJ0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5hZGQoe1xuICAgICAgICAgICAgICAgIGlkOiAtMSxcbiAgICAgICAgICAgICAgICBzdGF0ZTogXCJzdGFydGVkXCIsXG4gICAgICAgICAgICAgICAgdGltZTogdGlja3MsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHModGlja3MpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBFdmVudCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdGhlIGV2ZW50IHNob3VsZCBzdG9wLlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLmNhbmNlbCh0aW1lKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGlja3MsIHsgaWQ6IC0xIH0pO1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX3N0YXRlLmdldEJlZm9yZSh0aWNrcyk7XG4gICAgICAgICAgICBsZXQgcmVzY2hlZHVsVGltZSA9IHRpY2tzO1xuICAgICAgICAgICAgaWYgKHByZXZpb3VzRXZlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICByZXNjaGVkdWxUaW1lID0gcHJldmlvdXNFdmVudC50aW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cyhyZXNjaGVkdWxUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggZXZlbnRzIHdpbGwgYmUgY2FuY2VsLlxuICAgICAqL1xuICAgIGNhbmNlbCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSBkZWZhdWx0QXJnKHRpbWUsIC1JbmZpbml0eSk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoRnJvbSh0aWNrcywgZXZlbnQgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihldmVudC5pZCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGlja3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGludm9rZXIuIEFsc29cbiAgICAgKiBjaGVja3MgaWYgdGhlIEV2ZW50IGlzIGRvbmUgcGxheWluZ1xuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgb2YgdGhlIGV2ZW50IGluIHNlY29uZHNcbiAgICAgKi9cbiAgICBfdGljayh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvYmFiaWxpdHkgPCAxICYmIE1hdGgucmFuZG9tKCkgPiB0aGlzLnByb2JhYmlsaXR5KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaHVtYW5pemUpIHtcbiAgICAgICAgICAgICAgICBsZXQgdmFyaWF0aW9uID0gMC4wMjtcbiAgICAgICAgICAgICAgICBpZiAoIWlzQm9vbGVhbih0aGlzLmh1bWFuaXplKSkge1xuICAgICAgICAgICAgICAgICAgICB2YXJpYXRpb24gPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmh1bWFuaXplKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGltZSArPSAoTWF0aC5yYW5kb20oKSAqIDIgLSAxKSAqIHZhcmlhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGhpcy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBkdXJhdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBfZ2V0TG9vcER1cmF0aW9uKCkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZCgodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCkgLyB0aGlzLl9wbGF5YmFja1JhdGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgbm90ZSBzaG91bGQgbG9vcCBvciBub3RcbiAgICAgKiBiZXR3ZWVuIFRvbmVFdmVudC5sb29wU3RhcnQgYW5kXG4gICAgICogVG9uZUV2ZW50Lmxvb3BFbmQuIElmIHNldCB0byB0cnVlLFxuICAgICAqIHRoZSBldmVudCB3aWxsIGxvb3AgaW5kZWZpbml0ZWx5LFxuICAgICAqIGlmIHNldCB0byBhIG51bWJlciBncmVhdGVyIHRoYW4gMVxuICAgICAqIGl0IHdpbGwgcGxheSBhIHNwZWNpZmljIG51bWJlciBvZlxuICAgICAqIHRpbWVzLCBpZiBzZXQgdG8gZmFsc2UsIDAgb3IgMSwgdGhlXG4gICAgICogcGFydCB3aWxsIG9ubHkgcGxheSBvbmNlLlxuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbm90ZS4gRGVmYXVsdHMgdG8gMS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG5vdGUgPSBuZXcgVG9uZS5Ub25lRXZlbnQoKTtcbiAgICAgKiBub3RlLmxvb3AgPSB0cnVlO1xuICAgICAqIC8vIHJlcGVhdCB0aGUgbm90ZSB0d2ljZSBhcyBmYXN0XG4gICAgICogbm90ZS5wbGF5YmFja1JhdGUgPSAyO1xuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wRW5kIHBvaW50IGlzIHRoZSB0aW1lIHRoZSBldmVudCB3aWxsIGxvb3BcbiAgICAgKiBpZiBUb25lRXZlbnQubG9vcCBpcyB0cnVlLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wRW5kKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQobG9vcEVuZCkge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGxvb3BFbmQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIHdoZW4gdGhlIGxvb3Agc2hvdWxkIHN0YXJ0LlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhsb29wU3RhcnQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHByb2dyZXNzIG9mIHRoZSBsb29wIGludGVydmFsLlxuICAgICAqIFJldHVybnMgMCBpZiB0aGUgZXZlbnQgaXMgbm90IHN0YXJ0ZWQgeWV0IG9yXG4gICAgICogaXQgaXMgbm90IHNldCB0byBsb29wLlxuICAgICAqL1xuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcztcbiAgICAgICAgICAgIGNvbnN0IGxhc3RFdmVudCA9IHRoaXMuX3N0YXRlLmdldCh0aWNrcyk7XG4gICAgICAgICAgICBpZiAobGFzdEV2ZW50ICE9PSBudWxsICYmIGxhc3RFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBsb29wRHVyYXRpb24gPSB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9ncmVzcyA9ICh0aWNrcyAtIGxhc3RFdmVudC50aW1lKSAlIGxvb3BEdXJhdGlvbjtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvZ3Jlc3MgLyBsb29wRHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lRXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUV2ZW50IH0gZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogTG9vcCBjcmVhdGVzIGEgbG9vcGVkIGNhbGxiYWNrIGF0IHRoZVxuICogc3BlY2lmaWVkIGludGVydmFsLiBUaGUgY2FsbGJhY2sgY2FuIGJlXG4gKiBzdGFydGVkLCBzdG9wcGVkIGFuZCBzY2hlZHVsZWQgYWxvbmdcbiAqIHRoZSBUcmFuc3BvcnQncyB0aW1lbGluZS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBsb29wID0gbmV3IFRvbmUuTG9vcCgodGltZSkgPT4ge1xuICogXHQvLyB0cmlnZ2VyZWQgZXZlcnkgZWlnaHRoIG5vdGUuXG4gKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogfSwgXCI4blwiKS5zdGFydCgwKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIExvb3AgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhMb29wLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJpbnRlcnZhbFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxvb3BcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKExvb3AuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImludGVydmFsXCJdKTtcbiAgICAgICAgdGhpcy5fZXZlbnQgPSBuZXcgVG9uZUV2ZW50KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgbG9vcEVuZDogb3B0aW9ucy5pbnRlcnZhbCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogb3B0aW9ucy5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogb3B0aW9ucy5wcm9iYWJpbGl0eVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIC8vIHNldCB0aGUgaXRlcmF0aW9uc1xuICAgICAgICB0aGlzLml0ZXJhdGlvbnMgPSBvcHRpb25zLml0ZXJhdGlvbnM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGludGVydmFsOiBcIjRuXCIsXG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIGl0ZXJhdGlvbnM6IEluZmluaXR5LFxuICAgICAgICAgICAgcHJvYmFiaWxpdHk6IDEsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIGh1bWFuaXplOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGxvb3AgYXQgdGhlIHNwZWNpZmllZCB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQncyB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RhcnQgdGhlIExvb3AuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxvb3AgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHN0b3AgdGhlIExvb3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBhZnRlciB3aGljaCBldmVudHMgd2lsbCBiZSBjYW5jZWwuXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuY2FuY2VsKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgZnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIG5vdGVzIHNob3VsZCBiZSBjYWxsZWRcbiAgICAgKiBAcGFyYW0gdGltZSAgVGhlIHRpbWUgdGhlIGV2ZW50IG9jY3Vyc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXRlIG9mIHRoZSBMb29wLCBlaXRoZXIgc3RhcnRlZCBvciBzdG9wcGVkLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnN0YXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgYXMgYSB2YWx1ZSBiZXR3ZWVuIDAtMS4gMCwgd2hlbiB0aGUgbG9vcCBpcyBzdG9wcGVkIG9yIGRvbmUgaXRlcmF0aW5nLlxuICAgICAqL1xuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnByb2dyZXNzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBiZXR3ZWVuIHN1Y2Nlc3NpdmUgY2FsbGJhY2tzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbG9vcCA9IG5ldyBUb25lLkxvb3AoKTtcbiAgICAgKiBsb29wLmludGVydmFsID0gXCI4blwiOyAvLyBsb29wIGV2ZXJ5IDhuXG4gICAgICovXG4gICAgZ2V0IGludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGludGVydmFsKGludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50Lmxvb3BFbmQgPSBpbnRlcnZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIGxvb3AuIFRoZSBub3JtYWwgcGxheWJhY2sgcmF0ZSBpcyAxIChubyBjaGFuZ2UpLlxuICAgICAqIEEgYHBsYXliYWNrUmF0ZWAgb2YgMiB3b3VsZCBiZSB0d2ljZSBhcyBmYXN0LlxuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSYW5kb20gdmFyaWF0aW9uICsvLTAuMDFzIHRvIHRoZSBzY2hlZHVsZWQgdGltZS5cbiAgICAgKiBPciBnaXZlIGl0IGEgdGltZSB2YWx1ZSB3aGljaCBpdCB3aWxsIHJhbmRvbWl6ZSBieS5cbiAgICAgKi9cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9ldmVudC5odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHByb2JhYmx5IG9mIHRoZSBjYWxsYmFjayBiZWluZyBpbnZva2VkLlxuICAgICAqL1xuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnByb2JhYmlsaXR5O1xuICAgIH1cbiAgICBzZXQgcHJvYmFiaWxpdHkocHJvYikge1xuICAgICAgICB0aGlzLl9ldmVudC5wcm9iYWJpbGl0eSA9IHByb2I7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGluZyB0aGUgTG9vcCBtZWFucyB0aGF0IG5vIGNhbGxiYWNrcyBhcmUgaW52b2tlZC5cbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyBvZiB0aGUgbG9vcC4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgYEluZmluaXR5YCAobG9vcCBmb3JldmVyKS5cbiAgICAgKi9cbiAgICBnZXQgaXRlcmF0aW9ucygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50Lmxvb3AgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHJldHVybiBJbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5sb29wO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBpdGVyYXRpb25zKGl0ZXJzKSB7XG4gICAgICAgIGlmIChpdGVycyA9PT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50Lmxvb3AgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnQubG9vcCA9IGl0ZXJzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Mb29wLmpzLm1hcCIsImltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNVbmRlZiB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbi8qKlxuICogUGFydCBpcyBhIGNvbGxlY3Rpb24gVG9uZUV2ZW50cyB3aGljaCBjYW4gYmUgc3RhcnRlZC9zdG9wcGVkIGFuZCBsb29wZWQgYXMgYSBzaW5nbGUgdW5pdC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCgodGltZSwgbm90ZSkgPT4ge1xuICogXHQvLyB0aGUgbm90ZXMgZ2l2ZW4gYXMgdGhlIHNlY29uZCBlbGVtZW50IGluIHRoZSBhcnJheVxuICogXHQvLyB3aWxsIGJlIHBhc3NlZCBpbiBhcyB0aGUgc2Vjb25kIGFyZ3VtZW50XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGUsIFwiOG5cIiwgdGltZSk7XG4gKiB9KSwgW1swLCBcIkMyXCJdLCBbXCIwOjJcIiwgXCJDM1wiXSwgW1wiMDozOjJcIiwgXCJHMlwiXV0pO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gdXNlIGFuIGFycmF5IG9mIG9iamVjdHMgYXMgbG9uZyBhcyB0aGUgb2JqZWN0IGhhcyBhIFwidGltZVwiIGF0dHJpYnV0ZVxuICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKCh0aW1lLCB2YWx1ZSkgPT4ge1xuICogXHQvLyB0aGUgdmFsdWUgaXMgYW4gb2JqZWN0IHdoaWNoIGNvbnRhaW5zIGJvdGggdGhlIG5vdGUgYW5kIHRoZSB2ZWxvY2l0eVxuICogXHRzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSh2YWx1ZS5ub3RlLCBcIjhuXCIsIHRpbWUsIHZhbHVlLnZlbG9jaXR5KTtcbiAqIH0pLCBbeyB0aW1lOiAwLCBub3RlOiBcIkMzXCIsIHZlbG9jaXR5OiAwLjkgfSxcbiAqIFx0eyB0aW1lOiBcIjA6MlwiLCBub3RlOiBcIkM0XCIsIHZlbG9jaXR5OiAwLjUgfVxuICogXSkuc3RhcnQoMCk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYXJ0IGV4dGVuZHMgVG9uZUV2ZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFydC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZXZlbnRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFydFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVHJhY2tzIHRoZSBzY2hlZHVsZWQgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBldmVudHMgdGhhdCBiZWxvbmcgdG8gdGhpcyBwYXJ0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgU2V0KCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIl0pO1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhpbmdzIGFyZSBhc3NpZ25lZCBpbiB0aGUgcmlnaHQgb3JkZXJcbiAgICAgICAgdGhpcy5fc3RhdGUuaW5jcmVhc2luZyA9IHRydWU7XG4gICAgICAgIC8vIGFkZCB0aGUgZXZlbnRzXG4gICAgICAgIG9wdGlvbnMuZXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkoZXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQoZXZlbnRbMF0sIGV2ZW50WzFdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGV2ZW50czogW10sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgV2hlbiB0byBzdGFydCB0aGUgcGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCAgVGhlIG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgcGFydCB0byBiZWdpbiBwbGF5aW5nIGF0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wID8gdGhpcy5fbG9vcFN0YXJ0IDogMCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRPZmZzZXQgPSB0aGlzLnRvVGlja3Mob2Zmc2V0KTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh7XG4gICAgICAgICAgICAgICAgaWQ6IC0xLFxuICAgICAgICAgICAgICAgIG9mZnNldDogY29tcHV0ZWRPZmZzZXQsXG4gICAgICAgICAgICAgICAgc3RhdGU6IFwic3RhcnRlZFwiLFxuICAgICAgICAgICAgICAgIHRpbWU6IHRpY2tzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydE5vdGUoZXZlbnQsIHRpY2tzLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGV2ZW50IGluIHRoZSBnaXZlbiBldmVudCBhdCB0aGUgY29ycmVjdCB0aW1lIGdpdmVuXG4gICAgICogdGhlIHRpY2tzIGFuZCBvZmZzZXQgYW5kIGxvb3BpbmcuXG4gICAgICogQHBhcmFtICBldmVudFxuICAgICAqIEBwYXJhbSAgdGlja3NcbiAgICAgKiBAcGFyYW0gIG9mZnNldFxuICAgICAqL1xuICAgIF9zdGFydE5vdGUoZXZlbnQsIHRpY2tzLCBvZmZzZXQpIHtcbiAgICAgICAgdGlja3MgLT0gb2Zmc2V0O1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID49IHRoaXMuX2xvb3BTdGFydCAmJiBldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BFbmQpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPCBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gc3RhcnQgaXQgb24gdGhlIG5leHQgbG9vcFxuICAgICAgICAgICAgICAgICAgICB0aWNrcyArPSB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPCB0aGlzLl9sb29wU3RhcnQgJiYgZXZlbnQuc3RhcnRPZmZzZXQgPj0gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgZXZlbnQubG9vcCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGV2ZW50LnN0YXJ0KG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgIGV2ZW50LnN0YXJ0KG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGFydE9mZnNldDtcbiAgICB9XG4gICAgc2V0IHN0YXJ0T2Zmc2V0KG9mZnNldCkge1xuICAgICAgICB0aGlzLl9zdGFydE9mZnNldCA9IG9mZnNldDtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudC5zdGFydE9mZnNldCArPSB0aGlzLl9zdGFydE9mZnNldDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHN0b3AgdGhlIHBhcnQuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGlja3MpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGlja3MpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50LnN0b3AodGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0L1NldCBhbiBFdmVudCdzIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIElmIGEgdmFsdWUgaXMgcGFzc2VkIGluIGFuZCBubyBldmVudCBleGlzdHMgYXRcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZSwgb25lIHdpbGwgYmUgY3JlYXRlZCB3aXRoIHRoYXQgdmFsdWUuXG4gICAgICogSWYgdHdvIGV2ZW50cyBhcmUgYXQgdGhlIHNhbWUgdGltZSwgdGhlIGZpcnN0IG9uZSB3aWxsXG4gICAgICogYmUgcmV0dXJuZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgpO1xuICAgICAqIHBhcnQuYXQoXCIxbVwiKTsgLy8gcmV0dXJucyB0aGUgcGFydCBhdCB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIHBhcnQuYXQoXCIybVwiLCBcIkMyXCIpOyAvLyBzZXQgdGhlIHZhbHVlIGF0IFwiMm1cIiB0byBDMi5cbiAgICAgKiAvLyBpZiBhbiBldmVudCBkaWRuJ3QgZXhpc3QgYXQgdGhhdCB0aW1lLCBpdCB3aWxsIGJlIGNyZWF0ZWQuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgb2YgdGhlIGV2ZW50IHRvIGdldCBvciBzZXQuXG4gICAgICogQHBhcmFtIHZhbHVlIElmIGEgdmFsdWUgaXMgcGFzc2VkIGluLCB0aGUgdmFsdWUgb2YgdGhlIGV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lIHdpbGwgYmUgc2V0IHRvIGl0LlxuICAgICAqL1xuICAgIGF0KHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHRpbWVJblRpY2tzID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKTtcbiAgICAgICAgY29uc3QgdGlja1RpbWUgPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIDEpLnRvU2Vjb25kcygpO1xuICAgICAgICBjb25zdCBpdGVyYXRvciA9IHRoaXMuX2V2ZW50cy52YWx1ZXMoKTtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgd2hpbGUgKCFyZXN1bHQuZG9uZSkge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSByZXN1bHQudmFsdWU7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnModGltZUluVGlja3MgLSBldmVudC5zdGFydE9mZnNldCkgPCB0aWNrVGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnZhbHVlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiB0aGVyZSB3YXMgbm8gZXZlbnQgYXQgdGhhdCB0aW1lLCBjcmVhdGUgb25lXG4gICAgICAgIGlmIChpc0RlZmluZWQodmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLmFkZCh0aW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICAvLyByZXR1cm4gdGhlIG5ldyBldmVudFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYXQodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhZGQodGltZSwgdmFsdWUpIHtcbiAgICAgICAgLy8gZXh0cmFjdCB0aGUgcGFyYW1ldGVyc1xuICAgICAgICBpZiAodGltZSBpbnN0YW5jZW9mIE9iamVjdCAmJiBSZWZsZWN0Lmhhcyh0aW1lLCBcInRpbWVcIikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGltZTtcbiAgICAgICAgICAgIHRpbWUgPSB2YWx1ZS50aW1lO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBsZXQgZXZlbnQ7XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIFRvbmVFdmVudCkge1xuICAgICAgICAgICAgZXZlbnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIGV2ZW50LmNhbGxiYWNrID0gdGhpcy5fdGljay5iaW5kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZXZlbnQgPSBuZXcgVG9uZUV2ZW50KHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fdGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBzdGFydCBvZmZzZXRcbiAgICAgICAgZXZlbnQuc3RhcnRPZmZzZXQgPSB0aWNrcztcbiAgICAgICAgLy8gaW5pdGlhbGl6ZSB0aGUgdmFsdWVzXG4gICAgICAgIGV2ZW50LnNldCh7XG4gICAgICAgICAgICBodW1hbml6ZTogdGhpcy5odW1hbml6ZSxcbiAgICAgICAgICAgIGxvb3A6IHRoaXMubG9vcCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IHRoaXMubG9vcEVuZCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5sb29wU3RhcnQsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMucGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgcHJvYmFiaWxpdHk6IHRoaXMucHJvYmFiaWxpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKGV2ZW50KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG5vdGUgaWYgaXQgc2hvdWxkIGJlIHBsYXllZCByaWdodCBub3dcbiAgICAgICAgdGhpcy5fcmVzdGFydEV2ZW50KGV2ZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc3RhcnQgdGhlIGdpdmVuIGV2ZW50XG4gICAgICovXG4gICAgX3Jlc3RhcnRFdmVudChldmVudCkge1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoKChzdGF0ZUV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoc3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydE5vdGUoZXZlbnQsIHN0YXRlRXZlbnQudGltZSwgc3RhdGVFdmVudC5vZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gc3RvcCB0aGUgbm90ZVxuICAgICAgICAgICAgICAgIGV2ZW50LnN0b3AobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBzdGF0ZUV2ZW50LnRpbWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJlbW92ZSh0aW1lLCB2YWx1ZSkge1xuICAgICAgICAvLyBleHRyYWN0IHRoZSBwYXJhbWV0ZXJzXG4gICAgICAgIGlmIChpc09iamVjdCh0aW1lKSAmJiB0aW1lLmhhc093blByb3BlcnR5KFwidGltZVwiKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aW1lO1xuICAgICAgICAgICAgdGltZSA9IHZhbHVlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgdGltZSA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID09PSB0aW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzVW5kZWYodmFsdWUpIHx8IChpc0RlZmluZWQodmFsdWUpICYmIGV2ZW50LnZhbHVlID09PSB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmRlbGV0ZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFsbCBvZiB0aGUgbm90ZXMgZnJvbSB0aGUgZ3JvdXAuXG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4gZXZlbnQuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgc2NoZWR1bGVkIHN0YXRlIGNoYW5nZSBldmVudHM6IGkuZS4gXCJzdGFydFwiIGFuZCBcInN0b3BcIi5cbiAgICAgKiBAcGFyYW0gYWZ0ZXIgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgZXZlbnRzLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IGV2ZW50LmNhbmNlbChhZnRlcikpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGhpcy50b1RpY2tzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKi9cbiAgICBfZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgUGFydCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5fZm9yRWFjaChjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXR0cmlidXRlIG9mIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICogQHBhcmFtICBhdHRyICB0aGUgYXR0cmlidXRlIHRvIHNldFxuICAgICAqIEBwYXJhbSAgdmFsdWUgICAgICBUaGUgdmFsdWUgdG8gc2V0IGl0IHRvXG4gICAgICovXG4gICAgX3NldEFsbChhdHRyLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50W2F0dHJdID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCB0aWNrIG1ldGhvZFxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgb2YgdGhlIGV2ZW50IGluIHNlY29uZHNcbiAgICAgKi9cbiAgICBfdGljayh0aW1lLCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXRoaXMubXV0ZSkge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRGV0ZXJtaW5lIGlmIHRoZSBldmVudCBzaG91bGQgYmUgY3VycmVudGx5IGxvb3BpbmdcbiAgICAgKiBnaXZlbiB0aGUgbG9vcCBib3VuZHJpZXMgb2YgdGhpcyBQYXJ0LlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBldmVudCB0byB0ZXN0XG4gICAgICovXG4gICAgX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLl9sb29wICYmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCB8fCBldmVudC5zdGFydE9mZnNldCA+PSB0aGlzLl9sb29wRW5kKSkge1xuICAgICAgICAgICAgZXZlbnQuY2FuY2VsKDApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnN0YXRlID09PSBcInN0b3BwZWRcIikge1xuICAgICAgICAgICAgLy8gcmVzY2hlZHVsZSBpdCBpZiBpdCdzIHN0b3BwZWRcbiAgICAgICAgICAgIHRoaXMuX3Jlc3RhcnRFdmVudChldmVudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3Byb2JhYmlsaXR5ID0gcHJvYjtcbiAgICAgICAgdGhpcy5fc2V0QWxsKFwicHJvYmFiaWxpdHlcIiwgcHJvYik7XG4gICAgfVxuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2h1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX2h1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgICAgICB0aGlzLl9zZXRBbGwoXCJodW1hbml6ZVwiLCB2YXJpYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgcGFydCBzaG91bGQgbG9vcCBvciBub3RcbiAgICAgKiBiZXR3ZWVuIFBhcnQubG9vcFN0YXJ0IGFuZFxuICAgICAqIFBhcnQubG9vcEVuZC4gSWYgc2V0IHRvIHRydWUsXG4gICAgICogdGhlIHBhcnQgd2lsbCBsb29wIGluZGVmaW5pdGVseSxcbiAgICAgKiBpZiBzZXQgdG8gYSBudW1iZXIgZ3JlYXRlciB0aGFuIDFcbiAgICAgKiBpdCB3aWxsIHBsYXkgYSBzcGVjaWZpYyBudW1iZXIgb2ZcbiAgICAgKiB0aW1lcywgaWYgc2V0IHRvIGZhbHNlLCAwIG9yIDEsIHRoZVxuICAgICAqIHBhcnQgd2lsbCBvbmx5IHBsYXkgb25jZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCk7XG4gICAgICogLy8gbG9vcCB0aGUgcGFydCA4IHRpbWVzXG4gICAgICogcGFydC5sb29wID0gODtcbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fbG9vcCA9IGxvb3A7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQubG9vcFN0YXJ0ID0gdGhpcy5sb29wU3RhcnQ7XG4gICAgICAgICAgICBldmVudC5sb29wRW5kID0gdGhpcy5sb29wRW5kO1xuICAgICAgICAgICAgZXZlbnQubG9vcCA9IGxvb3A7XG4gICAgICAgICAgICB0aGlzLl90ZXN0TG9vcEJvdW5kcmllcyhldmVudCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcEVuZCBwb2ludCBkZXRlcm1pbmVzIHdoZW4gaXQgd2lsbFxuICAgICAqIGxvb3AgaWYgUGFydC5sb29wIGlzIHRydWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BFbmQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MobG9vcEVuZCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBldmVudC5sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXN0TG9vcEJvdW5kcmllcyhldmVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcFN0YXJ0IHBvaW50IGRldGVybWluZXMgd2hlbiBpdCB3aWxsXG4gICAgICogbG9vcCBpZiBQYXJ0Lmxvb3AgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wU3RhcnQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3MobG9vcFN0YXJ0KTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3BTdGFydCA9IHRoaXMubG9vcFN0YXJ0O1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBwYXJ0XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIHRoaXMuX3NldEFsbChcInBsYXliYWNrUmF0ZVwiLCByYXRlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBzY2hlZHVsZWQgbm90ZXMgaW4gdGhlIHBhcnQuXG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cy5zaXplO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFydC5qcy5tYXAiLCJpbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBjbGFtcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBTdGFydCBhdCB0aGUgZmlyc3QgdmFsdWUgYW5kIGdvIHVwIHRvIHRoZSBsYXN0XG4gKi9cbmZ1bmN0aW9uKiB1cFBhdHRlcm5HZW4odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPCB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgaW5kZXgrKztcbiAgICB9XG59XG4vKipcbiAqIFN0YXJ0IGF0IHRoZSBsYXN0IHZhbHVlIGFuZCBnbyBkb3duIHRvIDBcbiAqL1xuZnVuY3Rpb24qIGRvd25QYXR0ZXJuR2VuKHZhbHVlcykge1xuICAgIGxldCBpbmRleCA9IHZhbHVlcy5sZW5ndGggLSAxO1xuICAgIHdoaWxlIChpbmRleCA+PSAwKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgaW5kZXgtLTtcbiAgICB9XG59XG4vKipcbiAqIEluZmluaXRlbHkgeWllbGQgdGhlIGdlbmVyYXRvclxuICovXG5mdW5jdGlvbiogaW5maW5pdGVHZW4odmFsdWVzLCBnZW4pIHtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICB5aWVsZCogZ2VuKHZhbHVlcyk7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCB0aGUgaW5kZXggaXMgaW4gdGhlIGdpdmVuIHJhbmdlXG4gKi9cbmZ1bmN0aW9uIGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcykge1xuICAgIHJldHVybiBjbGFtcChpbmRleCwgMCwgdmFsdWVzLmxlbmd0aCAtIDEpO1xufVxuLyoqXG4gKiBBbHRlcm5hdGUgYmV0d2VlbiB0d28gZ2VuZXJhdG9yc1xuICovXG5mdW5jdGlvbiogYWx0ZXJuYXRpbmdHZW5lcmF0b3IodmFsdWVzLCBkaXJlY3Rpb25VcCkge1xuICAgIGxldCBpbmRleCA9IGRpcmVjdGlvblVwID8gMCA6IHZhbHVlcy5sZW5ndGggLSAxO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgaWYgKGRpcmVjdGlvblVwKSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgaWYgKGluZGV4ID49IHZhbHVlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uVXAgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4LS07XG4gICAgICAgICAgICBpZiAoaW5kZXggPD0gMCkge1xuICAgICAgICAgICAgICAgIGRpcmVjdGlvblVwID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogU3RhcnRpbmcgZnJvbSB0aGUgYm90dG9tIG1vdmUgdXAgMiwgZG93biAxXG4gKi9cbmZ1bmN0aW9uKiBqdW1wVXAodmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICBsZXQgc3RlcEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPCB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgc3RlcEluZGV4Kys7XG4gICAgICAgIGluZGV4ICs9IChzdGVwSW5kZXggJSAyID8gMiA6IC0xKTtcbiAgICB9XG59XG4vKipcbiAqIFN0YXJ0aW5nIGZyb20gdGhlIHRvcCBtb3ZlIGRvd24gMiwgdXAgMVxuICovXG5mdW5jdGlvbioganVtcERvd24odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgbGV0IHN0ZXBJbmRleCA9IDA7XG4gICAgd2hpbGUgKGluZGV4ID49IDApIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBzdGVwSW5kZXgrKztcbiAgICAgICAgaW5kZXggKz0gKHN0ZXBJbmRleCAlIDIgPyAtMiA6IDEpO1xuICAgIH1cbn1cbi8qKlxuICogQ2hvb3NlIGEgcmFuZG9tIGluZGV4IGVhY2ggdGltZVxuICovXG5mdW5jdGlvbiogcmFuZG9tR2VuKHZhbHVlcykge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGNvbnN0IHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tyYW5kb21JbmRleF07XG4gICAgfVxufVxuLyoqXG4gKiBSYW5kb21seSBnbyB0aHJvdWdoIGFsbCBvZiB0aGUgdmFsdWVzIG9uY2UgYmVmb3JlIGNob29zaW5nIGEgbmV3IHJhbmRvbSBvcmRlclxuICovXG5mdW5jdGlvbiogcmFuZG9tT25jZSh2YWx1ZXMpIHtcbiAgICAvLyBjcmVhdGUgYW4gYXJyYXkgb2YgaW5kaWNlc1xuICAgIGNvbnN0IGNvcHkgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb3B5LnB1c2goaSk7XG4gICAgfVxuICAgIHdoaWxlIChjb3B5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gcmFuZG9tIGNob29zZSBhbiBpbmRleCwgYW5kIHRoZW4gcmVtb3ZlIGl0IHNvIGl0J3Mgbm90IGNob3NlbiBhZ2FpblxuICAgICAgICBjb25zdCByYW5kVmFsID0gY29weS5zcGxpY2UoTWF0aC5mbG9vcihjb3B5Lmxlbmd0aCAqIE1hdGgucmFuZG9tKCkpLCAxKTtcbiAgICAgICAgY29uc3QgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKHJhbmRWYWxbMF0sIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgfVxufVxuLyoqXG4gKiBSYW5kb21seSBjaG9vc2UgdG8gd2FsayB1cCBvciBkb3duIDEgaW5kZXggaW4gdGhlIHZhbHVlcyBhcnJheVxuICovXG5mdW5jdGlvbiogcmFuZG9tV2Fsayh2YWx1ZXMpIHtcbiAgICAvLyByYW5kb21seSBjaG9vc2UgYSBzdGFydGluZyBpbmRleCBpbiB0aGUgdmFsdWVzIGFycmF5XG4gICAgbGV0IGluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdmFsdWVzLmxlbmd0aCk7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICBpbmRleCsrOyAvLyBhdCBib3R0b20gb2YgYXJyYXksIHNvIGZvcmNlIHVwd2FyZCBzdGVwXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPT09IHZhbHVlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICBpbmRleC0tOyAvLyBhdCB0b3Agb2YgYXJyYXksIHNvIGZvcmNlIGRvd253YXJkIHN0ZXBcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChNYXRoLnJhbmRvbSgpIDwgMC41KSB7IC8vIGVsc2UgY2hvb3NlIHJhbmRvbSBkb3dud2FyZCBvciB1cHdhcmQgc3RlcFxuICAgICAgICAgICAgaW5kZXgtLTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFBhdHRlcm5HZW5lcmF0b3IgcmV0dXJucyBhIGdlbmVyYXRvciB3aGljaCB3aWxsIGl0ZXJhdGUgb3ZlciB0aGUgZ2l2ZW4gYXJyYXlcbiAqIG9mIHZhbHVlcyBhbmQgeWllbGQgdGhlIGl0ZW1zIGFjY29yZGluZyB0byB0aGUgcGFzc2VkIGluIHBhdHRlcm5cbiAqIEBwYXJhbSB2YWx1ZXMgQW4gYXJyYXkgb2YgdmFsdWVzIHRvIGl0ZXJhdGUgb3ZlclxuICogQHBhcmFtIHBhdHRlcm4gVGhlIG5hbWUgb2YgdGhlIHBhdHRlcm4gdXNlIHdoZW4gaXRlcmF0aW5nIG92ZXJcbiAqIEBwYXJhbSBpbmRleCBXaGVyZSB0byBzdGFydCBpbiB0aGUgb2Zmc2V0IG9mIHRoZSB2YWx1ZXMgYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uKiBQYXR0ZXJuR2VuZXJhdG9yKHZhbHVlcywgcGF0dGVybiA9IFwidXBcIiwgaW5kZXggPSAwKSB7XG4gICAgLy8gc2FmZWd1YXJkc1xuICAgIGFzc2VydCh2YWx1ZXMubGVuZ3RoID4gMCwgXCJUaGUgYXJyYXkgbXVzdCBoYXZlIG1vcmUgdGhhbiBvbmUgdmFsdWUgaW4gaXRcIik7XG4gICAgc3dpdGNoIChwYXR0ZXJuKSB7XG4gICAgICAgIGNhc2UgXCJ1cFwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywgdXBQYXR0ZXJuR2VuKTtcbiAgICAgICAgY2FzZSBcImRvd25cIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGRvd25QYXR0ZXJuR2VuKTtcbiAgICAgICAgY2FzZSBcInVwRG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGFsdGVybmF0aW5nR2VuZXJhdG9yKHZhbHVlcywgdHJ1ZSk7XG4gICAgICAgIGNhc2UgXCJkb3duVXBcIjpcbiAgICAgICAgICAgIHlpZWxkKiBhbHRlcm5hdGluZ0dlbmVyYXRvcih2YWx1ZXMsIGZhbHNlKTtcbiAgICAgICAgY2FzZSBcImFsdGVybmF0ZVVwXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCBqdW1wVXApO1xuICAgICAgICBjYXNlIFwiYWx0ZXJuYXRlRG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywganVtcERvd24pO1xuICAgICAgICBjYXNlIFwicmFuZG9tXCI6XG4gICAgICAgICAgICB5aWVsZCogcmFuZG9tR2VuKHZhbHVlcyk7XG4gICAgICAgIGNhc2UgXCJyYW5kb21PbmNlXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCByYW5kb21PbmNlKTtcbiAgICAgICAgY2FzZSBcInJhbmRvbVdhbGtcIjpcbiAgICAgICAgICAgIHlpZWxkKiByYW5kb21XYWxrKHZhbHVlcyk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGF0dGVybkdlbmVyYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBMb29wIH0gZnJvbSBcIi4vTG9vcFwiO1xuaW1wb3J0IHsgUGF0dGVybkdlbmVyYXRvciB9IGZyb20gXCIuL1BhdHRlcm5HZW5lcmF0b3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBhdHRlcm4gYXJwZWdnaWF0ZXMgYmV0d2VlbiB0aGUgZ2l2ZW4gbm90ZXNcbiAqIGluIGEgbnVtYmVyIG9mIHBhdHRlcm5zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBhdHRlcm4gPSBuZXcgVG9uZS5QYXR0ZXJuKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdC8vIHRoZSBvcmRlciBvZiB0aGUgbm90ZXMgcGFzc2VkIGluIGRlcGVuZHMgb24gdGhlIHBhdHRlcm5cbiAqIH0sIFtcIkMyXCIsIFwiRDRcIiwgXCJFNVwiLCBcIkE2XCJdLCBcInVwRG93blwiKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgUGF0dGVybiBleHRlbmRzIExvb3Age1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXR0ZXJuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZXNcIiwgXCJwYXR0ZXJuXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGF0dGVyblwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGF0dGVybi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVzXCIsIFwicGF0dGVyblwiXSk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSBvcHRpb25zLnZhbHVlcztcbiAgICAgICAgdGhpcy5fcGF0dGVybiA9IFBhdHRlcm5HZW5lcmF0b3Iob3B0aW9ucy52YWx1ZXMsIG9wdGlvbnMucGF0dGVybik7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnBhdHRlcm47XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTG9vcC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwYXR0ZXJuOiBcInVwXCIsXG4gICAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgbm90ZXMgc2hvdWxkIGJlIGNhbGxlZFxuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9wYXR0ZXJuLm5leHQoKTtcbiAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZS52YWx1ZTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB0aGlzLl92YWx1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhcnJheSBvZiBldmVudHMuXG4gICAgICovXG4gICAgZ2V0IHZhbHVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlcztcbiAgICB9XG4gICAgc2V0IHZhbHVlcyh2YWwpIHtcbiAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsO1xuICAgICAgICAvLyByZXNldCB0aGUgcGF0dGVyblxuICAgICAgICB0aGlzLnBhdHRlcm4gPSB0aGlzLl90eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgcGF0dGVybi5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhdHRlcm4gdHlwZS4gU2VlIFRvbmUuQ3RybFBhdHRlcm4gZm9yIHRoZSBmdWxsIGxpc3Qgb2YgcGF0dGVybnMuXG4gICAgICovXG4gICAgZ2V0IHBhdHRlcm4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgcGF0dGVybihwYXR0ZXJuKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBwYXR0ZXJuO1xuICAgICAgICB0aGlzLl9wYXR0ZXJuID0gUGF0dGVybkdlbmVyYXRvcih0aGlzLl92YWx1ZXMsIHRoaXMuX3R5cGUpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhdHRlcm4uanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzU3RyaW5nIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFBhcnQgfSBmcm9tIFwiLi9QYXJ0XCI7XG5pbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbi8qKlxuICogQSBzZXF1ZW5jZSBpcyBhbiBhbHRlcm5hdGUgbm90YXRpb24gb2YgYSBwYXJ0LiBJbnN0ZWFkXG4gKiBvZiBwYXNzaW5nIGluIGFuIGFycmF5IG9mIFt0aW1lLCBldmVudF0gcGFpcnMsIHBhc3NcbiAqIGluIGFuIGFycmF5IG9mIGV2ZW50cyB3aGljaCB3aWxsIGJlIHNwYWNlZCBhdCB0aGVcbiAqIGdpdmVuIHN1YmRpdmlzaW9uLiBTdWItYXJyYXlzIHdpbGwgc3ViZGl2aWRlIHRoYXQgYmVhdFxuICogYnkgdGhlIG51bWJlciBvZiBpdGVtcyBhcmUgaW4gdGhlIGFycmF5LlxuICogU2VxdWVuY2Ugbm90YXRpb24gaW5zcGlyYXRpb24gZnJvbSBbVGlkYWxdKGh0dHA6Ly95YXh1Lm9yZy90aWRhbC8pXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHNlcSA9IG5ldyBUb25lLlNlcXVlbmNlKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGUsIDAuMSwgdGltZSk7XG4gKiBcdC8vIHN1YmRpdmlzaW9ucyBhcmUgZ2l2ZW4gYXMgc3ViYXJyYXlzXG4gKiB9LCBbXCJDNFwiLCBbXCJFNFwiLCBcIkQ0XCIsIFwiRTRcIl0sIFwiRzRcIiwgW1wiQTRcIiwgXCJHNFwiXV0pLnN0YXJ0KDApO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgU2VxdWVuY2UgZXh0ZW5kcyBUb25lRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTZXF1ZW5jZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZXZlbnRzXCIsIFwic3ViZGl2aXNpb25cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTZXF1ZW5jZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9iamVjdCByZXNwb25zaWJsZSBmb3Igc2NoZWR1bGluZyBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGFydCA9IG5ldyBQYXJ0KHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl9zZXFDYWxsYmFjay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHByaXZhdGUgcmVmZXJlbmNlIHRvIGFsbCBvZiB0aGUgc2VxdWVuY2UgcHJveGllc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcHJveGllZCBhcnJheVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzQXJyYXkgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNlcXVlbmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIiwgXCJzdWJkaXZpc2lvblwiXSk7XG4gICAgICAgIHRoaXMuX3N1YmRpdmlzaW9uID0gdGhpcy50b1RpY2tzKG9wdGlvbnMuc3ViZGl2aXNpb24pO1xuICAgICAgICB0aGlzLmV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuICAgICAgICAvLyBzZXQgYWxsIG9mIHRoZSB2YWx1ZXNcbiAgICAgICAgdGhpcy5sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMucHJvYmFiaWxpdHkgPSBvcHRpb25zLnByb2JhYmlsaXR5O1xuICAgICAgICB0aGlzLmh1bWFuaXplID0gb3B0aW9ucy5odW1hbml6ZTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCBbXCJ2YWx1ZVwiXSksIHtcbiAgICAgICAgICAgIGV2ZW50czogW10sXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHN1YmRpdmlzaW9uOiBcIjhuXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW50ZXJuYWwgY2FsbGJhY2sgZm9yIHdoZW4gYW4gZXZlbnQgaXMgaW52b2tlZFxuICAgICAqL1xuICAgIF9zZXFDYWxsYmFjayh0aW1lLCB2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzZXF1ZW5jZVxuICAgICAqL1xuICAgIGdldCBldmVudHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHM7XG4gICAgfVxuICAgIHNldCBldmVudHMocykge1xuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0FycmF5ID0gcztcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gdGhpcy5fY3JlYXRlU2VxdWVuY2UodGhpcy5fZXZlbnRzQXJyYXkpO1xuICAgICAgICB0aGlzLl9ldmVudHNVcGRhdGVkKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBXaGVuIHRvIHN0YXJ0IHRoZSBwYXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IGluZGV4IHRvIHN0YXJ0IGF0XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3BhcnQuc3RhcnQodGltZSwgb2Zmc2V0ID8gdGhpcy5faW5kZXhUaW1lKG9mZnNldCkgOiBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN1YmRpdmlzaW9uIG9mIHRoZSBzZXF1ZW5jZS4gVGhpcyBjYW4gb25seSBiZVxuICAgICAqIHNldCBpbiB0aGUgY29uc3RydWN0b3IuIFRoZSBzdWJkaXZpc2lvbiBpcyB0aGVcbiAgICAgKiBpbnRlcnZhbCBiZXR3ZWVuIHN1Y2Nlc3NpdmUgc3RlcHMuXG4gICAgICovXG4gICAgZ2V0IHN1YmRpdmlzaW9uKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9zdWJkaXZpc2lvbikudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIHNlcXVlbmNlIHByb3h5IHdoaWNoIGNhbiBiZSBtb25pdG9yZWQgdG8gY3JlYXRlIHN1YnNlcXVlbmNlc1xuICAgICAqL1xuICAgIF9jcmVhdGVTZXF1ZW5jZShhcnJheSkge1xuICAgICAgICByZXR1cm4gbmV3IFByb3h5KGFycmF5LCB7XG4gICAgICAgICAgICBnZXQ6ICh0YXJnZXQsIHByb3BlcnR5KSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gcHJvcGVydHkgaXMgaW5kZXggaW4gdGhpcyBjYXNlXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiAodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcocHJvcGVydHkpICYmIGlzRmluaXRlKHBhcnNlSW50KHByb3BlcnR5LCAxMCkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHRoaXMuX2NyZWF0ZVNlcXVlbmNlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNVcGRhdGVkKCk7XG4gICAgICAgICAgICAgICAgLy8gcmV0dXJuIHRydWUgdG8gYWNjZXB0IHRoZSBjaGFuZ2VzXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgc2VxdWVuY2UgaGFzIGNoYW5nZWQsIGFsbCBvZiB0aGUgZXZlbnRzIG5lZWQgdG8gYmUgcmVjcmVhdGVkXG4gICAgICovXG4gICAgX2V2ZW50c1VwZGF0ZWQoKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZVNlcXVlbmNlKHRoaXMuX2V2ZW50c0FycmF5LCB0aGlzLl9zdWJkaXZpc2lvbiwgdGhpcy5zdGFydE9mZnNldCk7XG4gICAgICAgIC8vIHVwZGF0ZSB0aGUgbG9vcEVuZFxuICAgICAgICB0aGlzLmxvb3BFbmQgPSB0aGlzLmxvb3BFbmQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJlc2NoZWR1bGUgYWxsIG9mIHRoZSBldmVudHMgdGhhdCBuZWVkIHRvIGJlIHJlc2NoZWR1bGVkXG4gICAgICovXG4gICAgX3Jlc2NoZWR1bGVTZXF1ZW5jZShzZXF1ZW5jZSwgc3ViZGl2aXNpb24sIHN0YXJ0T2Zmc2V0KSB7XG4gICAgICAgIHNlcXVlbmNlLmZvckVhY2goKHZhbHVlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZXZlbnRPZmZzZXQgPSBpbmRleCAqIChzdWJkaXZpc2lvbikgKyBzdGFydE9mZnNldDtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVTZXF1ZW5jZSh2YWx1ZSwgc3ViZGl2aXNpb24gLyB2YWx1ZS5sZW5ndGgsIGV2ZW50T2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgZXZlbnRPZmZzZXQsIFwiaVwiKS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0LmFkZChzdGFydFRpbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGltZSBvZiB0aGUgaW5kZXggZ2l2ZW4gdGhlIFNlcXVlbmNlJ3Mgc3ViZGl2aXNpb25cbiAgICAgKiBAcGFyYW0gIGluZGV4XG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGF0IGluZGV4XG4gICAgICovXG4gICAgX2luZGV4VGltZShpbmRleCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBpbmRleCAqICh0aGlzLl9zdWJkaXZpc2lvbikgKyB0aGlzLnN0YXJ0T2Zmc2V0KS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXIgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5fcGFydC5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYXJ0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFBST1hZIENBTExTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmxvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGwpIHtcbiAgICAgICAgdGhpcy5fcGFydC5sb29wID0gbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBzZXF1ZW5jZSBzaG91bGQgc3RhcnQgbG9vcGluZ1xuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wU3RhcnQ7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gaW5kZXg7XG4gICAgICAgIHRoaXMuX3BhcnQubG9vcFN0YXJ0ID0gdGhpcy5faW5kZXhUaW1lKGluZGV4KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGluZGV4IGF0IHdoaWNoIHRoZSBzZXF1ZW5jZSBzaG91bGQgZW5kIGxvb3BpbmdcbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGluZGV4KSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSBpbmRleDtcbiAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0Lmxvb3BFbmQgPSB0aGlzLl9pbmRleFRpbWUodGhpcy5fZXZlbnRzQXJyYXkubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnQubG9vcEVuZCA9IHRoaXMuX2luZGV4VGltZShpbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHN0YXJ0T2Zmc2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5zdGFydE9mZnNldDtcbiAgICB9XG4gICAgc2V0IHN0YXJ0T2Zmc2V0KHN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX3BhcnQuc3RhcnRPZmZzZXQgPSBzdGFydDtcbiAgICB9XG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQucGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGFydC5wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgIH1cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnByb2JhYmlsaXR5O1xuICAgIH1cbiAgICBzZXQgcHJvYmFiaWxpdHkocHJvYikge1xuICAgICAgICB0aGlzLl9wYXJ0LnByb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5wcm9ncmVzcztcbiAgICB9XG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9wYXJ0Lmh1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBldmVudHNcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5sZW5ndGg7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U2VxdWVuY2UuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vTG9vcFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGFydFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGF0dGVyblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2VxdWVuY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdCwgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBHYWluVG9BdWRpbyB9IGZyb20gXCIuLi8uLi9zaWduYWwvR2FpblRvQXVkaW9cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG4vKipcbiAqIFRvbmUuQ3Jvc3NmYWRlIHByb3ZpZGVzIGVxdWFsIHBvd2VyIGZhZGluZyBiZXR3ZWVuIHR3byBpbnB1dHMuXG4gKiBNb3JlIG9uIGNyb3NzZmFkaW5nIHRlY2huaXF1ZSBbaGVyZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRmFkZV8oYXVkaW9fZW5naW5lZXJpbmcpI0Nyb3NzZmFkaW5nKS5cbiAqIGBgYFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tK1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICs+IGlucHV0IGEgKz4tLStcbiAqICstLS0tLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAgICAgfCAgICAgICAgIHwgICB8XG4gKiB8IDFzIHNpZ25hbCArPi0tPiBzdGVyZW9QYW5uZXJOb2RlICBMICs+LS0tLT4gZ2FpbiAgICB8ICAgfFxuICogKy0tLS0tLS0tLS0tKyAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICArLS0tLS0tLS0tKyAgIHxcbiAqICAgICAgICAgICAgICAgKy0+IHBhbiAgICAgICAgICAgICAgIFIgKz4tKyAgICAgICAgICAgICAgICB8ICAgKy0tLS0tLS0tK1xuICogICAgICAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0rICB8ICAgICAgICAgICAgICAgICstLS0+IG91dHB1dCArPlxuICogICstLS0tLS0rICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICArLS0tLS0tLS0tKyAgIHwgICArLS0tLS0tLS0rXG4gKiAgfCBmYWRlICs+LS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKz4gaW5wdXQgYiArPi0tK1xuICogICstLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICB8ICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0+IGdhaW4gICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY3Jvc3NGYWRlID0gbmV3IFRvbmUuQ3Jvc3NGYWRlKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gY29ubmVjdCB0d28gaW5wdXRzIFRvbmUudG8gYS9iXG4gKiBjb25zdCBpbnB1dEEgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDQ0MCwgXCJzcXVhcmVcIikuY29ubmVjdChjcm9zc0ZhZGUuYSkuc3RhcnQoKTtcbiAqIGNvbnN0IGlucHV0QiA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNpbmVcIikuY29ubmVjdChjcm9zc0ZhZGUuYikuc3RhcnQoKTtcbiAqIC8vIHVzZSB0aGUgZmFkZSB0byBjb250cm9sIHRoZSBtaXggYmV0d2VlbiB0aGUgdHdvXG4gKiBjcm9zc0ZhZGUuZmFkZS52YWx1ZSA9IDAuNTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENyb3NzRmFkZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKENyb3NzRmFkZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZhZGVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ3Jvc3NGYWRlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY3Jvc3NmYWRpbmcgaXMgZG9uZSBieSBhIFN0ZXJlb1Bhbm5lck5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNwbGl0IHRoZSBvdXRwdXQgb2YgdGhlIHBhbm5lciBub2RlIGludG8gdHdvIHZhbHVlcyB1c2VkIHRvIGNvbnRyb2wgdGhlIGdhaW5zLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3BsaXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKDIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udmVydCB0aGUgZmFkZSB2YWx1ZSBpbnRvIGFuIGF1ZGlvIHJhbmdlIHZhbHVlIHNvIGl0IGNhbiBiZSBjb25uZWN0ZWRcbiAgICAgICAgICogdG8gdGhlIHBhbm5lci5wYW4gQXVkaW9QYXJhbVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZzJhID0gbmV3IEdhaW5Ub0F1ZGlvKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IHdoaWNoIGlzIGF0IGZ1bGwgbGV2ZWwgd2hlbiBmYWRlID0gMFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5hID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgd2hpY2ggaXMgYXQgZnVsbCBsZXZlbCB3aGVuIGZhZGUgPSAxXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmIgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgaXMgYSBtaXggYmV0d2VlbiBgYWAgYW5kIGBiYCBhdCB0aGUgcmF0aW8gb2YgYGZhZGVgXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuYSwgdGhpcy5iXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENyb3NzRmFkZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZhZGVcIl0pO1xuICAgICAgICB0aGlzLmZhZGUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mYWRlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmYWRlXCIpO1xuICAgICAgICB0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMSkuY29ubmVjdCh0aGlzLl9wYW5uZXIpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIC8vIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFxuICAgICAgICAvLyBkb2Vzbid0IG1ha2UgYW55IGRpZmZlcmVuY2UgZm9yIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9pc3N1ZXMvNjQ3XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnQgPSAxO1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9zcGxpdCwgdGhpcy5hLmdhaW4sIDApO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NwbGl0LCB0aGlzLmIuZ2FpbiwgMSk7XG4gICAgICAgIHRoaXMuZmFkZS5jaGFpbih0aGlzLl9nMmEsIHRoaXMuX3Bhbm5lci5wYW4pO1xuICAgICAgICB0aGlzLmEuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuYi5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZhZGU6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5hLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5iLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZhZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nMmEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNyb3NzRmFkZS5qcy5tYXAiLCJpbXBvcnQgeyBDcm9zc0ZhZGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvQ3Jvc3NGYWRlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEVmZmVjdCBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgZWZmZWN0cy4gQ29ubmVjdCB0aGUgZWZmZWN0IGJldHdlZW5cbiAqIHRoZSBlZmZlY3RTZW5kIGFuZCBlZmZlY3RSZXR1cm4gR2Fpbk5vZGVzLCB0aGVuIGNvbnRyb2wgdGhlIGFtb3VudCBvZlxuICogZWZmZWN0IHdoaWNoIGdvZXMgdG8gdGhlIG91dHB1dCB1c2luZyB0aGUgd2V0IGNvbnRyb2wuXG4gKi9cbmV4cG9ydCBjbGFzcyBFZmZlY3QgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVmZmVjdFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGRyeXdldCBrbm9iIHRvIGNvbnRyb2wgdGhlIGFtb3VudCBvZiBlZmZlY3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2RyeVdldCA9IG5ldyBDcm9zc0ZhZGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgd2V0IGNvbnRyb2wgaXMgaG93IG11Y2ggb2YgdGhlIGVmZmVjdGVkXG4gICAgICAgICAqIHdpbGwgcGFzcyB0aHJvdWdoIHRvIHRoZSBvdXRwdXQuIDEgPSAxMDAlIGVmZmVjdGVkXG4gICAgICAgICAqIHNpZ25hbCwgMCA9IDEwMCUgZHJ5IHNpZ25hbC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBjb25uZWN0IHRoZSBlZmZlY3RTZW5kIHRvIHRoZSBpbnB1dCBvZiBodGUgZWZmZWN0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiB0aGUgZWZmZWN0IHRvIHRoZSBlZmZlY3RSZXR1cm5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZWZmZWN0IGlucHV0IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlZmZlY3Qgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2RyeVdldDtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5mYW4odGhpcy5fZHJ5V2V0LmEsIHRoaXMuZWZmZWN0U2VuZCk7XG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmNvbm5lY3QodGhpcy5fZHJ5V2V0LmIpO1xuICAgICAgICB0aGlzLndldC5zZXRWYWx1ZUF0VGltZShvcHRpb25zLndldCwgMCk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5lZmZlY3RSZXR1cm4sIHRoaXMuZWZmZWN0U2VuZF07XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwid2V0XCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2V0OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhaW5zIHRoZSBlZmZlY3QgaW4gYmV0d2VlbiB0aGUgZWZmZWN0U2VuZCBhbmQgZWZmZWN0UmV0dXJuXG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdChlZmZlY3QpIHtcbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBpbnRlcm5hbCBjaGFubmVsc1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzLnB1c2goZWZmZWN0KTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKGVmZmVjdCwgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kcnlXZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVmZmVjdFJldHVybi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMud2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvRWZmZWN0XCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIExGTy1iYXNlZCBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgTEZPRWZmZWN0IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxGT0VmZmVjdFwiO1xuICAgICAgICB0aGlzLl9sZm8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBhbXBsaXR1ZGU6IG9wdGlvbnMuZGVwdGgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fbGZvLmFtcGxpdHVkZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAxLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICBkZXB0aDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBlZmZlY3QuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9sZm8uc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBsZm9cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBmaWx0ZXIgdG8gdGhlIHRyYW5zcG9ydC4gU2VlIFtbTEZPLnN5bmNdXVxuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmby5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm8udW5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgTEZPJ3Mgb3NjaWxsYXRvcjogU2VlIFtbT3NjaWxsYXRvci50eXBlXV1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKCkuc3RhcnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLnN0YXJ0KCkuY29ubmVjdChhdXRvRmlsdGVyKTtcbiAgICAgKiBhdXRvRmlsdGVyLnR5cGUgPSBcInNxdWFyZVwiO1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbGZvLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmby5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXB0aC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxGT0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPRWZmZWN0IH0gZnJvbSBcIi4vTEZPRWZmZWN0XCI7XG4vKipcbiAqIEF1dG9GaWx0ZXIgaXMgYSBUb25lLkZpbHRlciB3aXRoIGEgVG9uZS5MRk8gY29ubmVjdGVkIHRvIHRoZSBmaWx0ZXIgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAqIFNldHRpbmcgdGhlIExGTyByYXRlIGFuZCBkZXB0aCBhbGxvd3MgZm9yIGNvbnRyb2wgb3ZlciB0aGUgZmlsdGVyIG1vZHVsYXRpb24gcmF0ZVxuICogYW5kIGRlcHRoLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYW4gYXV0b2ZpbHRlciBhbmQgc3RhcnQgaXQncyBMRk9cbiAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKFwiNG5cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIGZpbHRlciBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhdXRvRmlsdGVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b0ZpbHRlciBleHRlbmRzIExGT0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9GaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9GaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9GaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiXSk7XG4gICAgICAgIHRoaXMuZmlsdGVyID0gbmV3IEZpbHRlcihPYmplY3QuYXNzaWduKG9wdGlvbnMuZmlsdGVyLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pKTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuZmlsdGVyKTtcbiAgICAgICAgdGhpcy5fbGZvLmNvbm5lY3QodGhpcy5maWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLmJhc2VGcmVxdWVuY3kgPSBvcHRpb25zLmJhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTEZPRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDIuNixcbiAgICAgICAgICAgIGZpbHRlcjoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICAgICAgICAgIHJvbGxvZmY6IC0xMixcbiAgICAgICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gdmFsdWUgb2YgdGhlIGZpbHRlcidzIGN1dG9mZiBmcmVxdWVuY3kuXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8ubWluO1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHRoaXMuX2xmby5taW4gPSB0aGlzLnRvRnJlcXVlbmN5KGZyZXEpO1xuICAgICAgICAvLyBhbmQgc2V0IHRoZSBtYXhcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gdmFsdWUgb2YgdGhlIGZpbHRlcidzIGN1dG9mZiBmcmVxdWVuY3kuXG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyhvY3QpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdDtcbiAgICAgICAgdGhpcy5fbGZvLm1heCA9IHRoaXMuX2xmby5taW4gKiBNYXRoLnBvdygyLCBvY3QpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXV0b0ZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQYW5uZXIgaXMgYW4gZXF1YWwgcG93ZXIgTGVmdC9SaWdodCBQYW5uZXIuIEl0IGlzIGEgd3JhcHBlciBhcm91bmQgdGhlIFN0ZXJlb1Bhbm5lck5vZGUuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiAvLyBtb3ZlIHRoZSBpbnB1dCBzaWduYWwgZnJvbSByaWdodCB0byBsZWZ0XG4gKiBcdGNvbnN0IHBhbm5lciA9IG5ldyBUb25lLlBhbm5lcigxKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdHBhbm5lci5wYW4ucmFtcFRvKC0xLCAwLjUpO1xuICogXHRjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDEwMCkuY29ubmVjdChwYW5uZXIpLnN0YXJ0KCk7XG4gKiB9LCAwLjUsIDIpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGFubmVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhbm5lclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHBhbm5lciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyKCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9wYW5uZXI7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fcGFubmVyO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCJdKTtcbiAgICAgICAgdGhpcy5wYW4gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wYW4sXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wYW4sXG4gICAgICAgICAgICBtaW5WYWx1ZTogLTEsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHRoaXMgaXMgbmVjZXNzYXJ5IGZvciBzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFxuICAgICAgICAvLyBkb2Vzbid0IG1ha2UgYW55IGRpZmZlcmVuY2UgZm9yIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9pc3N1ZXMvNjQ3XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnQgPSBvcHRpb25zLmNoYW5uZWxDb3VudDtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudE1vZGUgPSBcImV4cGxpY2l0XCI7XG4gICAgICAgIC8vIGluaXRpYWwgdmFsdWVcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJwYW5cIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwYW46IDAsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFubmVyLmpzLm1hcCIsImltcG9ydCB7IFBhbm5lciB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9QYW5uZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPRWZmZWN0IH0gZnJvbSBcIi4vTEZPRWZmZWN0XCI7XG4vKipcbiAqIEF1dG9QYW5uZXIgaXMgYSBbW1Bhbm5lcl1dIHdpdGggYW4gW1tMRk9dXSBjb25uZWN0ZWQgdG8gdGhlIHBhbiBhbW91bnQuXG4gKiBbUmVsYXRlZCBSZWFkaW5nXShodHRwczovL3d3dy5hYmxldG9uLmNvbS9lbi9ibG9nL2F1dG9wYW4tY2hvcHBlci1lZmZlY3QtYW5kLW1vcmUtbGl2ZXNjaG9vbC8pLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYW4gYXV0b3Bhbm5lciBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IGF1dG9QYW5uZXIgPSBuZXcgVG9uZS5BdXRvUGFubmVyKFwiNG5cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIHBhbm5lciBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChhdXRvUGFubmVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b1Bhbm5lciBleHRlbmRzIExGT0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9QYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBdXRvUGFubmVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gbmV3IFBhbm5lcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fcGFubmVyKTtcbiAgICAgICAgdGhpcy5fbGZvLmNvbm5lY3QodGhpcy5fcGFubmVyLnBhbik7XG4gICAgICAgIHRoaXMuX2xmby5taW4gPSAtMTtcbiAgICAgICAgdGhpcy5fbGZvLm1heCA9IDE7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTEZPRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdXRvUGFubmVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lUG9sZUZpbHRlciB9IGZyb20gXCIuLi9maWx0ZXIvT25lUG9sZUZpbHRlclwiO1xuaW1wb3J0IHsgQWJzIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BYnNcIjtcbi8qKlxuICogRm9sbG93ZXIgaXMgYSBzaW1wbGUgZW52ZWxvcGUgZm9sbG93ZXIuXG4gKiBJdCdzIGltcGxlbWVudGVkIGJ5IGFwcGx5aW5nIGEgbG93cGFzcyBmaWx0ZXIgdG8gdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBgYGBcbiAqICAgICAgICAgICstLS0tLSsgICAgKy0tLS0tLS0tLS0tLS0tLStcbiAqIElucHV0ICstLT4gQWJzICstLS0tPiBPbmVQb2xlRmlsdGVyICstLT4gT3V0cHV0XG4gKiAgICAgICAgICArLS0tLS0rICAgICstLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZvbGxvd2VyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZvbGxvd2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRm9sbG93ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZvbGxvd2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fYWJzID0gdGhpcy5pbnB1dCA9IG5ldyBBYnMoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MgPSB0aGlzLm91dHB1dCA9IG5ldyBPbmVQb2xlRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSAvIHRoaXMudG9TZWNvbmRzKG9wdGlvbnMuc21vb3RoaW5nKSxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hYnMuY29ubmVjdCh0aGlzLl9sb3dwYXNzKTtcbiAgICAgICAgdGhpcy5fc21vb3RoaW5nID0gb3B0aW9ucy5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuMDVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgdGltZSBpdCB0YWtlcyBhIHZhbHVlIGNoYW5nZSB0byBhcnJpdmUgYXQgdGhlIHVwZGF0ZWQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Ntb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyhzbW9vdGhpbmcpIHtcbiAgICAgICAgdGhpcy5fc21vb3RoaW5nID0gc21vb3RoaW5nO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeSA9IDEgLyB0aGlzLnRvU2Vjb25kcyh0aGlzLnNtb290aGluZyk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWJzLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93cGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZvbGxvd2VyLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBGb2xsb3dlciB9IGZyb20gXCIuLi9jb21wb25lbnQvYW5hbHlzaXMvRm9sbG93ZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgU2NhbGVFeHAgfSBmcm9tIFwiLi4vc2lnbmFsL1NjYWxlRXhwXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEF1dG9XYWggY29ubmVjdHMgYSBbW0ZvbGxvd2VyXV0gdG8gYSBbW0ZpbHRlcl1dLlxuICogVGhlIGZyZXF1ZW5jeSBvZiB0aGUgZmlsdGVyLCBmb2xsb3dzIHRoZSBpbnB1dCBhbXBsaXR1ZGUgY3VydmUuXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGF1dG9XYWggPSBuZXcgVG9uZS5BdXRvV2FoKDUwLCA2LCAtMzApLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIGluaXRpYWxpemUgdGhlIHN5bnRoIGFuZCBjb25uZWN0IHRvIGF1dG93YWhcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS5jb25uZWN0KGF1dG9XYWgpO1xuICogLy8gUSB2YWx1ZSBpbmZsdWVuY2VzIHRoZSBlZmZlY3Qgb2YgdGhlIHdhaCAtIGRlZmF1bHQgaXMgMlxuICogYXV0b1dhaC5RLnZhbHVlID0gNjtcbiAqIC8vIG1vcmUgYXVkaWJsZSBvbiBoaWdoZXIgbm90ZXNcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEF1dG9XYWggZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvV2FoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYmFzZUZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJzZW5zaXRpdml0eVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9XYWhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9XYWguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcInNlbnNpdGl2aXR5XCJdKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIgPSBuZXcgRm9sbG93ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiBvcHRpb25zLmZvbGxvd2VyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZSA9IG5ldyBTY2FsZUV4cCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBleHBvbmVudDogMC41LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5faW5wdXRCb29zdCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9iYW5kcGFzcyA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcm9sbG9mZjogLTQ4LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgUTogb3B0aW9ucy5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGVha2luZyA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJwZWFraW5nXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BlYWtpbmcuZ2Fpbi52YWx1ZSA9IG9wdGlvbnMuZ2FpbjtcbiAgICAgICAgdGhpcy5nYWluID0gdGhpcy5fcGVha2luZy5nYWluO1xuICAgICAgICB0aGlzLlEgPSB0aGlzLl9iYW5kcGFzcy5RO1xuICAgICAgICAvLyB0aGUgY29udHJvbCBzaWduYWwgcGF0aFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5faW5wdXRCb29zdCwgdGhpcy5fZm9sbG93ZXIsIHRoaXMuX3N3ZWVwUmFuZ2UpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmNvbm5lY3QodGhpcy5fYmFuZHBhc3MuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5jb25uZWN0KHRoaXMuX3BlYWtpbmcuZnJlcXVlbmN5KTtcbiAgICAgICAgLy8gdGhlIGZpbHRlcmVkIHBhdGhcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2JhbmRwYXNzLCB0aGlzLl9wZWFraW5nLCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG4gICAgICAgIHRoaXMuc2Vuc2l0aXZpdHkgPSBvcHRpb25zLnNlbnNpdGl2aXR5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJnYWluXCIsIFwiUVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDEwMCxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDYsXG4gICAgICAgICAgICBzZW5zaXRpdml0eTogMCxcbiAgICAgICAgICAgIFE6IDIsXG4gICAgICAgICAgICBnYWluOiAyLFxuICAgICAgICAgICAgZm9sbG93ZXI6IDAuMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyB0aGF0IHRoZSBmaWx0ZXIgd2lsbCBzd2VlcCBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX3NldFN3ZWVwUmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZvbGxvd2VyJ3Mgc21vb3RoaW5nIHRpbWVcbiAgICAgKi9cbiAgICBnZXQgZm9sbG93ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHNldCBmb2xsb3dlcihmb2xsb3dlcikge1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmcgPSBmb2xsb3dlcjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgZnJlcXVlbmN5IGZyb20gd2hpY2ggdGhlIHN3ZWVwIHdpbGwgc3RhcnQgZnJvbS5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KGJhc2VGcmVxKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KGJhc2VGcmVxKTtcbiAgICAgICAgdGhpcy5fc2V0U3dlZXBSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2Vuc2l0aXZpdHkgdG8gY29udHJvbCBob3cgcmVzcG9uc2l2ZSB0byB0aGUgaW5wdXQgc2lnbmFsIHRoZSBmaWx0ZXIgaXMuXG4gICAgICovXG4gICAgZ2V0IHNlbnNpdGl2aXR5KCkge1xuICAgICAgICByZXR1cm4gZ2FpblRvRGIoMSAvIHRoaXMuX2lucHV0Qm9vc3QuZ2Fpbi52YWx1ZSk7XG4gICAgfVxuICAgIHNldCBzZW5zaXRpdml0eShzZW5zaXRpdml0eSkge1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0LmdhaW4udmFsdWUgPSAxIC8gZGJUb0dhaW4oc2Vuc2l0aXZpdHkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXRzIHRoZSBzd2VlcCByYW5nZSBvZiB0aGUgc2NhbGVyXG4gICAgICovXG4gICAgX3NldFN3ZWVwUmFuZ2UoKSB7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5tYXggPSBNYXRoLm1pbih0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgdGhpcy5fb2N0YXZlcyksIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMik7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYmFuZHBhc3MuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wZWFraW5nLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5faW5wdXRCb29zdC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1dG9XYWguanMubWFwIiwiaW1wb3J0IFwiLi4vY29yZS93b3JrbGV0L1NpbmdsZUlPUHJvY2Vzc29yLndvcmtsZXRcIjtcbmltcG9ydCB7IHJlZ2lzdGVyUHJvY2Vzc29yIH0gZnJvbSBcIi4uL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCB3b3JrbGV0TmFtZSA9IFwiYml0LWNydXNoZXJcIjtcbmV4cG9ydCBjb25zdCBiaXRDcnVzaGVyV29ya2xldCA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHRjbGFzcyBCaXRDcnVzaGVyV29ya2xldCBleHRlbmRzIFNpbmdsZUlPUHJvY2Vzc29yIHtcblxuXHRcdHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7XG5cdFx0XHRyZXR1cm4gW3tcblx0XHRcdFx0bmFtZTogXCJiaXRzXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMTIsXG5cdFx0XHRcdG1pblZhbHVlOiAxLFxuXHRcdFx0XHRtYXhWYWx1ZTogMTYsXG5cdFx0XHRcdGF1dG9tYXRpb25SYXRlOiAnay1yYXRlJ1xuXHRcdFx0fV07XG5cdFx0fVxuXG5cdFx0Z2VuZXJhdGUoaW5wdXQsIF9jaGFubmVsLCBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRjb25zdCBzdGVwID0gTWF0aC5wb3coMC41LCBwYXJhbWV0ZXJzLmJpdHMgLSAxKTtcblx0XHRcdGNvbnN0IHZhbCA9IHN0ZXAgKiBNYXRoLmZsb29yKGlucHV0IC8gc3RlcCArIDAuNSk7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0fVxuYDtcbnJlZ2lzdGVyUHJvY2Vzc29yKHdvcmtsZXROYW1lLCBiaXRDcnVzaGVyV29ya2xldCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1CaXRDcnVzaGVyLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvV29ya2xldCB9IGZyb20gXCIuLi9jb3JlL3dvcmtsZXQvVG9uZUF1ZGlvV29ya2xldFwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgd29ya2xldE5hbWUgfSBmcm9tIFwiLi9CaXRDcnVzaGVyLndvcmtsZXRcIjtcbi8qKlxuICogQml0Q3J1c2hlciBkb3duLXNhbXBsZXMgdGhlIGluY29taW5nIHNpZ25hbCB0byBhIGRpZmZlcmVudCBiaXQgZGVwdGguXG4gKiBMb3dlcmluZyB0aGUgYml0IGRlcHRoIG9mIHRoZSBzaWduYWwgY3JlYXRlcyBkaXN0b3J0aW9uLiBSZWFkIG1vcmUgYWJvdXQgQml0Q3J1c2hpbmdcbiAqIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0JpdGNydXNoZXIpLlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemUgY3J1c2hlciBhbmQgcm91dGUgYSBzeW50aCB0aHJvdWdoIGl0XG4gKiBjb25zdCBjcnVzaGVyID0gbmV3IFRvbmUuQml0Q3J1c2hlcig0KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkuY29ubmVjdChjcnVzaGVyKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgMik7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQml0Q3J1c2hlciBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQml0Q3J1c2hlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJpdHNcIl0pO1xuICAgICAgICB0aGlzLl9iaXRDcnVzaGVyV29ya2xldCA9IG5ldyBCaXRDcnVzaGVyV29ya2xldCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBiaXRzOiBvcHRpb25zLmJpdHMsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9iaXRDcnVzaGVyV29ya2xldCk7XG4gICAgICAgIHRoaXMuYml0cyA9IHRoaXMuX2JpdENydXNoZXJXb3JrbGV0LmJpdHM7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJpdHM6IDQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2JpdENydXNoZXJXb3JrbGV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBJbnRlcm5hbCBjbGFzcyB3aGljaCBjcmVhdGVzIGFuIEF1ZGlvV29ya2xldCB0byBkbyB0aGUgYml0IGNydXNoaW5nXG4gKi9cbmNsYXNzIEJpdENydXNoZXJXb3JrbGV0IGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXJXb3JrbGV0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkJpdENydXNoZXJXb3JrbGV0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyV29ya2xldC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuYml0cyA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5iaXRzLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIG1pblZhbHVlOiAxLFxuICAgICAgICAgICAgbWF4VmFsdWU6IDE2LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb1dvcmtsZXQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYml0czogMTIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfYXVkaW9Xb3JrbGV0TmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHdvcmtsZXROYW1lO1xuICAgIH1cbiAgICBvblJlYWR5KG5vZGUpIHtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCBub2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbnN0IGJpdHMgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiYml0c1wiKTtcbiAgICAgICAgdGhpcy5iaXRzLnNldFBhcmFtKGJpdHMpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYml0cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpdENydXNoZXIuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi4vc2lnbmFsL1dhdmVTaGFwZXJcIjtcbi8qKlxuICogQ2hlYnlzaGV2IGlzIGEgd2F2ZXNoYXBlciB3aGljaCBpcyBnb29kXG4gKiBmb3IgbWFraW5nIGRpZmZlcmVudCB0eXBlcyBvZiBkaXN0b3J0aW9uIHNvdW5kcy5cbiAqIE5vdGUgdGhhdCBvZGQgb3JkZXJzIHNvdW5kIHZlcnkgZGlmZmVyZW50IGZyb20gZXZlbiBvbmVzLFxuICogYW5kIG9yZGVyID0gMSBpcyBubyBjaGFuZ2UuXG4gKiBSZWFkIG1vcmUgYXQgW211c2ljLmNvbHVtYmlhLmVkdV0oaHR0cDovL211c2ljLmNvbHVtYmlhLmVkdS9jbWMvbXVzaWNhbmRjb21wdXRlcnMvY2hhcHRlcjQvMDRfMDYucGhwKS5cbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYSBuZXcgY2hlYnlcbiAqIGNvbnN0IGNoZWJ5ID0gbmV3IFRvbmUuQ2hlYnlzaGV2KDUwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBjcmVhdGUgYSBtb25vc3ludGggY29ubmVjdGVkIHRvIG91ciBjaGVieVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Nb25vU3ludGgoKS5jb25uZWN0KGNoZWJ5KTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgMC40KTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIENoZWJ5c2hldiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENoZWJ5c2hldi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9yZGVyXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hlYnlzaGV2XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGVieXNoZXYuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvcmRlclwiXSk7XG4gICAgICAgIHRoaXMuX3NoYXBlciA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxlbmd0aDogNDA5NlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fb3JkZXIgPSBvcHRpb25zLm9yZGVyO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fc2hhcGVyKTtcbiAgICAgICAgdGhpcy5vcmRlciA9IG9wdGlvbnMub3JkZXI7XG4gICAgICAgIHRoaXMub3ZlcnNhbXBsZSA9IG9wdGlvbnMub3ZlcnNhbXBsZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgb3JkZXI6IDEsXG4gICAgICAgICAgICBvdmVyc2FtcGxlOiBcIm5vbmVcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZ2V0IHRoZSBjb2VmZmljaWVudCBmb3IgdGhhdCBkZWdyZWVcbiAgICAgKiBAcGFyYW0gIHggdGhlIHggdmFsdWVcbiAgICAgKiBAcGFyYW0gIGRlZ3JlZVxuICAgICAqIEBwYXJhbSAgbWVtbyBtZW1vaXplIHRoZSBjb21wdXRlZCB2YWx1ZS4gdGhpcyBzcGVlZHMgdXAgY29tcHV0YXRpb24gZ3JlYXRseS5cbiAgICAgKi9cbiAgICBfZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlLCBtZW1vKSB7XG4gICAgICAgIGlmIChtZW1vLmhhcyhkZWdyZWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbWVtby5nZXQoZGVncmVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZWdyZWUgPT09IDApIHtcbiAgICAgICAgICAgIG1lbW8uc2V0KGRlZ3JlZSwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGVncmVlID09PSAxKSB7XG4gICAgICAgICAgICBtZW1vLnNldChkZWdyZWUsIHgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbWVtby5zZXQoZGVncmVlLCAyICogeCAqIHRoaXMuX2dldENvZWZmaWNpZW50KHgsIGRlZ3JlZSAtIDEsIG1lbW8pIC0gdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlIC0gMiwgbWVtbykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZW1vLmdldChkZWdyZWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3JkZXIgb2YgdGhlIENoZWJ5c2hldiBwb2x5bm9taWFsIHdoaWNoIGNyZWF0ZXMgdGhlIGVxdWF0aW9uIHdoaWNoIGlzIGFwcGxpZWQgdG8gdGhlIGluY29taW5nXG4gICAgICogc2lnbmFsIHRocm91Z2ggYSBUb25lLldhdmVTaGFwZXIuIFRoZSBlcXVhdGlvbnMgYXJlIGluIHRoZSBmb3JtOlxuICAgICAqIGBgYFxuICAgICAqIG9yZGVyIDI6IDJ4XjIgKyAxXG4gICAgICogb3JkZXIgMzogNHheMyArIDN4XG4gICAgICogYGBgXG4gICAgICogQG1pbiAxXG4gICAgICogQG1heCAxMDBcbiAgICAgKi9cbiAgICBnZXQgb3JkZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vcmRlcjtcbiAgICB9XG4gICAgc2V0IG9yZGVyKG9yZGVyKSB7XG4gICAgICAgIHRoaXMuX29yZGVyID0gb3JkZXI7XG4gICAgICAgIHRoaXMuX3NoYXBlci5zZXRNYXAoKHggPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldENvZWZmaWNpZW50KHgsIG9yZGVyLCBuZXcgTWFwKCkpO1xuICAgICAgICB9KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvdmVyc2FtcGxpbmcgb2YgdGhlIGVmZmVjdC4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzZXQgb3ZlcnNhbXBsZShvdmVyc2FtcGxpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2hlYnlzaGV2LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBTcGxpdCBzcGxpdHMgYW4gaW5jb21pbmcgc2lnbmFsIGludG8gdGhlIG51bWJlciBvZiBnaXZlbiBjaGFubmVscy5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3BsaXQgPSBuZXcgVG9uZS5TcGxpdCgpO1xuICogLy8gc3RlcmVvU2lnbmFsLmNvbm5lY3Qoc3BsaXQpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgU3BsaXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNwbGl0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG9wdGlvbnMuY2hhbm5lbHMpO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuX3NwbGl0dGVyXTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNwbGl0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBNZXJnZSBicmluZ3MgbXVsdGlwbGUgbW9ubyBpbnB1dCBjaGFubmVscyBpbnRvIGEgc2luZ2xlIG11bHRpY2hhbm5lbCBvdXRwdXQgY2hhbm5lbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWVyZ2UgPSBuZXcgVG9uZS5NZXJnZSgpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHJvdXRpbmcgYSBzaW5lIHRvbmUgaW4gdGhlIGxlZnQgY2hhbm5lbFxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QobWVyZ2UsIDAsIDApLnN0YXJ0KCk7XG4gKiAvLyBhbmQgbm9pc2UgaW4gdGhlIHJpZ2h0IGNoYW5uZWxcbiAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS5jb25uZWN0KG1lcmdlLCAwLCAxKS5zdGFydCgpOztcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1lcmdlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1lcmdlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZXJnZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSk7XG4gICAgICAgIHRoaXMuX21lcmdlciA9IHRoaXMub3V0cHV0ID0gdGhpcy5pbnB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsTWVyZ2VyKG9wdGlvbnMuY2hhbm5lbHMpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21lcmdlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1lcmdlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QsIGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1NwbGl0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NZXJnZVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBTdGVyZW8gZWZmZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0ZXJlb0VmZmVjdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3RlcmVvRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gZm9yY2UgbW9ubyBzb3VyY2VzIHRvIGJlIHN0ZXJlb1xuICAgICAgICB0aGlzLmlucHV0LmNoYW5uZWxDb3VudCA9IDI7XG4gICAgICAgIHRoaXMuaW5wdXQuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgdGhpcy5fZHJ5V2V0ID0gdGhpcy5vdXRwdXQgPSBuZXcgQ3Jvc3NGYWRlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZhZGU6IG9wdGlvbnMud2V0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLndldCA9IHRoaXMuX2RyeVdldC5mYWRlO1xuICAgICAgICB0aGlzLl9zcGxpdCA9IG5ldyBTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlID0gbmV3IE1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgLy8gZHJ5IHdldCBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fZHJ5V2V0LmEpO1xuICAgICAgICB0aGlzLl9tZXJnZS5jb25uZWN0KHRoaXMuX2RyeVdldC5iKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wid2V0XCJdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgbGVmdCBwYXJ0IG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0TGVmdCguLi5ub2Rlcykge1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KG5vZGVzWzBdLCAwLCAwKTtcbiAgICAgICAgY29ubmVjdFNlcmllcyguLi5ub2Rlcyk7XG4gICAgICAgIGNvbm5lY3Qobm9kZXNbbm9kZXMubGVuZ3RoIC0gMV0sIHRoaXMuX21lcmdlLCAwLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgcmlnaHQgcGFydCBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdFJpZ2h0KC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3Qobm9kZXNbMF0sIDEsIDApO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLm5vZGVzKTtcbiAgICAgICAgY29ubmVjdChub2Rlc1tub2Rlcy5sZW5ndGggLSAxXSwgdGhpcy5fbWVyZ2UsIDAsIDEpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2V0OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kcnlXZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1NwbGl0XCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NZXJnZVwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBzdGVyZW8gZmVlZGJhY2sgZWZmZWN0cyB3aGVyZSB0aGUgZWZmZWN0UmV0dXJuIGlzIGZlZCBiYWNrIGludG8gdGhlIHNhbWUgY2hhbm5lbC5cbiAqL1xuZXhwb3J0IGNsYXNzIFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLmZlZWRiYWNrID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mZWVkYmFjayxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdCA9IG5ldyBTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICB0aGlzLl9tZXJnZS5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrU3BsaXQpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja01lcmdlLmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICAvLyB0aGUgbGVmdCBvdXRwdXQgY29ubmVjdGVkIHRvIHRoZSBsZWZ0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrU3BsaXQuY29ubmVjdCh0aGlzLl9mZWVkYmFja0wsIDAsIDApO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAwKTtcbiAgICAgICAgLy8gdGhlIHJpZ2h0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrU3BsaXQuY29ubmVjdCh0aGlzLl9mZWVkYmFja1IsIDEsIDApO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAxKTtcbiAgICAgICAgLy8gdGhlIGZlZWRiYWNrIGNvbnRyb2xcbiAgICAgICAgdGhpcy5mZWVkYmFjay5mYW4odGhpcy5fZmVlZGJhY2tMLmdhaW4sIHRoaXMuX2ZlZWRiYWNrUi5nYWluKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZmVlZGJhY2tcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmZWVkYmFjazogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZlZWRiYWNrLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9GZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9GZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvU3RlcmVvRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENob3J1cyBpcyBhIHN0ZXJlbyBjaG9ydXMgZWZmZWN0IGNvbXBvc2VkIG9mIGEgbGVmdCBhbmQgcmlnaHQgZGVsYXkgd2l0aCBhbiBbW0xGT11dIGFwcGxpZWQgdG8gdGhlIGRlbGF5VGltZSBvZiBlYWNoIGNoYW5uZWwuXG4gKiBXaGVuIFtbZmVlZGJhY2tdXSBpcyBzZXQgdG8gYSB2YWx1ZSBsYXJnZXIgdGhhbiAwLCB5b3UgYWxzbyBnZXQgRmxhbmdlci10eXBlIGVmZmVjdHMuXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYS9ibG9iL21hc3Rlci90dW5hLmpzKS5cbiAqIFJlYWQgbW9yZSBvbiB0aGUgY2hvcnVzIGVmZmVjdCBvbiBbU291bmRPblNvdW5kXShodHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb20vc29zL2p1bjA0L2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjaG9ydXMgPSBuZXcgVG9uZS5DaG9ydXMoNCwgMi41LCAwLjUpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS5jb25uZWN0KGNob3J1cyk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDM1wiLCBcIkUzXCIsIFwiRzNcIl0sIFwiOG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQ2hvcnVzIGV4dGVuZHMgU3RlcmVvRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDaG9ydXMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZWxheVRpbWVcIiwgXCJkZXB0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNob3J1c1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hvcnVzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVsYXlUaW1lXCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLl9kZXB0aCA9IG9wdGlvbnMuZGVwdGg7XG4gICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IG9wdGlvbnMuZGVsYXlUaW1lIC8gMTAwMDtcbiAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBwaGFzZTogMTgwXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVMID0gbmV3IERlbGF5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVSID0gbmV3IERlbGF5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmb0wuZnJlcXVlbmN5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICAvLyBoYXZlIG9uZSBMRk8gZnJlcXVlbmN5IGNvbnRyb2wgdGhlIG90aGVyXG4gICAgICAgIHRoaXMuX2xmb0wuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KHRoaXMuX2RlbGF5Tm9kZUwpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCh0aGlzLl9kZWxheU5vZGVSKTtcbiAgICAgICAgLy8gbGZvIHNldHVwXG4gICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9kZWxheU5vZGVMLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1IuY29ubmVjdCh0aGlzLl9kZWxheU5vZGVSLmRlbGF5VGltZSk7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZXNcbiAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2RlcHRoO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAxLjUsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDMuNSxcbiAgICAgICAgICAgIGRlcHRoOiAwLjcsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIHNwcmVhZDogMTgwLFxuICAgICAgICAgICAgZmVlZGJhY2s6IDAsXG4gICAgICAgICAgICB3ZXQ6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZXB0aCBvZiB0aGUgZWZmZWN0LiBBIGRlcHRoIG9mIDEgbWFrZXMgdGhlIGRlbGF5VGltZVxuICAgICAqIG1vZHVsYXRlIGJldHdlZW4gMCBhbmQgMipkZWxheVRpbWUgKGNlbnRlcmVkIGFyb3VuZCB0aGUgZGVsYXlUaW1lKS5cbiAgICAgKi9cbiAgICBnZXQgZGVwdGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZXB0aDtcbiAgICB9XG4gICAgc2V0IGRlcHRoKGRlcHRoKSB7XG4gICAgICAgIHRoaXMuX2RlcHRoID0gZGVwdGg7XG4gICAgICAgIGNvbnN0IGRldmlhdGlvbiA9IHRoaXMuX2RlbGF5VGltZSAqIGRlcHRoO1xuICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IE1hdGgubWF4KHRoaXMuX2RlbGF5VGltZSAtIGRldmlhdGlvbiwgMCk7XG4gICAgICAgIHRoaXMuX2xmb0wubWF4ID0gdGhpcy5fZGVsYXlUaW1lICsgZGV2aWF0aW9uO1xuICAgICAgICB0aGlzLl9sZm9SLm1pbiA9IE1hdGgubWF4KHRoaXMuX2RlbGF5VGltZSAtIGRldmlhdGlvbiwgMCk7XG4gICAgICAgIHRoaXMuX2xmb1IubWF4ID0gdGhpcy5fZGVsYXlUaW1lICsgZGV2aWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGVsYXlUaW1lIGluIG1pbGxpc2Vjb25kcyBvZiB0aGUgY2hvcnVzLiBBIGxhcmdlciBkZWxheVRpbWVcbiAgICAgKiB3aWxsIGdpdmUgYSBtb3JlIHByb25vdW5jZWQgZWZmZWN0LiBOb21pbmFsIHJhbmdlIGEgZGVsYXlUaW1lXG4gICAgICogaXMgYmV0d2VlbiAyIGFuZCAyMG1zLlxuICAgICAqL1xuICAgIGdldCBkZWxheVRpbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWxheVRpbWUgKiAxMDAwO1xuICAgIH1cbiAgICBzZXQgZGVsYXlUaW1lKGRlbGF5VGltZSkge1xuICAgICAgICB0aGlzLl9kZWxheVRpbWUgPSBkZWxheVRpbWUgLyAxMDAwO1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fZGVwdGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yIHR5cGUgb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmb0wudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9sZm9SLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbW91bnQgb2Ygc3RlcmVvIHNwcmVhZC4gV2hlbiBzZXQgdG8gMCwgYm90aCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBjZW50cmFsbHkuXG4gICAgICogV2hlbiBzZXQgdG8gMTgwLCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBoYXJkIGxlZnQgYW5kIHJpZ2h0IHJlc3BlY3RpdmVseS5cbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvUi5waGFzZSAtIHRoaXMuX2xmb0wucGhhc2U7XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX2xmb0wucGhhc2UgPSA5MCAtIChzcHJlYWQgLyAyKTtcbiAgICAgICAgdGhpcy5fbGZvUi5waGFzZSA9IChzcHJlYWQgLyAyKSArIDkwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgZWZmZWN0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxmb1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGZpbHRlciB0byB0aGUgdHJhbnNwb3J0LiBTZWUgW1tMRk8uc3luY11dXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBmaWx0ZXIgZnJvbSB0aGUgdHJhbnNwb3J0LlxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi51bnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVMLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2hvcnVzLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuLi9zaWduYWwvV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG4vKipcbiAqIEEgc2ltcGxlIGRpc3RvcnRpb24gZWZmZWN0IHVzaW5nIFRvbmUuV2F2ZVNoYXBlci5cbiAqIEFsZ29yaXRobSBmcm9tIFt0aGlzIHN0YWNrb3ZlcmZsb3cgYW5zd2VyXShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMjMxMzQwOCkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGRpc3QgPSBuZXcgVG9uZS5EaXN0b3J0aW9uKDAuOCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgZm0gPSBuZXcgVG9uZS5GTVN5bnRoKCkuY29ubmVjdChkaXN0KTtcbiAqIGZtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTFcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIERpc3RvcnRpb24gZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEaXN0b3J0aW9uLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGlzdG9ydGlvblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRpc3RvcnRpb25cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERpc3RvcnRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkaXN0b3J0aW9uXCJdKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbGVuZ3RoOiA0MDk2LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZGlzdG9ydGlvbiA9IG9wdGlvbnMuZGlzdG9ydGlvbjtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX3NoYXBlcik7XG4gICAgICAgIHRoaXMuZGlzdG9ydGlvbiA9IG9wdGlvbnMuZGlzdG9ydGlvbjtcbiAgICAgICAgdGhpcy5vdmVyc2FtcGxlID0gb3B0aW9ucy5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkaXN0b3J0aW9uOiAwLjQsXG4gICAgICAgICAgICBvdmVyc2FtcGxlOiBcIm5vbmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgZGlzdG9ydGlvbi4gTm9taW5hbCByYW5nZSBpcyBiZXR3ZWVuIDAgYW5kIDEuXG4gICAgICovXG4gICAgZ2V0IGRpc3RvcnRpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXN0b3J0aW9uO1xuICAgIH1cbiAgICBzZXQgZGlzdG9ydGlvbihhbW91bnQpIHtcbiAgICAgICAgdGhpcy5fZGlzdG9ydGlvbiA9IGFtb3VudDtcbiAgICAgICAgY29uc3QgayA9IGFtb3VudCAqIDEwMDtcbiAgICAgICAgY29uc3QgZGVnID0gTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgdGhpcy5fc2hhcGVyLnNldE1hcCgoeCkgPT4ge1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKHgpIDwgMC4wMDEpIHtcbiAgICAgICAgICAgICAgICAvLyBzaG91bGQgb3V0cHV0IDAgd2hlbiBpbnB1dCBpcyAwXG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKDMgKyBrKSAqIHggKiAyMCAqIGRlZyAvIChNYXRoLlBJICsgayAqIE1hdGguYWJzKHgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvdmVyc2FtcGxpbmcgb2YgdGhlIGVmZmVjdC4gQ2FuIGVpdGhlciBiZSBcIm5vbmVcIiwgXCIyeFwiIG9yIFwiNHhcIi5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzZXQgb3ZlcnNhbXBsZShvdmVyc2FtcGxpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGUgPSBvdmVyc2FtcGxpbmc7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGlzdG9ydGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbi8qKlxuICogRmVlZGJhY2tFZmZlY3QgcHJvdmlkZXMgYSBsb29wIGJldHdlZW4gYW4gYXVkaW8gc291cmNlIGFuZCBpdHMgb3duIG91dHB1dC5cbiAqIFRoaXMgaXMgYSBiYXNlLWNsYXNzIGZvciBmZWVkYmFjayBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmVlZGJhY2tFZmZlY3RcIjtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5mZWVkYmFjayxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZlZWRiYWNrID0gdGhpcy5fZmVlZGJhY2tHYWluLmdhaW47XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZmVlZGJhY2tcIik7XG4gICAgICAgIC8vIHRoZSBmZWVkYmFjayBsb29wXG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmNoYWluKHRoaXMuX2ZlZWRiYWNrR2FpbiwgdGhpcy5lZmZlY3RTZW5kKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmVlZGJhY2s6IDAuMTI1LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0dhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZlZWRiYWNrLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tFZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4vRmVlZGJhY2tFZmZlY3RcIjtcbi8qKlxuICogRmVlZGJhY2tEZWxheSBpcyBhIERlbGF5Tm9kZSBpbiB3aGljaCBwYXJ0IG9mIG91dHB1dCBzaWduYWwgaXMgZmVkIGJhY2sgaW50byB0aGUgZGVsYXkuXG4gKlxuICogQHBhcmFtIGRlbGF5VGltZSBUaGUgZGVsYXkgYXBwbGllZCB0byB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICogQHBhcmFtIGZlZWRiYWNrIFRoZSBhbW91bnQgb2YgdGhlIGVmZmVjdGVkIHNpZ25hbCB3aGljaCBpcyBmZWQgYmFjayB0aHJvdWdoIHRoZSBkZWxheS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmZWVkYmFja0RlbGF5ID0gbmV3IFRvbmUuRmVlZGJhY2tEZWxheShcIjhuXCIsIDAuNSkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgdG9tID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCh7XG4gKiBcdG9jdGF2ZXM6IDQsXG4gKiBcdHBpdGNoRGVjYXk6IDAuMVxuICogfSkuY29ubmVjdChmZWVkYmFja0RlbGF5KTtcbiAqIHRvbS50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkEyXCIsIFwiMzJuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tEZWxheSBleHRlbmRzIEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmVlZGJhY2tEZWxheVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gdGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZTtcbiAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fZGVsYXlOb2RlKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZWxheVRpbWVcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjI1LFxuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tEZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIFBoYXNlU2hpZnRBbGxwYXNzIGlzIGFuIHZlcnkgZWZmaWNpZW50IGltcGxlbWVudGF0aW9uIG9mIGEgSGlsYmVydCBUcmFuc2Zvcm1cbiAqIHVzaW5nIHR3byBBbGxwYXNzIGZpbHRlciBiYW5rcyB3aG9zZSBvdXRwdXRzIGhhdmUgYSBwaGFzZSBkaWZmZXJlbmNlIG9mIDkwwrAuXG4gKiBIZXJlIHRoZSBgb2Zmc2V0OTBgIHBoYXNlIGlzIG9mZnNldCBieSArOTDCsCBpbiByZWxhdGlvbiB0byBgb3V0cHV0YC5cbiAqIENvZWZmaWNpZW50cyBhbmQgc3RydWN0dXJlIHdhcyBkZXZlbG9wZWQgYnkgT2xsaSBOaWVtaXRhbG8uXG4gKiBGb3IgbW9yZSBkZXRhaWxzIHNlZTogaHR0cDovL3llaGFyLmNvbS9ibG9nLz9wPTM2OFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGhhc2VTaGlmdEFsbHBhc3MgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBoYXNlU2hpZnRBbGxwYXNzXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwaGFzZSBzaGlmdGVkIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBQaGFzZVNoaWZ0ZWQgYWxscGFzcyBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub2Zmc2V0OTAgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgY29uc3QgYWxscGFzc0JhbmsxVmFsdWVzID0gWzAuNjkyMzg3OCwgMC45MzYwNjU0MzIyOTU5LCAwLjk4ODIyOTUyMjY4NjAsIDAuOTk4NzQ4ODQ1MjczN107XG4gICAgICAgIGNvbnN0IGFsbHBhc3NCYW5rMlZhbHVlcyA9IFswLjQwMjE5MjExNjI0MjYsIDAuODU2MTcxMDg4MjQyMCwgMC45NzIyOTA5NTQ1NjUxLCAwLjk5NTI4ODQ3OTEyNzhdO1xuICAgICAgICB0aGlzLl9iYW5rMCA9IHRoaXMuX2NyZWF0ZUFsbFBhc3NGaWx0ZXJCYW5rKGFsbHBhc3NCYW5rMVZhbHVlcyk7XG4gICAgICAgIHRoaXMuX2JhbmsxID0gdGhpcy5fY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYWxscGFzc0JhbmsyVmFsdWVzKTtcbiAgICAgICAgdGhpcy5fb25lU2FtcGxlRGVsYXkgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFswLjAsIDEuMF0sIFsxLjAsIDAuMF0pO1xuICAgICAgICAvLyBjb25uZWN0IEFsbHBhc3MgZmlsdGVyIGJhbmtzXG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgLi4udGhpcy5fYmFuazAsIHRoaXMuX29uZVNhbXBsZURlbGF5LCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgLi4udGhpcy5fYmFuazEsIHRoaXMub2Zmc2V0OTApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYWxsIG9mIHRoZSBJSVIgZmlsdGVycyBmcm9tIGFuIGFycmF5IG9mIHZhbHVlcyB1c2luZyB0aGUgY29lZmZpY2llbnQgY2FsY3VsYXRpb24uXG4gICAgICovXG4gICAgX2NyZWF0ZUFsbFBhc3NGaWx0ZXJCYW5rKGJhbmtWYWx1ZXMpIHtcbiAgICAgICAgY29uc3Qgbm9kZXMgPSBiYW5rVmFsdWVzLm1hcCh2YWx1ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb2VmZmljaWVudHMgPSBbW3ZhbHVlICogdmFsdWUsIDAsIC0xXSwgWzEsIDAsIC0odmFsdWUgKiB2YWx1ZSldXTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKGNvZWZmaWNpZW50c1swXSwgY29lZmZpY2llbnRzWzFdKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9mZnNldDkwLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYmFuazAuZm9yRWFjaChmID0+IGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fYmFuazEuZm9yRWFjaChmID0+IGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fb25lU2FtcGxlRGVsYXkuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QaGFzZVNoaWZ0QWxscGFzcy5qcy5tYXAiLCJpbXBvcnQgeyBQaGFzZVNoaWZ0QWxscGFzcyB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL1BoYXNlU2hpZnRBbGxwYXNzXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvRWZmZWN0XCI7XG5pbXBvcnQgeyBBZGQgfSBmcm9tIFwiLi4vc2lnbmFsL0FkZFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBOZWdhdGUgfSBmcm9tIFwiLi4vc2lnbmFsL05lZ2F0ZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgVG9uZU9zY2lsbGF0b3JOb2RlIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL1RvbmVPc2NpbGxhdG9yTm9kZVwiO1xuLyoqXG4gKiBGcmVxdWVuY3lTaGlmdGVyIGNhbiBiZSB1c2VkIHRvIHNoaWZ0IGFsbCBmcmVxdWVuY2llcyBvZiBhIHNpZ25hbCBieSBhIGZpeGVkIGFtb3VudC5cbiAqIFRoZSBhbW91bnQgY2FuIGJlIGNoYW5nZWQgYXQgYXVkaW8gcmF0ZSBhbmQgdGhlIGVmZmVjdCBpcyBhcHBsaWVkIGluIHJlYWwgdGltZS5cbiAqIFRoZSBmcmVxdWVuY3kgc2hpZnRpbmcgaXMgaW1wbGVtZW50ZWQgd2l0aCBhIHRlY2huaXF1ZSBjYWxsZWQgc2luZ2xlIHNpZGUgYmFuZCBtb2R1bGF0aW9uIHVzaW5nIGEgcmluZyBtb2R1bGF0b3IuXG4gKiBOb3RlOiBDb250cmFyeSB0byBwaXRjaCBzaGlmdGluZywgYWxsIGZyZXF1ZW5jaWVzIGFyZSBzaGlmdGVkIGJ5IHRoZSBzYW1lIGFtb3VudCxcbiAqIGRlc3Ryb3lpbmcgdGhlIGhhcm1vbmljIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZW0uIFRoaXMgbGVhZHMgdG8gdGhlIGNsYXNzaWMgcmluZyBtb2R1bGF0b3IgdGltYnJlIGRpc3RvcnRpb24uXG4gKiBUaGUgYWxnb3JpdGhtIHdpbGwgcHJvZHVjZXMgc29tZSBhbGlhc2luZyB0b3dhcmRzIHRoZSBoaWdoIGVuZCwgZXNwZWNpYWxseSBpZiB5b3VyIHNvdXJjZSBtYXRlcmlhbFxuICogY29udGFpbnMgYSBsb3Qgb2YgaGlnaCBmcmVxdWVuY2llcy4gVW5mb3J0dW5hdGVsbHkgdGhlIHdlYmF1ZGlvIEFQSSBkb2VzIG5vdCBzdXBwb3J0IHJlc2FtcGxpbmdcbiAqIGJ1ZmZlcnMgaW4gcmVhbCB0aW1lLCBzbyBpdCBpcyBub3QgcG9zc2libGUgdG8gZml4IGl0IHByb3Blcmx5LiBEZXBlbmRpbmcgb24gdGhlIHVzZSBjYXNlIGl0IG1pZ2h0XG4gKiBiZSBhbiBvcHRpb24gdG8gbG93IHBhc3MgZmlsdGVyIHlvdXIgaW5wdXQgYmVmb3JlIGZyZXF1ZW5jeSBzaGlmdGluZyBpdCB0byBnZXQgcmlkZSBvZiB0aGUgYWxpYXNpbmcuXG4gKiBZb3UgY2FuIGZpbmQgYSB2ZXJ5IGRldGFpbGVkIGRlc2NyaXB0aW9uIG9mIHRoZSBhbGdvcml0aG0gaGVyZTogaHR0cHM6Ly9sYXJ6ZWl0bGluLmdpdGh1Yi5pby9STUZTL1xuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBpbnB1dCA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMjMwLCBcInNhd3Rvb3RoXCIpLnN0YXJ0KCk7XG4gKiBjb25zdCBzaGlmdCA9IG5ldyBUb25lLkZyZXF1ZW5jeVNoaWZ0ZXIoNDIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGlucHV0LmNvbm5lY3Qoc2hpZnQpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRnJlcXVlbmN5U2hpZnRlciBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeVNoaWZ0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lTaGlmdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lTaGlmdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluVmFsdWU6IC10aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2luZSA9IG5ldyBUb25lT3NjaWxsYXRvck5vZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jb3NpbmUgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwaGFzZTogLTkwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaW5lTXVsdGlwbHkgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9uZWdhdGUgPSBuZXcgTmVnYXRlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hZGQgPSBuZXcgQWRkKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIgPSBuZXcgUGhhc2VTaGlmdEFsbHBhc3MoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jb25uZWN0KHRoaXMuX3BoYXNlU2hpZnRlcik7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGNhcnJpZXIgZnJlcXVlbmN5IHNpZ25hbCB0byB0aGUgdHdvIG9zY2lsbGF0b3JzXG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmZhbih0aGlzLl9zaW5lLmZyZXF1ZW5jeSwgdGhpcy5fY29zaW5lLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlci5vZmZzZXQ5MC5jb25uZWN0KHRoaXMuX2Nvc2luZU11bHRpcGx5KTtcbiAgICAgICAgdGhpcy5fY29zaW5lLmNvbm5lY3QodGhpcy5fY29zaW5lTXVsdGlwbHkuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLmNvbm5lY3QodGhpcy5fc2luZU11bHRpcGx5KTtcbiAgICAgICAgdGhpcy5fc2luZS5jb25uZWN0KHRoaXMuX3NpbmVNdWx0aXBseS5mYWN0b3IpO1xuICAgICAgICB0aGlzLl9zaW5lTXVsdGlwbHkuY29ubmVjdCh0aGlzLl9uZWdhdGUpO1xuICAgICAgICB0aGlzLl9jb3NpbmVNdWx0aXBseS5jb25uZWN0KHRoaXMuX2FkZCk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZS5jb25uZWN0KHRoaXMuX2FkZC5hZGRlbmQpO1xuICAgICAgICB0aGlzLl9hZGQuY29ubmVjdCh0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBvc2NpbGxhdG9ycyBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMuaW1tZWRpYXRlKCk7XG4gICAgICAgIHRoaXMuX3NpbmUuc3RhcnQobm93KTtcbiAgICAgICAgdGhpcy5fY29zaW5lLnN0YXJ0KG5vdyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hZGQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb3NpbmVNdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaW5lTXVsdGlwbHkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3lTaGlmdGVyLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTG93cGFzc0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlclwiO1xuLyoqXG4gKiBBbiBhcnJheSBvZiBjb21iIGZpbHRlciBkZWxheSB2YWx1ZXMgZnJvbSBGcmVldmVyYiBpbXBsZW1lbnRhdGlvblxuICovXG5jb25zdCBjb21iRmlsdGVyVHVuaW5ncyA9IFsxNTU3IC8gNDQxMDAsIDE2MTcgLyA0NDEwMCwgMTQ5MSAvIDQ0MTAwLCAxNDIyIC8gNDQxMDAsIDEyNzcgLyA0NDEwMCwgMTM1NiAvIDQ0MTAwLCAxMTg4IC8gNDQxMDAsIDExMTYgLyA0NDEwMF07XG4vKipcbiAqIEFuIGFycmF5IG9mIGFsbHBhc3MgZmlsdGVyIGZyZXF1ZW5jeSB2YWx1ZXMgZnJvbSBGcmVldmVyYiBpbXBsZW1lbnRhdGlvblxuICovXG5jb25zdCBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXMgPSBbMjI1LCA1NTYsIDQ0MSwgMzQxXTtcbi8qKlxuICogRnJlZXZlcmIgaXMgYSByZXZlcmIgYmFzZWQgb24gW0ZyZWV2ZXJiXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvRnJlZXZlcmIuaHRtbCkuXG4gKiBSZWFkIG1vcmUgb24gcmV2ZXJiIG9uIFtTb3VuZCBPbiBTb3VuZF0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDA0MDgzOTAyL2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbTo4MC9zb3MvZmViMDEvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmFzcCkuXG4gKiBGcmVldmVyYiBpcyBub3cgaW1wbGVtZW50ZWQgd2l0aCBhbiBBdWRpb1dvcmtsZXROb2RlIHdoaWNoIG1heSByZXN1bHQgb24gcGVyZm9ybWFuY2UgZGVncmFkYXRpb24gb24gc29tZSBwbGF0Zm9ybXMuIENvbnNpZGVyIHVzaW5nIFtbUmV2ZXJiXV0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZnJlZXZlcmIgPSBuZXcgVG9uZS5GcmVldmVyYigpLnRvRGVzdGluYXRpb24oKTtcbiAqIGZyZWV2ZXJiLmRhbXBlbmluZyA9IDEwMDA7XG4gKiAvLyByb3V0aW5nIHN5bnRoIHRocm91Z2ggdGhlIHJldmVyYlxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Ob2lzZVN5bnRoKCkuY29ubmVjdChmcmVldmVyYik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZSgwLjA1KTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZWV2ZXJiIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiLCBcImRhbXBlbmluZ1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZWV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgY29tYiBmaWx0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGFsbHBhc3MgZmlsdGVycyBvbiB0aGUgbGVmdFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSByaWdodFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCIsIFwiZGFtcGVuaW5nXCJdKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucm9vbVNpemUsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gbWFrZSB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSByaWdodFxuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wgPSBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXMubWFwKGZyZXEgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWxscGFzc0wgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBhbGxwYXNzTC50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICBhbGxwYXNzTC5mcmVxdWVuY3kudmFsdWUgPSBmcmVxO1xuICAgICAgICAgICAgcmV0dXJuIGFsbHBhc3NMO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gbWFrZSB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSBsZWZ0XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzUiA9IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzUiA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3NSLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIGFsbHBhc3NSLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzc1I7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBjb21iIGZpbHRlcnNcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMgPSBjb21iRmlsdGVyVHVuaW5ncy5tYXAoKGRlbGF5VGltZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxmcGYgPSBuZXcgTG93cGFzc0NvbWJGaWx0ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBkYW1wZW5pbmc6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgICAgIGRlbGF5VGltZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGluZGV4IDwgY29tYkZpbHRlclR1bmluZ3MubGVuZ3RoIC8gMikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQobGZwZiwgLi4udGhpcy5fYWxscGFzc0ZpbHRlcnNMKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KGxmcGYsIC4uLnRoaXMuX2FsbHBhc3NGaWx0ZXJzUik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJvb21TaXplLmNvbm5lY3QobGZwZi5yZXNvbmFuY2UpO1xuICAgICAgICAgICAgcmV0dXJuIGxmcGY7XG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyb29tU2l6ZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHJvb21TaXplOiAwLjcsXG4gICAgICAgICAgICBkYW1wZW5pbmc6IDMwMDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgZGFtcGVuaW5nIG9mIHRoZSByZXZlcmJlcmFudCBzaWduYWwuXG4gICAgICovXG4gICAgZ2V0IGRhbXBlbmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbWJGaWx0ZXJzWzBdLmRhbXBlbmluZztcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhkKSB7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzLmZvckVhY2goYyA9PiBjLmRhbXBlbmluZyA9IGQpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTC5mb3JFYWNoKGFsID0+IGFsLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzUi5mb3JFYWNoKGFyID0+IGFyLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzLmZvckVhY2goY2YgPT4gY2YuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZWV2ZXJiLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBGZWVkYmFja0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GZWVkYmFja0NvbWJGaWx0ZXJcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogYW4gYXJyYXkgb2YgdGhlIGNvbWIgZmlsdGVyIGRlbGF5IHRpbWUgdmFsdWVzXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJEZWxheVRpbWVzID0gWzE2ODcgLyAyNTAwMCwgMTYwMSAvIDI1MDAwLCAyMDUzIC8gMjUwMDAsIDIyNTEgLyAyNTAwMF07XG4vKipcbiAqIHRoZSByZXNvbmFuY2VzIG9mIGVhY2ggb2YgdGhlIGNvbWIgZmlsdGVyc1xuICovXG5jb25zdCBjb21iRmlsdGVyUmVzb25hbmNlcyA9IFswLjc3MywgMC44MDIsIDAuNzUzLCAwLjczM107XG4vKipcbiAqIHRoZSBhbGxwYXNzIGZpbHRlciBmcmVxdWVuY2llc1xuICovXG5jb25zdCBhbGxwYXNzRmlsdGVyRnJlcXMgPSBbMzQ3LCAxMTMsIDM3XTtcbi8qKlxuICogSkNSZXZlcmIgaXMgYSBzaW1wbGUgW1NjaHJvZWRlciBSZXZlcmJlcmF0b3JdKGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L35qb3MvcGFzcC9TY2hyb2VkZXJfUmV2ZXJiZXJhdG9ycy5odG1sKVxuICogdHVuZWQgYnkgSm9obiBDaG93bmluZyBpbiAxOTcwLlxuICogSXQgaXMgbWFkZSB1cCBvZiB0aHJlZSBhbGxwYXNzIGZpbHRlcnMgYW5kIGZvdXIgW1tGZWVkYmFja0NvbWJGaWx0ZXJdXS5cbiAqIEpDUmV2ZXJiIGlzIG5vdyBpbXBsZW1lbnRlZCB3aXRoIGFuIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggbWF5IHJlc3VsdCBvbiBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbiBvbiBzb21lIHBsYXRmb3Jtcy4gQ29uc2lkZXIgdXNpbmcgW1tSZXZlcmJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZXZlcmIgPSBuZXcgVG9uZS5KQ1JldmVyYigwLjQpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGRlbGF5ID0gbmV3IFRvbmUuRmVlZGJhY2tEZWxheSgwLjUpO1xuICogLy8gY29ubmVjdGluZyB0aGUgc3ludGggdG8gcmV2ZXJiIHRocm91Z2ggZGVsYXlcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuRHVvU3ludGgoKS5jaGFpbihkZWxheSwgcmV2ZXJiKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTRcIiwgXCI4blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBKQ1JldmVyYiBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEpDUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJKQ1JldmVyYlwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogYSBzZXJpZXMgb2YgYWxscGFzcyBmaWx0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogcGFyYWxsZWwgZmVlZGJhY2sgY29tYiBmaWx0ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhKQ1JldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCJdKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucm9vbVNpemUsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZSA9IG5ldyBTY2FsZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IC0wLjczMyxcbiAgICAgICAgICAgIG1heDogMC4xOTcsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnNcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnMgPSBhbGxwYXNzRmlsdGVyRnJlcXMubWFwKGZyZXEgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWxscGFzcyA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3MudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgYWxscGFzcy5mcmVxdWVuY3kudmFsdWUgPSBmcmVxO1xuICAgICAgICAgICAgcmV0dXJuIGFsbHBhc3M7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBhbmQgdGhlIGNvbWIgZmlsdGVyc1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzID0gY29tYkZpbHRlckRlbGF5VGltZXMubWFwKChkZWxheVRpbWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmYmNmID0gbmV3IEZlZWRiYWNrQ29tYkZpbHRlcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGRlbGF5VGltZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZS5jb25uZWN0KGZiY2YucmVzb25hbmNlKTtcbiAgICAgICAgICAgIGZiY2YucmVzb25hbmNlLnZhbHVlID0gY29tYkZpbHRlclJlc29uYW5jZXNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKGluZGV4IDwgY29tYkZpbHRlckRlbGF5VGltZXMubGVuZ3RoIC8gMikge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQoLi4udGhpcy5fYWxscGFzc0ZpbHRlcnMsIGZiY2YpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQoLi4udGhpcy5fYWxscGFzc0ZpbHRlcnMsIGZiY2YpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZiY2Y7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjaGFpbiB0aGUgYWxscGFzcyBmaWx0ZXJzIHRvZ2V0aGVyXG4gICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdCh0aGlzLl9zY2FsZVJvb21TaXplKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicm9vbVNpemVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICByb29tU2l6ZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycy5mb3JFYWNoKGFwZiA9PiBhcGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tDb21iRmlsdGVycy5mb3JFYWNoKGZiY2YgPT4gZmJjZi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLnJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGVSb29tU2l6ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUpDUmV2ZXJiLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogSnVzdCBsaWtlIGEgW1tTdGVyZW9GZWVkYmFja0VmZmVjdF1dLCBidXQgdGhlIGZlZWRiYWNrIGlzIHJvdXRlZCBmcm9tIGxlZnQgdG8gcmlnaHRcbiAqIGFuZCByaWdodCB0byBsZWZ0IGluc3RlYWQgb2Ygb24gdGhlIHNhbWUgY2hhbm5lbC5cbiAqIGBgYFxuICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyBmZWVkYmFja0wgPC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogKy0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tPiAgICAgICAgKy0tLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0rXG4gKiAgICAgIGZlZWRiYWNrTWVyZ2UgKy0tPiBzcGxpdCAgICAgICAgKEVGRkVDVCkgICAgICAgbWVyZ2UgKy0tPiBmZWVkYmFja1NwbGl0ICAgICB8IHxcbiAqICstLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLT4gICAgICAgICstLS0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLSsgfFxuICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIGZlZWRiYWNrUiA8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvWEZlZWRiYWNrRWZmZWN0IGV4dGVuZHMgU3RlcmVvRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDEpO1xuICAgICAgICAvLyB0aGUgbGVmdCBvdXRwdXQgY29ubmVjdGVkIHRvIHRoZSByaWdodCBpbnB1dFxuICAgICAgICB0aGlzLl9mZWVkYmFja1IuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAwKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZmVlZGJhY2tcIl0pO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb1hGZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9YRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9YRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQaW5nUG9uZ0RlbGF5IGlzIGEgZmVlZGJhY2sgZGVsYXkgZWZmZWN0IHdoZXJlIHRoZSBlY2hvIGlzIGhlYXJkXG4gKiBmaXJzdCBpbiBvbmUgY2hhbm5lbCBhbmQgbmV4dCBpbiB0aGUgb3Bwb3NpdGUgY2hhbm5lbC4gSW4gYSBzdGVyZW9cbiAqIHN5c3RlbSB0aGVzZSBhcmUgdGhlIHJpZ2h0IGFuZCBsZWZ0IGNoYW5uZWxzLlxuICogUGluZ1BvbmdEZWxheSBpbiBtb3JlIHNpbXBsaWZpZWQgdGVybXMgaXMgdHdvIFRvbmUuRmVlZGJhY2tEZWxheXNcbiAqIHdpdGggaW5kZXBlbmRlbnQgZGVsYXkgdmFsdWVzLiBFYWNoIGRlbGF5IGlzIHJvdXRlZCB0byBvbmUgY2hhbm5lbFxuICogKGxlZnQgb3IgcmlnaHQpLCBhbmQgdGhlIGNoYW5uZWwgdHJpZ2dlcmVkIHNlY29uZCB3aWxsIGFsd2F5c1xuICogdHJpZ2dlciBhdCB0aGUgc2FtZSBpbnRlcnZhbCBhZnRlciB0aGUgZmlyc3QuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGluZ1BvbmcgPSBuZXcgVG9uZS5QaW5nUG9uZ0RlbGF5KFwiNG5cIiwgMC4yKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBkcnVtID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCgpLmNvbm5lY3QocGluZ1BvbmcpO1xuICogZHJ1bS50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiMzJuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgUGluZ1BvbmdEZWxheSBleHRlbmRzIFN0ZXJlb1hGZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBpbmdQb25nRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJmZWVkYmFja1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBpbmdQb25nRGVsYXlcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBpbmdQb25nRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJmZWVkYmFja1wiXSk7XG4gICAgICAgIHRoaXMuX2xlZnREZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0RGVsYXkgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXlcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0UHJlRGVsYXkgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXlcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fbGVmdERlbGF5KTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQodGhpcy5fcmlnaHRQcmVEZWxheSwgdGhpcy5fcmlnaHREZWxheSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmZhbih0aGlzLl9sZWZ0RGVsYXkuZGVsYXlUaW1lLCB0aGlzLl9yaWdodERlbGF5LmRlbGF5VGltZSwgdGhpcy5fcmlnaHRQcmVEZWxheS5kZWxheVRpbWUpO1xuICAgICAgICAvLyByZWFycmFuZ2VkIHRoZSBmZWVkYmFjayB0byBiZSBhZnRlciB0aGUgcmlnaHRQcmVEZWxheVxuICAgICAgICB0aGlzLl9mZWVkYmFja0wuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuY29ubmVjdCh0aGlzLl9yaWdodERlbGF5KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZGVsYXlUaW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9YRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjI1LFxuICAgICAgICAgICAgbWF4RGVsYXk6IDFcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGVmdERlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHREZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0UHJlRGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBpbmdQb25nRGVsYXkuanMubWFwIiwiaW1wb3J0IHsgRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8gfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG4vKipcbiAqIFBpdGNoU2hpZnQgZG9lcyBuZWFyLXJlYWx0aW1lIHBpdGNoIHNoaWZ0aW5nIHRvIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBUaGUgZWZmZWN0IGlzIGFjaGlldmVkIGJ5IHNwZWVkaW5nIHVwIG9yIHNsb3dpbmcgZG93biB0aGUgZGVsYXlUaW1lXG4gKiBvZiBhIERlbGF5Tm9kZSB1c2luZyBhIHNhd3Rvb3RoIHdhdmUuXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW3RoaXMgcGRmXShodHRwOi8vZHNwLWJvb2submFyb2QucnUvc291bmRwcm9jLnBkZikuXG4gKiBBZGRpdGlvbmFsIHJlZmVyZW5jZSBieSBbTWlsbGVyIFB1Y2tldF0oaHR0cDovL21zcC51Y3NkLmVkdS90ZWNobmlxdWVzL3YwLjExL2Jvb2staHRtbC9ub2RlMTE1Lmh0bWwpLlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgUGl0Y2hTaGlmdCBleHRlbmRzIEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGl0Y2hTaGlmdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBpdGNoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGl0Y2hTaGlmdFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGl0Y2hTaGlmdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBpdGNoXCJdKTtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZGVsYXlBID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9BID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDAuMSxcbiAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIlxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2RlbGF5QS5kZWxheVRpbWUpO1xuICAgICAgICB0aGlzLl9kZWxheUIgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb0IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiLFxuICAgICAgICAgICAgcGhhc2U6IDE4MFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2RlbGF5Qi5kZWxheVRpbWUpO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGUgPSBuZXcgQ3Jvc3NGYWRlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGVMRk8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgICAgIHBoYXNlOiA5MFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2Nyb3NzRmFkZS5mYWRlKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tEZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBkZWxheVRpbWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9mZWVkYmFja0RlbGF5LmRlbGF5VGltZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJkZWxheVRpbWVcIik7XG4gICAgICAgIHRoaXMuX3BpdGNoID0gb3B0aW9ucy5waXRjaDtcbiAgICAgICAgdGhpcy5fd2luZG93U2l6ZSA9IG9wdGlvbnMud2luZG93U2l6ZTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgdHdvIGRlbGF5IGxpbmVzIHVwXG4gICAgICAgIHRoaXMuX2RlbGF5QS5jb25uZWN0KHRoaXMuX2Nyb3NzRmFkZS5hKTtcbiAgICAgICAgdGhpcy5fZGVsYXlCLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmIpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBmcmVxdWVuY3lcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5LmZhbih0aGlzLl9sZm9BLmZyZXF1ZW5jeSwgdGhpcy5fbGZvQi5mcmVxdWVuY3ksIHRoaXMuX2Nyb3NzRmFkZUxGTy5mcmVxdWVuY3kpO1xuICAgICAgICAvLyByb3V0ZSB0aGUgaW5wdXRcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmZhbih0aGlzLl9kZWxheUEsIHRoaXMuX2RlbGF5Qik7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZS5jaGFpbih0aGlzLl9mZWVkYmFja0RlbGF5LCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBMRk9zIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgdGhpcy5fbGZvQS5zdGFydChub3cpO1xuICAgICAgICB0aGlzLl9sZm9CLnN0YXJ0KG5vdyk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTy5zdGFydChub3cpO1xuICAgICAgICAvLyBzZXQgdGhlIGluaXRpYWwgdmFsdWVcbiAgICAgICAgdGhpcy53aW5kb3dTaXplID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwaXRjaDogMCxcbiAgICAgICAgICAgIHdpbmRvd1NpemU6IDAuMSxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBpdGNoIHRoZSBpbmNvbWluZyBzaWduYWwgYnkgc29tZSBpbnRlcnZhbCAobWVhc3VyZWQgaW4gc2VtaS10b25lcykuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwaXRjaFNoaWZ0ID0gbmV3IFRvbmUuUGl0Y2hTaGlmdCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChwaXRjaFNoaWZ0KS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwaXRjaFNoaWZ0LnBpdGNoID0gLTEyOyAvLyBkb3duIG9uZSBvY3RhdmVcbiAgICAgKiBwaXRjaFNoaWZ0LnBpdGNoID0gNzsgLy8gdXAgYSBmaWZ0aFxuICAgICAqL1xuICAgIGdldCBwaXRjaCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BpdGNoO1xuICAgIH1cbiAgICBzZXQgcGl0Y2goaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fcGl0Y2ggPSBpbnRlcnZhbDtcbiAgICAgICAgbGV0IGZhY3RvciA9IDA7XG4gICAgICAgIGlmIChpbnRlcnZhbCA8IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWluID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWF4ID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWluID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWF4ID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIGZhY3RvciA9IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCAtIDEpICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWluID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX2xmb0EubWF4ID0gMDtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWluID0gdGhpcy5fd2luZG93U2l6ZTtcbiAgICAgICAgICAgIHRoaXMuX2xmb0IubWF4ID0gMDtcbiAgICAgICAgICAgIGZhY3RvciA9IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCkgLSAxO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS52YWx1ZSA9IGZhY3RvciAqICgxLjIgLyB0aGlzLl93aW5kb3dTaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHdpbmRvdyBzaXplIGNvcnJlc3BvbmRzIHJvdWdobHkgdG8gdGhlIHNhbXBsZSBsZW5ndGggaW4gYSBsb29waW5nIHNhbXBsZXIuXG4gICAgICogU21hbGxlciB2YWx1ZXMgYXJlIGRlc2lyYWJsZSBmb3IgYSBsZXNzIG5vdGljZWFibGUgZGVsYXkgdGltZSBvZiB0aGUgcGl0Y2ggc2hpZnRlZFxuICAgICAqIHNpZ25hbCwgYnV0IGxhcmdlciB2YWx1ZXMgd2lsbCByZXN1bHQgaW4gc21vb3RoZXIgcGl0Y2ggc2hpZnRpbmcgZm9yIGxhcmdlciBpbnRlcnZhbHMuXG4gICAgICogQSBub21pbmFsIHJhbmdlIG9mIDAuMDMgdG8gMC4xIGlzIHJlY29tbWVuZGVkLlxuICAgICAqL1xuICAgIGdldCB3aW5kb3dTaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fd2luZG93U2l6ZTtcbiAgICB9XG4gICAgc2V0IHdpbmRvd1NpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl93aW5kb3dTaXplID0gdGhpcy50b1NlY29uZHMoc2l6ZSk7XG4gICAgICAgIHRoaXMucGl0Y2ggPSB0aGlzLl9waXRjaDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheUEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheUIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9BLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvQi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrRGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QaXRjaFNoaWZ0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQaGFzZXIgaXMgYSBwaGFzZXIgZWZmZWN0LiBQaGFzZXJzIHdvcmsgYnkgY2hhbmdpbmcgdGhlIHBoYXNlXG4gKiBvZiBkaWZmZXJlbnQgZnJlcXVlbmN5IGNvbXBvbmVudHMgb2YgYW4gaW5jb21pbmcgc2lnbmFsLiBSZWFkIG1vcmUgb25cbiAqIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BoYXNlcl8oZWZmZWN0KSkuXG4gKiBJbnNwaXJhdGlvbiBmb3IgdGhpcyBwaGFzZXIgY29tZXMgZnJvbSBbVHVuYS5qc10oaHR0cHM6Ly9naXRodWIuY29tL0RpbmFobW9lL3R1bmEvKS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwaGFzZXIgPSBuZXcgVG9uZS5QaGFzZXIoe1xuICogXHRmcmVxdWVuY3k6IDE1LFxuICogXHRvY3RhdmVzOiA1LFxuICogXHRiYXNlRnJlcXVlbmN5OiAxMDAwXG4gKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLkZNU3ludGgoKS5jb25uZWN0KHBoYXNlcik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkUzXCIsIFwiMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaGFzZXIgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQaGFzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwiYmFzZUZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBoYXNlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGhhc2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcImJhc2VGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9sZm9MID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9SID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgcGhhc2U6IDE4MCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KG9wdGlvbnMuYmFzZUZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9maWx0ZXJzTCA9IHRoaXMuX21ha2VGaWx0ZXJzKG9wdGlvbnMuc3RhZ2VzLCB0aGlzLl9sZm9MKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyc1IgPSB0aGlzLl9tYWtlRmlsdGVycyhvcHRpb25zLnN0YWdlcywgdGhpcy5fbGZvUik7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvTC5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LnZhbHVlID0gb3B0aW9ucy5mcmVxdWVuY3k7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlbSB1cFxuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KC4uLnRoaXMuX2ZpbHRlcnNMKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQoLi4udGhpcy5fZmlsdGVyc1IpO1xuICAgICAgICAvLyBjb250cm9sIHRoZSBmcmVxdWVuY3kgd2l0aCBvbmUgTEZPXG4gICAgICAgIHRoaXMuX2xmb0wuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuICAgICAgICAvLyBzZXQgdGhlIG9wdGlvbnNcbiAgICAgICAgdGhpcy5iYXNlRnJlcXVlbmN5ID0gb3B0aW9ucy5iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBsZm9cbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCgpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcIlFcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAuNSxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDMsXG4gICAgICAgICAgICBzdGFnZXM6IDEwLFxuICAgICAgICAgICAgUTogMTAsXG4gICAgICAgICAgICBiYXNlRnJlcXVlbmN5OiAzNTAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfbWFrZUZpbHRlcnMoc3RhZ2VzLCBjb25uZWN0VG9GcmVxKSB7XG4gICAgICAgIGNvbnN0IGZpbHRlcnMgPSBbXTtcbiAgICAgICAgLy8gbWFrZSBhbGwgdGhlIGZpbHRlcnNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGFnZXM7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgZmlsdGVyLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIHRoaXMuUS5jb25uZWN0KGZpbHRlci5RKTtcbiAgICAgICAgICAgIGNvbm5lY3RUb0ZyZXEuY29ubmVjdChmaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIGZpbHRlcnMucHVzaChmaWx0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmaWx0ZXJzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgdGhlIHBoYXNlIGdvZXMgYWJvdmUgdGhlIGJhc2VGcmVxdWVuY3lcbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIGNvbnN0IG1heCA9IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcbiAgICAgICAgdGhpcy5fbGZvTC5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMuX2xmb1IubWF4ID0gbWF4O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGhlIGJhc2UgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXJzLlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3koZnJlcSkge1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShmcmVxKTtcbiAgICAgICAgdGhpcy5fbGZvTC5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9sZm9SLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzTC5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzUi5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBoYXNlci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5vaXNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Ob2lzZVwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFNpbXBsZSBjb252b2x1dGlvbiBjcmVhdGVkIHdpdGggZGVjYXlpbmcgbm9pc2UuXG4gKiBHZW5lcmF0ZXMgYW4gSW1wdWxzZSBSZXNwb25zZSBCdWZmZXJcbiAqIHdpdGggVG9uZS5PZmZsaW5lIHRoZW4gZmVlZHMgdGhlIElSIGludG8gQ29udm9sdmVyTm9kZS5cbiAqIFRoZSBpbXB1bHNlIHJlc3BvbnNlIGdlbmVyYXRpb24gaXMgYXN5bmMsIHNvIHlvdSBoYXZlXG4gKiB0byB3YWl0IHVudGlsIFtbcmVhZHldXSByZXNvbHZlcyBiZWZvcmUgaXQgd2lsbCBtYWtlIGEgc291bmQuXG4gKlxuICogSW5zcGlyYXRpb24gZnJvbSBbUmV2ZXJiR2VuXShodHRwczovL2dpdGh1Yi5jb20vYWRlbGVzcGluYXNzZS9yZXZlcmJHZW4pLlxuICogQ29weXJpZ2h0IChjKSAyMDE0IEFsYW4gZGVMZXNwaW5hc3NlIEFwYWNoZSAyLjAgTGljZW5zZS5cbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBSZXZlcmIgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWNheVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlJldmVyYlwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQ29udm9sdmVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnZvbHZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlc29sdmVzIHdoZW4gdGhlIHJldmVyYiBidWZmZXIgaXMgZ2VuZXJhdGVkLiBXaGVuZXZlciBlaXRoZXIgW1tkZWNheV1dXG4gICAgICAgICAqIG9yIFtbcHJlRGVsYXldXSBhcmUgc2V0LCB5b3UgaGF2ZSB0byB3YWl0IHVudGlsIFtbcmVhZHldXSByZXNvbHZlc1xuICAgICAgICAgKiBiZWZvcmUgdGhlIElSIGlzIGdlbmVyYXRlZCB3aXRoIHRoZSBsYXRlc3QgdmFsdWVzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5yZWFkeSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVjYXlcIl0pO1xuICAgICAgICB0aGlzLl9kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG4gICAgICAgIHRoaXMuX3ByZURlbGF5ID0gb3B0aW9ucy5wcmVEZWxheTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZSgpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fY29udm9sdmVyKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVjYXk6IDEuNSxcbiAgICAgICAgICAgIHByZURlbGF5OiAwLjAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIG9mIHRoZSByZXZlcmIuXG4gICAgICovXG4gICAgZ2V0IGRlY2F5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjYXk7XG4gICAgfVxuICAgIHNldCBkZWNheSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0UmFuZ2UodGltZSwgMC4wMDEpO1xuICAgICAgICB0aGlzLl9kZWNheSA9IHRpbWU7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGJlZm9yZSB0aGUgcmV2ZXJiIGlzIGZ1bGx5IHJhbXBlZCBpbi5cbiAgICAgKi9cbiAgICBnZXQgcHJlRGVsYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmVEZWxheTtcbiAgICB9XG4gICAgc2V0IHByZURlbGF5KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwKTtcbiAgICAgICAgdGhpcy5fcHJlRGVsYXkgPSB0aW1lO1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIHRoZSBJbXB1bHNlIFJlc3BvbnNlLiBSZXR1cm5zIGEgcHJvbWlzZSB3aGlsZSB0aGUgSVIgaXMgYmVpbmcgZ2VuZXJhdGVkLlxuICAgICAqIEByZXR1cm4gUHJvbWlzZSB3aGljaCByZXR1cm5zIHRoaXMgb2JqZWN0LlxuICAgICAqL1xuICAgIGdlbmVyYXRlKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNSZWFkeSA9IHRoaXMucmVhZHk7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYSBub2lzZSBidXJzdCB3aGljaCBkZWNheXMgb3ZlciB0aGUgZHVyYXRpb24gaW4gZWFjaCBjaGFubmVsXG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDIsIHRoaXMuX2RlY2F5ICsgdGhpcy5fcHJlRGVsYXksIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIGNvbnN0IG5vaXNlTCA9IG5ldyBOb2lzZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBjb25zdCBub2lzZVIgPSBuZXcgTm9pc2UoeyBjb250ZXh0IH0pO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0IH0pO1xuICAgICAgICAgICAgbm9pc2VMLmNvbm5lY3QobWVyZ2UsIDAsIDApO1xuICAgICAgICAgICAgbm9pc2VSLmNvbm5lY3QobWVyZ2UsIDAsIDEpO1xuICAgICAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBuZXcgR2Fpbih7IGNvbnRleHQgfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAgICAgICAgbWVyZ2UuY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgICAgICBub2lzZUwuc3RhcnQoMCk7XG4gICAgICAgICAgICBub2lzZVIuc3RhcnQoMCk7XG4gICAgICAgICAgICAvLyBwcmVkZWxheVxuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCAwKTtcbiAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgdGhpcy5fcHJlRGVsYXkpO1xuICAgICAgICAgICAgLy8gZGVjYXlcbiAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKDAsIHRoaXMuX3ByZURlbGF5LCB0aGlzLmRlY2F5KTtcbiAgICAgICAgICAgIC8vIHJlbmRlciB0aGUgYnVmZmVyXG4gICAgICAgICAgICBjb25zdCByZW5kZXJQcm9taXNlID0gY29udGV4dC5yZW5kZXIoKTtcbiAgICAgICAgICAgIHRoaXMucmVhZHkgPSByZW5kZXJQcm9taXNlLnRoZW4obm9PcCk7XG4gICAgICAgICAgICAvLyB3YWl0IGZvciB0aGUgcHJldmlvdXMgYHJlYWR5YCB0byByZXNvbHZlXG4gICAgICAgICAgICB5aWVsZCBwcmV2aW91c1JlYWR5O1xuICAgICAgICAgICAgLy8gc2V0IHRoZSBidWZmZXJcbiAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSAoeWllbGQgcmVuZGVyUHJvbWlzZSkuZ2V0KCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UmV2ZXJiLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4vU3BsaXRcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi8uLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1pZC9TaWRlIHByb2Nlc3Npbmcgc2VwYXJhdGVzIHRoZSB0aGUgJ21pZCcgc2lnbmFsICh3aGljaCBjb21lcyBvdXQgb2YgYm90aCB0aGUgbGVmdCBhbmQgdGhlIHJpZ2h0IGNoYW5uZWwpXG4gKiBhbmQgdGhlICdzaWRlJyAod2hpY2ggb25seSBjb21lcyBvdXQgb2YgdGhlIHRoZSBzaWRlIGNoYW5uZWxzKS5cbiAqIGBgYFxuICogTWlkID0gKExlZnQrUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIG1pZC1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogU2lkZSA9IChMZWZ0LVJpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBzaWRlLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZVNwbGl0XCI7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gdGhpcy5pbnB1dCA9IG5ldyBTcGxpdCh7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkQWRkID0gbmV3IEFkZCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5taWQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpZGVTdWJ0cmFjdCA9IG5ldyBTdWJ0cmFjdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5zaWRlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBNYXRoLlNRUlQxXzIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX21pZEFkZCwgMCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fbWlkQWRkLmFkZGVuZCwgMSk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fc2lkZVN1YnRyYWN0LCAwKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9zaWRlU3VidHJhY3Quc3VidHJhaGVuZCwgMSk7XG4gICAgICAgIHRoaXMuX21pZEFkZC5jb25uZWN0KHRoaXMubWlkKTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmNvbm5lY3QodGhpcy5zaWRlKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuc2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZEFkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVTdWJ0cmFjdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZVNwbGl0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4vTWVyZ2VcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi8uLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1pZFNpZGVNZXJnZSBtZXJnZXMgdGhlIG1pZCBhbmQgc2lkZSBzaWduYWwgYWZ0ZXIgdGhleSd2ZSBiZWVuIHNlcGFyYXRlZCBieSBbW01pZFNpZGVTcGxpdF1dXG4gKiBgYGBcbiAqIE1pZCA9IChMZWZ0K1JpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBtaWQtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIFNpZGUgPSAoTGVmdC1SaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gc2lkZS1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlTWVyZ2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZU1lcmdlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVNZXJnZVwiO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLnNpZGUgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG5ldyBBZGQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2xlZnRNdWx0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBNYXRoLlNRUlQxXzJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5taWQuZmFuKHRoaXMuX2xlZnQpO1xuICAgICAgICB0aGlzLnNpZGUuY29ubmVjdCh0aGlzLl9sZWZ0LmFkZGVuZCk7XG4gICAgICAgIHRoaXMubWlkLmNvbm5lY3QodGhpcy5fcmlnaHQpO1xuICAgICAgICB0aGlzLnNpZGUuY29ubmVjdCh0aGlzLl9yaWdodC5zdWJ0cmFoZW5kKTtcbiAgICAgICAgdGhpcy5fbGVmdC5jb25uZWN0KHRoaXMuX2xlZnRNdWx0KTtcbiAgICAgICAgdGhpcy5fcmlnaHQuY29ubmVjdCh0aGlzLl9yaWdodE11bHQpO1xuICAgICAgICB0aGlzLl9sZWZ0TXVsdC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAwKTtcbiAgICAgICAgdGhpcy5fcmlnaHRNdWx0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDEpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGVmdE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlTWVyZ2UuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBNaWRTaWRlU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5pbXBvcnQgeyBNaWRTaWRlTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZU1lcmdlXCI7XG4vKipcbiAqIE1pZC9TaWRlIHByb2Nlc3Npbmcgc2VwYXJhdGVzIHRoZSB0aGUgJ21pZCcgc2lnbmFsXG4gKiAod2hpY2ggY29tZXMgb3V0IG9mIGJvdGggdGhlIGxlZnQgYW5kIHRoZSByaWdodCBjaGFubmVsKVxuICogYW5kIHRoZSAnc2lkZScgKHdoaWNoIG9ubHkgY29tZXMgb3V0IG9mIHRoZSB0aGUgc2lkZSBjaGFubmVscylcbiAqIGFuZCBlZmZlY3RzIHRoZW0gc2VwYXJhdGVseSBiZWZvcmUgYmVpbmcgcmVjb21iaW5lZC5cbiAqIEFwcGxpZXMgYSBNaWQvU2lkZSBzZXBlcmF0aW9uIGFuZCByZWNvbWJpbmF0aW9uLlxuICogQWxnb3JpdGhtIGZvdW5kIGluIFtrdnJhdWRpbyBmb3J1bXNdKGh0dHA6Ly93d3cua3ZyYXVkaW8uY29tL2ZvcnVtL3ZpZXd0b3BpYy5waHA/dD0yMTI1ODcpLlxuICogVGhpcyBpcyBhIGJhc2UtY2xhc3MgZm9yIE1pZC9TaWRlIEVmZmVjdHMuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlRWZmZWN0IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVFZmZlY3RcIjtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlID0gbmV3IE1pZFNpZGVNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0ID0gbmV3IE1pZFNpZGVTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2VuZCA9IHRoaXMuX21pZFNpZGVTcGxpdC5taWQ7XG4gICAgICAgIHRoaXMuX3NpZGVTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0LnNpZGU7XG4gICAgICAgIHRoaXMuX21pZFJldHVybiA9IHRoaXMuX21pZFNpZGVNZXJnZS5taWQ7XG4gICAgICAgIHRoaXMuX3NpZGVSZXR1cm4gPSB0aGlzLl9taWRTaWRlTWVyZ2Uuc2lkZTtcbiAgICAgICAgLy8gdGhlIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jb25uZWN0KHRoaXMuX21pZFNpZGVTcGxpdCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5jb25uZWN0KHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgbWlkIGNoYWluIG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0TWlkKC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX21pZFNlbmQuY2hhaW4oLi4ubm9kZXMsIHRoaXMuX21pZFJldHVybik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIHNpZGUgY2hhaW4gb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RTaWRlKC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NpZGVTZW5kLmNoYWluKC4uLm5vZGVzLCB0aGlzLl9zaWRlUmV0dXJuKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTZW5kLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRSZXR1cm4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlUmV0dXJuLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZUVmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBNaWRTaWRlRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9NaWRTaWRlRWZmZWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuLi9zaWduYWwvU3VidHJhY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBBcHBsaWVzIGEgd2lkdGggZmFjdG9yIHRvIHRoZSBtaWQvc2lkZSBzZXBlcmF0aW9uLlxuICogMCBpcyBhbGwgbWlkIGFuZCAxIGlzIGFsbCBzaWRlLlxuICogQWxnb3JpdGhtIGZvdW5kIGluIFtrdnJhdWRpbyBmb3J1bXNdKGh0dHA6Ly93d3cua3ZyYXVkaW8uY29tL2ZvcnVtL3ZpZXd0b3BpYy5waHA/dD0yMTI1ODcpLlxuICogYGBgXG4gKiBNaWQgKj0gMiooMS13aWR0aCk8YnI+XG4gKiBTaWRlICo9IDIqd2lkdGhcbiAqIGBgYFxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvV2lkZW5lciBleHRlbmRzIE1pZFNpZGVFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTdGVyZW9XaWRlbmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wid2lkdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGVyZW9XaWRlbmVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTdGVyZW9XaWRlbmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wid2lkdGhcIl0pO1xuICAgICAgICB0aGlzLndpZHRoID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy53aWR0aCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21pZE11bHQgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQuY29ubmVjdCh0aGlzLl9taWRNdWx0LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdE1pZCh0aGlzLl9taWRNdWx0KTtcbiAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aCA9IG5ldyBTdWJ0cmFjdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aC5jb25uZWN0KHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQpO1xuICAgICAgICBjb25uZWN0KHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgxKSwgdGhpcy5fb25lTWludXNXaWR0aCk7XG4gICAgICAgIHRoaXMud2lkdGguY29ubmVjdCh0aGlzLl9vbmVNaW51c1dpZHRoLnN1YnRyYWhlbmQpO1xuICAgICAgICB0aGlzLl9zaWRlTXVsdCA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy53aWR0aC5jb25uZWN0KHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUuY29ubmVjdCh0aGlzLl9zaWRlTXVsdC5mYWN0b3IpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RTaWRlKHRoaXMuX3NpZGVNdWx0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNaWRTaWRlRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHdpZHRoOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMud2lkdGguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRNdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZU11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoTWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvV2lkZW5lci5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9FZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9FZmZlY3RcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogVHJlbW9sbyBtb2R1bGF0ZXMgdGhlIGFtcGxpdHVkZSBvZiBhbiBpbmNvbWluZyBzaWduYWwgdXNpbmcgYW4gW1tMRk9dXS5cbiAqIFRoZSBlZmZlY3QgaXMgYSBzdGVyZW8gZWZmZWN0IHdoZXJlIHRoZSBtb2R1bGF0aW9uIHBoYXNlIGlzIGludmVydGVkIGluIGVhY2ggY2hhbm5lbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gY3JlYXRlIGEgdHJlbW9sbyBhbmQgc3RhcnQgaXQncyBMRk9cbiAqIGNvbnN0IHRyZW1vbG8gPSBuZXcgVG9uZS5UcmVtb2xvKDksIDAuNzUpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gcm91dGUgYW4gb3NjaWxsYXRvciB0aHJvdWdoIHRoZSB0cmVtb2xvIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHRyZW1vbG8pLnN0YXJ0KCk7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgVHJlbW9sbyBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyZW1vbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRyZW1vbG9cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyZW1vbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMSxcbiAgICAgICAgICAgIG1heDogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMSxcbiAgICAgICAgICAgIG1heDogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUwgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlUiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlcHRoID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXB0aCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fYW1wbGl0dWRlTCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KHRoaXMuX2FtcGxpdHVkZVIpO1xuICAgICAgICB0aGlzLl9sZm9MLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlTC5nYWluKTtcbiAgICAgICAgdGhpcy5fbGZvUi5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZVIuZ2Fpbik7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmZhbih0aGlzLl9sZm9MLmZyZXF1ZW5jeSwgdGhpcy5fbGZvUi5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmRlcHRoLmZhbih0aGlzLl9sZm9SLmFtcGxpdHVkZSwgdGhpcy5fbGZvTC5hbXBsaXR1ZGUpO1xuICAgICAgICB0aGlzLnNwcmVhZCA9IG9wdGlvbnMuc3ByZWFkO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICBkZXB0aDogMC41LFxuICAgICAgICAgICAgc3ByZWFkOiAxODAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgdHJlbW9sby5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSB0cmVtb2xvLlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGVmZmVjdCB0byB0aGUgdHJhbnNwb3J0LlxuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnN5bmMoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC51bnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmb0wudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9sZm9SLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbW91bnQgb2Ygc3RlcmVvIHNwcmVhZC4gV2hlbiBzZXQgdG8gMCwgYm90aCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBjZW50cmFsbHkuXG4gICAgICogV2hlbiBzZXQgdG8gMTgwLCBMRk8ncyB3aWxsIGJlIHBhbm5lZCBoYXJkIGxlZnQgYW5kIHJpZ2h0IHJlc3BlY3RpdmVseS5cbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvUi5waGFzZSAtIHRoaXMuX2xmb0wucGhhc2U7IC8vIDE4MFxuICAgIH1cbiAgICBzZXQgc3ByZWFkKHNwcmVhZCkge1xuICAgICAgICB0aGlzLl9sZm9MLnBoYXNlID0gOTAgLSAoc3ByZWFkIC8gMik7XG4gICAgICAgIHRoaXMuX2xmb1IucGhhc2UgPSAoc3ByZWFkIC8gMikgKyA5MDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJlbW9sby5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEEgVmlicmF0byBlZmZlY3QgY29tcG9zZWQgb2YgYSBUb25lLkRlbGF5IGFuZCBhIFRvbmUuTEZPLiBUaGUgTEZPXG4gKiBtb2R1bGF0ZXMgdGhlIGRlbGF5VGltZSBvZiB0aGUgZGVsYXksIGNhdXNpbmcgdGhlIHBpdGNoIHRvIHJpc2UgYW5kIGZhbGwuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBWaWJyYXRvIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVmlicmF0by5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVmlicmF0b1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVmlicmF0by5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgcGhhc2U6IC05MCAvLyBvZmZzZSB0aGUgcGhhc2Ugc28gdGhlIHJlc3RpbmcgcG9zaXRpb24gaXMgaW4gdGhlIGNlbnRlclxuICAgICAgICB9KS5zdGFydCgpLmNvbm5lY3QodGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2xmby5hbXBsaXR1ZGU7XG4gICAgICAgIHRoaXMuZGVwdGgudmFsdWUgPSBvcHRpb25zLmRlcHRoO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9kZWxheU5vZGUsIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4RGVsYXk6IDAuMDA1LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA1LFxuICAgICAgICAgICAgZGVwdGg6IDAuMSxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIG9zY2lsbGF0b3IgYXR0YWNoZWQgdG8gdGhlIFZpYnJhdG8uXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8udHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm8udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VmlicmF0by5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BdXRvRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BdXRvUGFubmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BdXRvV2FoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9CaXRDcnVzaGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9DaGVieXNoZXZcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Nob3J1c1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vRGlzdG9ydGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRmVlZGJhY2tEZWxheVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRnJlcXVlbmN5U2hpZnRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRnJlZXZlcmJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0pDUmV2ZXJiXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QaW5nUG9uZ0RlbGF5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QaXRjaFNoaWZ0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QaGFzZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1JldmVyYlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3RlcmVvV2lkZW5lclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVHJlbW9sb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vVmlicmF0b1wiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL1NwbGl0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBhc3NlcnQsIGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIFdlYiBBdWRpbydzIFtBbmFseXNlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jaWRsLWRlZi1BbmFseXNlck5vZGUpLlxuICogRXh0cmFjdHMgRkZUIG9yIFdhdmVmb3JtIGRhdGEgZnJvbSB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQW5hbHlzZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQW5hbHlzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0eXBlXCIsIFwic2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFuYWx5c2VyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYW5hbHlzZXIgbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FuYWx5c2VycyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGJ1ZmZlciB0aGF0IHRoZSBGRlQgZGF0YSBpcyB3cml0dGVuIHRvXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBbmFseXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIiwgXCJzaXplXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fZ2FpbiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9zcGxpdCA9IG5ldyBTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjaGFubmVsczogb3B0aW9ucy5jaGFubmVscyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIGFzc2VydFJhbmdlKG9wdGlvbnMuY2hhbm5lbHMsIDEpO1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGFuYWx5c2Vyc1xuICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IG9wdGlvbnMuY2hhbm5lbHM7IGNoYW5uZWwrKykge1xuICAgICAgICAgICAgdGhpcy5fYW5hbHlzZXJzW2NoYW5uZWxdID0gdGhpcy5jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX2FuYWx5c2Vyc1tjaGFubmVsXSwgY2hhbm5lbCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IHRoZSB2YWx1ZXMgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICAgICAgdHlwZTogXCJmZnRcIixcbiAgICAgICAgICAgIGNoYW5uZWxzOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUnVuIHRoZSBhbmFseXNpcyBnaXZlbiB0aGUgY3VycmVudCBzZXR0aW5ncy4gSWYgW1tjaGFubmVsc11dID0gMSxcbiAgICAgKiBpdCB3aWxsIHJldHVybiBhIEZsb2F0MzJBcnJheS4gSWYgW1tjaGFubmVsc11dID4gMSwgaXQgd2lsbFxuICAgICAqIHJldHVybiBhbiBhcnJheSBvZiBGbG9hdDMyQXJyYXlzIHdoZXJlIGVhY2ggaW5kZXggaW4gdGhlIGFycmF5XG4gICAgICogcmVwcmVzZW50cyB0aGUgYW5hbHlzaXMgZG9uZSBvbiBhIGNoYW5uZWwuXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKChhbmFseXNlciwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuX2J1ZmZlcnNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwiZmZ0XCIpIHtcbiAgICAgICAgICAgICAgICBhbmFseXNlci5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoYnVmZmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3R5cGUgPT09IFwid2F2ZWZvcm1cIikge1xuICAgICAgICAgICAgICAgIGFuYWx5c2VyLmdldEZsb2F0VGltZURvbWFpbkRhdGEoYnVmZmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLmNoYW5uZWxzID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyc1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGFuYWx5c2lzLiBUaGlzIG11c3QgYmUgYSBwb3dlciBvZiB0d28gaW4gdGhlIHJhbmdlIDE2IHRvIDE2Mzg0LlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXJzWzBdLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgIH1cbiAgICBzZXQgc2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKChhbmFseXNlciwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGFuYWx5c2VyLmZmdFNpemUgPSBzaXplICogMjtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnNbaW5kZXhdID0gbmV3IEZsb2F0MzJBcnJheShzaXplKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgdGhlIGFuYWx5c2VyIGRvZXMgdGhlIGFuYWx5c2lzIG9uLiBDaGFubmVsXG4gICAgICogc2VwYXJhdGlvbiBpcyBkb25lIHVzaW5nIFtbU3BsaXRdXVxuICAgICAqL1xuICAgIGdldCBjaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2Vycy5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbmFseXNpcyBmdW5jdGlvbiByZXR1cm5lZCBieSBhbmFseXNlci5nZXRWYWx1ZSgpLCBlaXRoZXIgXCJmZnRcIiBvciBcIndhdmVmb3JtXCIuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGFzc2VydCh0eXBlID09PSBcIndhdmVmb3JtXCIgfHwgdHlwZSA9PT0gXCJmZnRcIiwgYEFuYWx5c2VyOiBpbnZhbGlkIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIDAgcmVwcmVzZW50cyBubyB0aW1lIGF2ZXJhZ2luZyB3aXRoIHRoZSBsYXN0IGFuYWx5c2lzIGZyYW1lLlxuICAgICAqL1xuICAgIGdldCBzbW9vdGhpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlcnNbMF0uc21vb3RoaW5nVGltZUNvbnN0YW50O1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHZhbCkge1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMuZm9yRWFjaChhID0+IGEuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gdmFsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMuZm9yRWFjaChhID0+IGEuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QW5hbHlzZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBBbmFseXNlciB9IGZyb20gXCIuL0FuYWx5c2VyXCI7XG4vKipcbiAqIFRoZSBiYXNlIGNsYXNzIGZvciBNZXRlcmluZyBjbGFzc2VzLlxuICovXG5leHBvcnQgY2xhc3MgTWV0ZXJCYXNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyQmFzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZXRlckJhc2VcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fYW5hbHlzZXIgPSBuZXcgQW5hbHlzZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc2l6ZTogMjU2LFxuICAgICAgICAgICAgdHlwZTogXCJ3YXZlZm9ybVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbmFseXNlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1ldGVyQmFzZS5qcy5tYXAiLCJpbXBvcnQgeyBnYWluVG9EYiB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG5pbXBvcnQgeyB3YXJuIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgQW5hbHlzZXIgfSBmcm9tIFwiLi9BbmFseXNlclwiO1xuLyoqXG4gKiBNZXRlciBnZXRzIHRoZSBbUk1TXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Sb290X21lYW5fc3F1YXJlKVxuICogb2YgYW4gaW5wdXQgc2lnbmFsLiBJdCBjYW4gYWxzbyBnZXQgdGhlIHJhdyB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXRlciA9IG5ldyBUb25lLk1ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAqIG1pYy5vcGVuKCk7XG4gKiAvLyBjb25uZWN0IG1pYyB0byB0aGUgbWV0ZXJcbiAqIG1pYy5jb25uZWN0KG1ldGVyKTtcbiAqIC8vIHRoZSBjdXJyZW50IGxldmVsIG9mIHRoZSBtaWNcbiAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKG1ldGVyLmdldFZhbHVlKCkpLCAxMDApO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWV0ZXIgZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNtb290aGluZ1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcHJldmlvdXMgZnJhbWUncyB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcm1zID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5fYW5hbHlzZXIgPSBuZXcgQW5hbHlzZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc2l6ZTogMjU2LFxuICAgICAgICAgICAgdHlwZTogXCJ3YXZlZm9ybVwiLFxuICAgICAgICAgICAgY2hhbm5lbHM6IG9wdGlvbnMuY2hhbm5lbHMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNtb290aGluZyA9IG9wdGlvbnMuc21vb3RoaW5nLFxuICAgICAgICAgICAgdGhpcy5ub3JtYWxSYW5nZSA9IG9wdGlvbnMubm9ybWFsUmFuZ2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTWV0ZXJCYXNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICAgICAgbm9ybWFsUmFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgY2hhbm5lbHM6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVc2UgW1tnZXRWYWx1ZV1dIGluc3RlYWQuIEZvciB0aGUgcHJldmlvdXMgZ2V0VmFsdWUgYmVoYXZpb3IsIHVzZSBEQ01ldGVyLlxuICAgICAqIEBkZXByZWNhdGVkXG4gICAgICovXG4gICAgZ2V0TGV2ZWwoKSB7XG4gICAgICAgIHdhcm4oXCInZ2V0TGV2ZWwnIGhhcyBiZWVuIGNoYW5nZWQgdG8gJ2dldFZhbHVlJ1wiKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gICAgICogT3V0cHV0IGlzIGluIGRlY2liZWxzIHdoZW4gW1tub3JtYWxSYW5nZV1dIGlzIGBmYWxzZWAuXG4gICAgICogSWYgW1tjaGFubmVsc11dID0gMSwgdGhlbiB0aGUgb3V0cHV0IGlzIGEgc2luZ2xlIG51bWJlclxuICAgICAqIHJlcHJlc2VudGluZyB0aGUgdmFsdWUgb2YgdGhlIGlucHV0IHNpZ25hbC4gV2hlbiBbW2NoYW5uZWxzXV0gPiAxLFxuICAgICAqIHRoZW4gZWFjaCBjaGFubmVsIGlzIHJldHVybmVkIGFzIGEgdmFsdWUgaW4gYSBudW1iZXIgYXJyYXkuXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IGFWYWx1ZXMgPSB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuICAgICAgICBjb25zdCBjaGFubmVsVmFsdWVzID0gdGhpcy5jaGFubmVscyA9PT0gMSA/IFthVmFsdWVzXSA6IGFWYWx1ZXM7XG4gICAgICAgIGNvbnN0IHZhbHMgPSBjaGFubmVsVmFsdWVzLm1hcCh2YWx1ZXMgPT4ge1xuICAgICAgICAgICAgY29uc3QgdG90YWxTcXVhcmVkID0gdmFsdWVzLnJlZHVjZSgodG90YWwsIGN1cnJlbnQpID0+IHRvdGFsICsgY3VycmVudCAqIGN1cnJlbnQsIDApO1xuICAgICAgICAgICAgY29uc3Qgcm1zID0gTWF0aC5zcXJ0KHRvdGFsU3F1YXJlZCAvIHZhbHVlcy5sZW5ndGgpO1xuICAgICAgICAgICAgLy8gdGhlIHJtcyBjYW4gb25seSBmYWxsIGF0IHRoZSByYXRlIG9mIHRoZSBzbW9vdGhpbmdcbiAgICAgICAgICAgIC8vIGJ1dCBjYW4ganVtcCB1cCBpbnN0YW50bHlcbiAgICAgICAgICAgIHRoaXMuX3JtcyA9IE1hdGgubWF4KHJtcywgdGhpcy5fcm1zICogdGhpcy5zbW9vdGhpbmcpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubm9ybWFsUmFuZ2UgPyB0aGlzLl9ybXMgOiBnYWluVG9EYih0aGlzLl9ybXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWxzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBjaGFubmVscyBvZiBhbmFseXNpcy5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5jaGFubmVscztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbmFseXNlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1ldGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRiVG9HYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGZyZXF1ZW5jeSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlIHVzaW5nIGEgZmFzdCBGb3VyaWVyIHRyYW5zZm9ybS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZGVCBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZGVC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGRlRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZGVC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pO1xuICAgICAgICB0aGlzLm5vcm1hbFJhbmdlID0gb3B0aW9ucy5ub3JtYWxSYW5nZTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwiZmZ0XCI7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG5vcm1hbFJhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgIHNpemU6IDEwMjQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuOCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGN1cnJlbnQgZnJlcXVlbmN5IGRhdGEgZnJvbSB0aGUgY29ubmVjdGVkIGF1ZGlvIHNvdXJjZS5cbiAgICAgKiBSZXR1cm5zIHRoZSBmcmVxdWVuY3kgZGF0YSBvZiBsZW5ndGggW1tzaXplXV0gYXMgYSBGbG9hdDMyQXJyYXkgb2YgZGVjaWJlbCB2YWx1ZXMuXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIHJldHVybiB2YWx1ZXMubWFwKHYgPT4gdGhpcy5ub3JtYWxSYW5nZSA/IGRiVG9HYWluKHYpIDogdik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGFuYWx5c2lzLiBUaGlzIG11c3QgYmUgYSBwb3dlciBvZiB0d28gaW4gdGhlIHJhbmdlIDE2IHRvIDE2Mzg0LlxuICAgICAqIERldGVybWluZXMgdGhlIHNpemUgb2YgdGhlIGFycmF5IHJldHVybmVkIGJ5IFtbZ2V0VmFsdWVdXSAoaS5lLiB0aGUgbnVtYmVyIG9mXG4gICAgICogZnJlcXVlbmN5IGJpbnMpLiBMYXJnZSBGRlQgc2l6ZXMgbWF5IGJlIGNvc3RseSB0byBjb21wdXRlLlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc2l6ZTtcbiAgICB9XG4gICAgc2V0IHNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gc2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogMCByZXByZXNlbnRzIG5vIHRpbWUgYXZlcmFnaW5nIHdpdGggdGhlIGxhc3QgYW5hbHlzaXMgZnJhbWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyh2YWwpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBmcmVxdWVuY3kgdmFsdWUgaW4gaGVydHogb2YgZWFjaCBvZiB0aGUgaW5kaWNlcyBvZiB0aGUgRkZUJ3MgW1tnZXRWYWx1ZV1dIHJlc3BvbnNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmZ0ID0gbmV3IFRvbmUuRkZUKDMyKTtcbiAgICAgKiBjb25zb2xlLmxvZyhbMCwgMSwgMiwgMywgNF0ubWFwKGluZGV4ID0+IGZmdC5nZXRGcmVxdWVuY3lPZkluZGV4KGluZGV4KSkpO1xuICAgICAqL1xuICAgIGdldEZyZXF1ZW5jeU9mSW5kZXgoaW5kZXgpIHtcbiAgICAgICAgYXNzZXJ0KDAgPD0gaW5kZXggJiYgaW5kZXggPCB0aGlzLnNpemUsIGBpbmRleCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwIGFuZCBsZXNzIHRoYW4gJHt0aGlzLnNpemV9YCk7XG4gICAgICAgIHJldHVybiBpbmRleCAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gKHRoaXMuc2l6ZSAqIDIpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZGVC5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuLyoqXG4gKiBEQ01ldGVyIGdldHMgdGhlIHJhdyB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsIGF0IHRoZSBjdXJyZW50IHRpbWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuRENNZXRlcigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCk7XG4gKiBtaWMub3BlbigpO1xuICogLy8gY29ubmVjdCBtaWMgdG8gdGhlIG1ldGVyXG4gKiBtaWMuY29ubmVjdChtZXRlcik7XG4gKiAvLyB0aGUgY3VycmVudCBsZXZlbCBvZiB0aGUgbWljXG4gKiBjb25zdCBsZXZlbCA9IG1ldGVyLmdldFZhbHVlKCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBEQ01ldGVyIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRENNZXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEQ01ldGVyXCI7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnR5cGUgPSBcIndhdmVmb3JtXCI7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSAyNTY7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgc2lnbmFsIHZhbHVlIG9mIHRoZSBpbmNvbWluZyBzaWduYWxcbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuICAgICAgICByZXR1cm4gdmFsdWVbMF07XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RENNZXRlci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgd2F2ZWZvcm0gZGF0YSBvZiB0aGUgY29ubmVjdGVkIGF1ZGlvIHNvdXJjZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFdhdmVmb3JtIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZWZvcm0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiV2F2ZWZvcm1cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFdhdmVmb3JtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnR5cGUgPSBcIndhdmVmb3JtXCI7XG4gICAgICAgIHRoaXMuc2l6ZSA9IG9wdGlvbnMuc2l6ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNZXRlckJhc2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgd2F2ZWZvcm0gZm9yIHRoZSBjdXJyZW50IHRpbWUgYXMgYSBGbG9hdDMyQXJyYXkgd2hlcmUgZWFjaCB2YWx1ZSBpbiB0aGUgYXJyYXlcbiAgICAgKiByZXByZXNlbnRzIGEgc2FtcGxlIGluIHRoZSB3YXZlZm9ybS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGFuYWx5c2lzLiBUaGlzIG11c3QgYmUgYSBwb3dlciBvZiB0d28gaW4gdGhlIHJhbmdlIDE2IHRvIDE2Mzg0LlxuICAgICAqIERldGVybWluZXMgdGhlIHNpemUgb2YgdGhlIGFycmF5IHJldHVybmVkIGJ5IFtbZ2V0VmFsdWVdXS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLnNpemU7XG4gICAgfVxuICAgIHNldCBzaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc2l6ZSA9IHNpemU7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9V2F2ZWZvcm0uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIFNvbG8gbGV0cyB5b3UgaXNvbGF0ZSBhIHNwZWNpZmljIGF1ZGlvIHN0cmVhbS4gV2hlbiBhbiBpbnN0YW5jZSBpcyBzZXQgdG8gYHNvbG89dHJ1ZWAsXG4gKiBpdCB3aWxsIG11dGUgYWxsIG90aGVyIGluc3RhbmNlcyBvZiBTb2xvLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNvbG9BID0gbmV3IFRvbmUuU29sbygpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zY0EgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKFwiQzRcIiwgXCJzYXd0b290aFwiKS5jb25uZWN0KHNvbG9BKTtcbiAqIGNvbnN0IHNvbG9CID0gbmV3IFRvbmUuU29sbygpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zY0IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKFwiRTRcIiwgXCJzcXVhcmVcIikuY29ubmVjdChzb2xvQik7XG4gKiBzb2xvQS5zb2xvID0gdHJ1ZTtcbiAqIC8vIG5vIGF1ZGlvIHdpbGwgcGFzcyB0aHJvdWdoIHNvbG9CXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTb2xvIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNvbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzb2xvXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU29sb1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU29sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNvbG9cIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIVNvbG8uX2FsbFNvbG9zLmhhcyh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICBTb2xvLl9hbGxTb2xvcy5zZXQodGhpcy5jb250ZXh0LCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmFkZCh0aGlzKTtcbiAgICAgICAgLy8gc2V0IGluaXRpYWxseVxuICAgICAgICB0aGlzLnNvbG8gPSBvcHRpb25zLnNvbG87XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzb2xvOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElzb2xhdGVzIHRoaXMgaW5zdGFuY2UgYW5kIG11dGVzIGFsbCBvdGhlciBpbnN0YW5jZXMgb2YgU29sby5cbiAgICAgKiBPbmx5IG9uZSBpbnN0YW5jZSBjYW4gYmUgc29sb2VkIGF0IGEgdGltZS4gQSBzb2xvZWRcbiAgICAgKiBpbnN0YW5jZSB3aWxsIHJlcG9ydCBgc29sbz1mYWxzZWAgd2hlbiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZC5cbiAgICAgKi9cbiAgICBnZXQgc29sbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lzU29sb2VkKCk7XG4gICAgfVxuICAgIHNldCBzb2xvKHNvbG8pIHtcbiAgICAgICAgaWYgKHNvbG8pIHtcbiAgICAgICAgICAgIHRoaXMuX2FkZFNvbG8oKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3JlbW92ZVNvbG8oKTtcbiAgICAgICAgfVxuICAgICAgICBTb2xvLl9hbGxTb2xvcy5nZXQodGhpcy5jb250ZXh0KS5mb3JFYWNoKGluc3RhbmNlID0+IGluc3RhbmNlLl91cGRhdGVTb2xvKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY3VycmVudCBpbnN0YW5jZSBpcyBtdXRlZCwgaS5lLiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZFxuICAgICAqL1xuICAgIGdldCBtdXRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9PT0gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIHRoaXMgdG8gdGhlIHNvbG9lZCBhcnJheVxuICAgICAqL1xuICAgIF9hZGRTb2xvKCkge1xuICAgICAgICBpZiAoIVNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgU29sby5fc29sb2VkLnNldCh0aGlzLmNvbnRleHQsIG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmFkZCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoaXMgZnJvbSB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX3JlbW92ZVNvbG8oKSB7XG4gICAgICAgIGlmIChTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkpIHtcbiAgICAgICAgICAgIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5kZWxldGUodGhpcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSXMgdGhpcyBvbiB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX2lzU29sb2VkKCkge1xuICAgICAgICByZXR1cm4gU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpICYmIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5oYXModGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiBubyBvbmUgaXMgc29sb2VkXG4gICAgICovXG4gICAgX25vU29sb3MoKSB7XG4gICAgICAgIC8vIGVpdGhlciBkb2VzIG5vdCBoYXZlIGFueSBzb2xvZWQgYWRkZWRcbiAgICAgICAgcmV0dXJuICFTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgfHxcbiAgICAgICAgICAgIC8vIG9yIGhhcyBhIHNvbG8gc2V0IGJ1dCBkb2Vzbid0IGluY2x1ZGUgYW55IGl0ZW1zXG4gICAgICAgICAgICAoU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpICYmIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5zaXplID09PSAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU29sbyB0aGUgY3VycmVudCBpbnN0YW5jZSBhbmQgdW5zb2xvIGFsbCBvdGhlciBpbnN0YW5jZXMuXG4gICAgICovXG4gICAgX3VwZGF0ZVNvbG8oKSB7XG4gICAgICAgIGlmICh0aGlzLl9pc1NvbG9lZCgpKSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX25vU29sb3MoKSkge1xuICAgICAgICAgICAgLy8gbm8gb25lIGlzIHNvbG9lZFxuICAgICAgICAgICAgdGhpcy5pbnB1dC5nYWluLnZhbHVlID0gMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBTb2xvLl9hbGxTb2xvcy5nZXQodGhpcy5jb250ZXh0KS5kZWxldGUodGhpcyk7XG4gICAgICAgIHRoaXMuX3JlbW92ZVNvbG8oKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBIb2xkIGFsbCBvZiB0aGUgc29sbydlZCB0cmFja3MgYmVsb25naW5nIHRvIGEgc3BlY2lmaWMgY29udGV4dFxuICovXG5Tb2xvLl9hbGxTb2xvcyA9IG5ldyBNYXAoKTtcbi8qKlxuICogSG9sZCB0aGUgY3VycmVudGx5IHNvbG8nZWQgaW5zdGFuY2UocylcbiAqL1xuU29sby5fc29sb2VkID0gbmV3IE1hcCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U29sby5qcy5tYXAiLCJpbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBhbm5lciB9IGZyb20gXCIuL1Bhbm5lclwiO1xuaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4vVm9sdW1lXCI7XG4vKipcbiAqIFBhblZvbCBpcyBhIFRvbmUuUGFubmVyIGFuZCBUb25lLlZvbHVtZSBpbiBvbmUuXG4gKiBAZXhhbXBsZVxuICogLy8gcGFuIHRoZSBpbmNvbWluZyBzaWduYWwgbGVmdCBhbmQgZHJvcCB0aGUgdm9sdW1lXG4gKiBjb25zdCBwYW5Wb2wgPSBuZXcgVG9uZS5QYW5Wb2woLTAuMjUsIC0xMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QocGFuVm9sKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGFuVm9sIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhblZvbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhblwiLCBcInZvbHVtZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhblZvbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFuVm9sLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IG5ldyBQYW5uZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFuOiBvcHRpb25zLnBhbixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBhbiA9IHRoaXMuX3Bhbm5lci5wYW47XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29ubmVjdCh0aGlzLl92b2x1bWUpO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInBhblwiLCBcInZvbHVtZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUvdW5tdXRlIHRoZSB2b2x1bWVcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBhbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFuVm9sLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU29sbyB9IGZyb20gXCIuL1NvbG9cIjtcbmltcG9ydCB7IFBhblZvbCB9IGZyb20gXCIuL1BhblZvbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBDaGFubmVsIHByb3ZpZGVzIGEgY2hhbm5lbCBzdHJpcCBpbnRlcmZhY2Ugd2l0aCB2b2x1bWUsIHBhbiwgc29sbyBhbmQgbXV0ZSBjb250cm9scy5cbiAqIFNlZSBbW1BhblZvbF1dIGFuZCBbW1NvbG9dXVxuICogQGV4YW1wbGVcbiAqIC8vIHBhbiB0aGUgaW5jb21pbmcgc2lnbmFsIGxlZnQgYW5kIGRyb3AgdGhlIHZvbHVtZSAxMmRiXG4gKiBjb25zdCBjaGFubmVsID0gbmV3IFRvbmUuQ2hhbm5lbCgtMC4yNSwgLTEyKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENoYW5uZWwgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hhbm5lbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiLCBcInBhblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNoYW5uZWxcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENoYW5uZWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIiwgXCJwYW5cIl0pO1xuICAgICAgICB0aGlzLl9zb2xvID0gdGhpcy5pbnB1dCA9IG5ldyBTb2xvKHtcbiAgICAgICAgICAgIHNvbG86IG9wdGlvbnMuc29sbyxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BhblZvbCA9IHRoaXMub3V0cHV0ID0gbmV3IFBhblZvbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYW46IG9wdGlvbnMucGFuLFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgICAgIG11dGU6IG9wdGlvbnMubXV0ZSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGFuID0gdGhpcy5fcGFuVm9sLnBhbjtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl9wYW5Wb2wudm9sdW1lO1xuICAgICAgICB0aGlzLl9zb2xvLmNvbm5lY3QodGhpcy5fcGFuVm9sKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgc29sbzogZmFsc2UsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTb2xvL3Vuc29sbyB0aGUgY2hhbm5lbC4gU29sb2luZyBpcyBvbmx5IHJlbGF0aXZlIHRvIG90aGVyIFtbQ2hhbm5lbHNdXSBhbmQgW1tTb2xvXV0gaW5zdGFuY2VzXG4gICAgICovXG4gICAgZ2V0IHNvbG8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb2xvLnNvbG87XG4gICAgfVxuICAgIHNldCBzb2xvKHNvbG8pIHtcbiAgICAgICAgdGhpcy5fc29sby5zb2xvID0gc29sbztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGN1cnJlbnQgaW5zdGFuY2UgaXMgbXV0ZWQsIGkuZS4gYW5vdGhlciBpbnN0YW5jZSBpcyBzb2xvZWQsXG4gICAgICogb3IgdGhlIGNoYW5uZWwgaXMgbXV0ZWRcbiAgICAgKi9cbiAgICBnZXQgbXV0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb2xvLm11dGVkIHx8IHRoaXMubXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZS91bm11dGUgdGhlIHZvbHVtZVxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFuVm9sLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fcGFuVm9sLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGdhaW4gbm9kZSBiZWxvbmdpbmcgdG8gdGhlIGJ1cyBuYW1lLiBDcmVhdGUgaXQgaWZcbiAgICAgKiBpdCBkb2Vzbid0IGV4aXN0XG4gICAgICogQHBhcmFtIG5hbWUgVGhlIGJ1cyBuYW1lXG4gICAgICovXG4gICAgX2dldEJ1cyhuYW1lKSB7XG4gICAgICAgIGlmICghQ2hhbm5lbC5idXNlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgIENoYW5uZWwuYnVzZXMuc2V0KG5hbWUsIG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQ2hhbm5lbC5idXNlcy5nZXQobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlbmQgYXVkaW8gdG8gYW5vdGhlciBjaGFubmVsIHVzaW5nIGEgc3RyaW5nLiBgc2VuZGAgaXMgYSBsb3QgbGlrZVxuICAgICAqIFtbY29ubmVjdF1dLCBleGNlcHQgaXQgdXNlcyBhIHN0cmluZyBpbnN0ZWFkIG9mIGFuIG9iamVjdC4gVGhpcyBjYW5cbiAgICAgKiBiZSB1c2VmdWwgaW4gbGFyZ2UgYXBwbGljYXRpb25zIHRvIGRlY291cGxlIHNlY3Rpb25zIHNpbmNlIFtbc2VuZF1dXG4gICAgICogYW5kIFtbcmVjZWl2ZV1dIGNhbiBiZSBpbnZva2VkIHNlcGFyYXRlbHkgaW4gb3JkZXIgdG8gY29ubmVjdCBhbiBvYmplY3RcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgY2hhbm5lbCBuYW1lIHRvIHNlbmQgdGhlIGF1ZGlvXG4gICAgICogQHBhcmFtIHZvbHVtZSBUaGUgYW1vdW50IG9mIHRoZSBzaWduYWwgdG8gc2VuZC5cbiAgICAgKiBcdERlZmF1bHRzIHRvIDBkYiwgaS5lLiBzZW5kIHRoZSBlbnRpcmUgc2lnbmFsXG4gICAgICogQHJldHVybnMgUmV0dXJucyB0aGUgZ2FpbiBub2RlIG9mIHRoaXMgY29ubmVjdGlvbi5cbiAgICAgKi9cbiAgICBzZW5kKG5hbWUsIHZvbHVtZSA9IDApIHtcbiAgICAgICAgY29uc3QgYnVzID0gdGhpcy5fZ2V0QnVzKG5hbWUpO1xuICAgICAgICBjb25zdCBzZW5kS25vYiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBnYWluOiB2b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNvbm5lY3Qoc2VuZEtub2IpO1xuICAgICAgICBzZW5kS25vYi5jb25uZWN0KGJ1cyk7XG4gICAgICAgIHJldHVybiBzZW5kS25vYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVjZWl2ZSBhdWRpbyBmcm9tIGEgY2hhbm5lbCB3aGljaCB3YXMgY29ubmVjdGVkIHdpdGggW1tzZW5kXV0uXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIGNoYW5uZWwgbmFtZSB0byByZWNlaXZlIGF1ZGlvIGZyb20uXG4gICAgICovXG4gICAgcmVjZWl2ZShuYW1lKSB7XG4gICAgICAgIGNvbnN0IGJ1cyA9IHRoaXMuX2dldEJ1cyhuYW1lKTtcbiAgICAgICAgYnVzLmNvbm5lY3QodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhblZvbC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zb2xvLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBTdG9yZSB0aGUgc2VuZC9yZWNlaXZlIGNoYW5uZWxzIGJ5IG5hbWUuXG4gKi9cbkNoYW5uZWwuYnVzZXMgPSBuZXcgTWFwKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaGFubmVsLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi9NZXJnZVwiO1xuLyoqXG4gKiBNb25vIGNvZXJjZXMgdGhlIGluY29taW5nIG1vbm8gb3Igc3RlcmVvIHNpZ25hbCBpbnRvIGEgbW9ubyBzaWduYWxcbiAqIHdoZXJlIGJvdGggbGVmdCBhbmQgcmlnaHQgY2hhbm5lbHMgaGF2ZSB0aGUgc2FtZSB2YWx1ZS4gVGhpcyBjYW4gYmUgdXNlZnVsXG4gKiBmb3IgW3N0ZXJlbyBpbWFnaW5nXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TdGVyZW9faW1hZ2luZykuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNb25vIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTW9ub1wiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlID0gdGhpcy5vdXRwdXQgPSBuZXcgTWVyZ2Uoe1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDEpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vbm8uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSwgd3JpdGFibGUgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9maWx0ZXIvRmlsdGVyXCI7XG4vKipcbiAqIFNwbGl0IHRoZSBpbmNvbWluZyBzaWduYWwgaW50byB0aHJlZSBiYW5kcyAobG93LCBtaWQsIGhpZ2gpXG4gKiB3aXRoIHR3byBjcm9zc292ZXIgZnJlcXVlbmN5IGNvbnRyb2xzLlxuICogYGBgXG4gKiAgICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgKy0+IGlucHV0IDwgbG93RnJlcXVlbmN5ICstLS0tLS0tLS0tLS0tLS0tLS0+IGxvd1xuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgIHxcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogaW5wdXQgLS0tKy0+IGxvd0ZyZXF1ZW5jeSA8IGlucHV0IDwgaGlnaEZyZXF1ZW5jeSArLS0+IG1pZFxuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICB8XG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgICstPiBoaWdoRnJlcXVlbmN5IDwgaW5wdXQgKy0tLS0tLS0tLS0tLS0tLS0tPiBoaWdoXG4gKiAgICAgICAgICAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTXVsdGliYW5kU3BsaXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dGcmVxdWVuY3lcIiwgXCJoaWdoRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGliYW5kU3BsaXRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBpbnB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogbm8gb3V0cHV0IG5vZGUsIHVzZSBlaXRoZXIgbG93LCBtaWQgb3IgaGlnaCBvdXRwdXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb3cgYmFuZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubG93ID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbG93ZXIgZmlsdGVyIG9mIHRoZSBtaWQgYmFuZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG93TWlkRmlsdGVyID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImhpZ2hwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1pZCBiYW5kIG91dHB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubWlkID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaGlnaCBiYW5kIG91dHB1dC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaGlnaCA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgdHlwZTogXCJoaWdocGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmxvdywgdGhpcy5taWQsIHRoaXMuaGlnaF07XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5sb3dGcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0LmZhbih0aGlzLmxvdywgdGhpcy5oaWdoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9sb3dNaWRGaWx0ZXIsIHRoaXMubWlkKTtcbiAgICAgICAgLy8gdGhlIGZyZXF1ZW5jeSBjb250cm9sIHNpZ25hbFxuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5mYW4odGhpcy5sb3cuZnJlcXVlbmN5LCB0aGlzLl9sb3dNaWRGaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmZhbih0aGlzLm1pZC5mcmVxdWVuY3ksIHRoaXMuaGlnaC5mcmVxdWVuY3kpO1xuICAgICAgICAvLyB0aGUgUSB2YWx1ZVxuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLmxvdy5RKTtcbiAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5fbG93TWlkRmlsdGVyLlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLm1pZC5RKTtcbiAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5oaWdoLlEpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJoaWdoXCIsIFwibWlkXCIsIFwibG93XCIsIFwiaGlnaEZyZXF1ZW5jeVwiLCBcImxvd0ZyZXF1ZW5jeVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogMjUwMCxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogNDAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBbXCJoaWdoXCIsIFwibWlkXCIsIFwibG93XCIsIFwiaGlnaEZyZXF1ZW5jeVwiLCBcImxvd0ZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93TWlkRmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2guZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU11bHRpYmFuZFNwbGl0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuL1BhcmFtXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuL0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuLyoqXG4gKiBUb25lLkxpc3RlbmVyIGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgQXVkaW9MaXN0ZW5lci4gTGlzdGVuZXIgY29tYmluZWRcbiAqIHdpdGggW1tQYW5uZXIzRF1dIG1ha2VzIHVwIHRoZSBXZWIgQXVkaW8gQVBJJ3MgM0QgcGFubmluZyBzeXN0ZW0uIFBhbm5lcjNEIGFsbG93cyB5b3VcbiAqIHRvIHBsYWNlIHNvdW5kcyBpbiAzRCBhbmQgTGlzdGVuZXIgYWxsb3dzIHlvdSB0byBuYXZpZ2F0ZSB0aGUgM0Qgc291bmQgZW52aXJvbm1lbnQgZnJvbVxuICogYSBmaXJzdC1wZXJzb24gcGVyc3BlY3RpdmUuIFRoZXJlIGlzIG9ubHkgb25lIGxpc3RlbmVyIHBlciBhdWRpbyBjb250ZXh0LlxuICovXG5leHBvcnQgY2xhc3MgTGlzdGVuZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMaXN0ZW5lclwiO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIucG9zaXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5wb3NpdGlvblosXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcndhcmRYID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5mb3J3YXJkWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIuZm9yd2FyZFosXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIudXBYLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cFkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnVwWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBaID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci51cFosXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcG9zaXRpb25YOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25ZOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25aOiAwLFxuICAgICAgICAgICAgZm9yd2FyZFg6IDAsXG4gICAgICAgICAgICBmb3J3YXJkWTogMCxcbiAgICAgICAgICAgIGZvcndhcmRaOiAtMSxcbiAgICAgICAgICAgIHVwWDogMCxcbiAgICAgICAgICAgIHVwWTogMSxcbiAgICAgICAgICAgIHVwWjogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZvcndhcmRaLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51cFguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVwWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudXBaLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5saXN0ZW5lciA9IG5ldyBMaXN0ZW5lcih7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQubGlzdGVuZXIuZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1MaXN0ZW5lci5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IFwiLi4vLi4vY29yZS9jb250ZXh0L0xpc3RlbmVyXCI7XG4vKipcbiAqIEEgc3BhdGlhbGl6ZWQgcGFubmVyIG5vZGUgd2hpY2ggc3VwcG9ydHMgZXF1YWxwb3dlciBvciBIUlRGIHBhbm5pbmcuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5uZXIzRCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIzRC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBvc2l0aW9uWFwiLCBcInBvc2l0aW9uWVwiLCBcInBvc2l0aW9uWlwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhbm5lcjNEXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIzRC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBvc2l0aW9uWFwiLCBcInBvc2l0aW9uWVwiLCBcInBvc2l0aW9uWlwiXSk7XG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICAgICAgLy8gc2V0IHNvbWUgdmFsdWVzXG4gICAgICAgIHRoaXMucGFubmluZ01vZGVsID0gb3B0aW9ucy5wYW5uaW5nTW9kZWw7XG4gICAgICAgIHRoaXMubWF4RGlzdGFuY2UgPSBvcHRpb25zLm1heERpc3RhbmNlO1xuICAgICAgICB0aGlzLmRpc3RhbmNlTW9kZWwgPSBvcHRpb25zLmRpc3RhbmNlTW9kZWw7XG4gICAgICAgIHRoaXMuY29uZU91dGVyR2FpbiA9IG9wdGlvbnMuY29uZU91dGVyR2FpbjtcbiAgICAgICAgdGhpcy5jb25lT3V0ZXJBbmdsZSA9IG9wdGlvbnMuY29uZU91dGVyQW5nbGU7XG4gICAgICAgIHRoaXMuY29uZUlubmVyQW5nbGUgPSBvcHRpb25zLmNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB0aGlzLnJlZkRpc3RhbmNlID0gb3B0aW9ucy5yZWZEaXN0YW5jZTtcbiAgICAgICAgdGhpcy5yb2xsb2ZmRmFjdG9yID0gb3B0aW9ucy5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBvc2l0aW9uWCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBvc2l0aW9uWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucG9zaXRpb25ZLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucG9zaXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wb3NpdGlvblosXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wb3NpdGlvblosXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLm9yaWVudGF0aW9uWCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9yaWVudGF0aW9uWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIub3JpZW50YXRpb25ZLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub3JpZW50YXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblosXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vcmllbnRhdGlvblosXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29uZUlubmVyQW5nbGU6IDM2MCxcbiAgICAgICAgICAgIGNvbmVPdXRlckFuZ2xlOiAzNjAsXG4gICAgICAgICAgICBjb25lT3V0ZXJHYWluOiAwLFxuICAgICAgICAgICAgZGlzdGFuY2VNb2RlbDogXCJpbnZlcnNlXCIsXG4gICAgICAgICAgICBtYXhEaXN0YW5jZTogMTAwMDAsXG4gICAgICAgICAgICBvcmllbnRhdGlvblg6IDAsXG4gICAgICAgICAgICBvcmllbnRhdGlvblk6IDAsXG4gICAgICAgICAgICBvcmllbnRhdGlvblo6IDAsXG4gICAgICAgICAgICBwYW5uaW5nTW9kZWw6IFwiZXF1YWxwb3dlclwiLFxuICAgICAgICAgICAgcG9zaXRpb25YOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25ZOiAwLFxuICAgICAgICAgICAgcG9zaXRpb25aOiAwLFxuICAgICAgICAgICAgcmVmRGlzdGFuY2U6IDEsXG4gICAgICAgICAgICByb2xsb2ZmRmFjdG9yOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgcG9zaXRpb24gb2YgdGhlIHNvdXJjZSBpbiAzZCBzcGFjZS5cbiAgICAgKi9cbiAgICBzZXRQb3NpdGlvbih4LCB5LCB6KSB7XG4gICAgICAgIHRoaXMucG9zaXRpb25YLnZhbHVlID0geDtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkudmFsdWUgPSB5O1xuICAgICAgICB0aGlzLnBvc2l0aW9uWi52YWx1ZSA9IHo7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBvcmllbnRhdGlvbiBvZiB0aGUgc291cmNlIGluIDNkIHNwYWNlLlxuICAgICAqL1xuICAgIHNldE9yaWVudGF0aW9uKHgsIHksIHopIHtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblgudmFsdWUgPSB4O1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWS52YWx1ZSA9IHk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25aLnZhbHVlID0gejtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYW5uaW5nIG1vZGVsLiBFaXRoZXIgXCJlcXVhbHBvd2VyXCIgb3IgXCJIUlRGXCIuXG4gICAgICovXG4gICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5wYW5uaW5nTW9kZWw7XG4gICAgfVxuICAgIHNldCBwYW5uaW5nTW9kZWwodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5wYW5uaW5nTW9kZWwgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcmVmZXJlbmNlIGRpc3RhbmNlIGZvciByZWR1Y2luZyB2b2x1bWUgYXMgc291cmNlIG1vdmUgZnVydGhlciBmcm9tIHRoZSBsaXN0ZW5lclxuICAgICAqL1xuICAgIGdldCByZWZEaXN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5yZWZEaXN0YW5jZTtcbiAgICB9XG4gICAgc2V0IHJlZkRpc3RhbmNlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIucmVmRGlzdGFuY2UgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlc2NyaWJlcyBob3cgcXVpY2tseSB0aGUgdm9sdW1lIGlzIHJlZHVjZWQgYXMgc291cmNlIG1vdmVzIGF3YXkgZnJvbSBsaXN0ZW5lci5cbiAgICAgKi9cbiAgICBnZXQgcm9sbG9mZkZhY3RvcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5yb2xsb2ZmRmFjdG9yO1xuICAgIH1cbiAgICBzZXQgcm9sbG9mZkZhY3Rvcih2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLnJvbGxvZmZGYWN0b3IgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkaXN0YW5jZSBtb2RlbCB1c2VkIGJ5LCAgXCJsaW5lYXJcIiwgXCJpbnZlcnNlXCIsIG9yIFwiZXhwb25lbnRpYWxcIi5cbiAgICAgKi9cbiAgICBnZXQgZGlzdGFuY2VNb2RlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5kaXN0YW5jZU1vZGVsO1xuICAgIH1cbiAgICBzZXQgZGlzdGFuY2VNb2RlbCh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc3RhbmNlTW9kZWwgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbmdsZSwgaW4gZGVncmVlcywgaW5zaWRlIG9mIHdoaWNoIHRoZXJlIHdpbGwgYmUgbm8gdm9sdW1lIHJlZHVjdGlvblxuICAgICAqL1xuICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lSW5uZXJBbmdsZTtcbiAgICB9XG4gICAgc2V0IGNvbmVJbm5lckFuZ2xlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29uZUlubmVyQW5nbGUgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbmdsZSwgaW4gZGVncmVlcywgb3V0c2lkZSBvZiB3aGljaCB0aGUgdm9sdW1lIHdpbGwgYmUgcmVkdWNlZFxuICAgICAqIHRvIGEgY29uc3RhbnQgdmFsdWUgb2YgY29uZU91dGVyR2FpblxuICAgICAqL1xuICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJBbmdsZTtcbiAgICB9XG4gICAgc2V0IGNvbmVPdXRlckFuZ2xlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29uZU91dGVyQW5nbGUgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBnYWluIG91dHNpZGUgb2YgdGhlIGNvbmVPdXRlckFuZ2xlXG4gICAgICovXG4gICAgZ2V0IGNvbmVPdXRlckdhaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIuY29uZU91dGVyR2FpbjtcbiAgICB9XG4gICAgc2V0IGNvbmVPdXRlckdhaW4odmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJHYWluID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBkaXN0YW5jZSBiZXR3ZWVuIHNvdXJjZSBhbmQgbGlzdGVuZXIsXG4gICAgICogYWZ0ZXIgd2hpY2ggdGhlIHZvbHVtZSB3aWxsIG5vdCBiZSByZWR1Y2VkIGFueSBmdXJ0aGVyLlxuICAgICAqL1xuICAgIGdldCBtYXhEaXN0YW5jZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5tYXhEaXN0YW5jZTtcbiAgICB9XG4gICAgc2V0IG1heERpc3RhbmNlKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIubWF4RGlzdGFuY2UgPSB2YWw7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25aLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFubmVyM0QuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyB0aGVXaW5kb3cgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIEEgd3JhcHBlciBhcm91bmQgdGhlIE1lZGlhUmVjb3JkZXIgQVBJLiBVbmxpa2UgdGhlIHJlc3Qgb2YgVG9uZS5qcywgdGhpcyBtb2R1bGUgZG9lcyBub3Qgb2ZmZXJcbiAqIGFueSBzYW1wbGUtYWNjdXJhdGUgc2NoZWR1bGluZyBiZWNhdXNlIGl0IGlzIG5vdCBhIGZlYXR1cmUgb2YgdGhlIE1lZGlhUmVjb3JkZXIgQVBJLlxuICogVGhpcyBpcyBvbmx5IG5hdGl2ZWx5IHN1cHBvcnRlZCBpbiBDaHJvbWUgYW5kIEZpcmVmb3guXG4gKiBGb3IgYSBjcm9zcy1icm93c2VyIHNoaW0sIGluc3RhbGwgKGF1ZGlvLXJlY29yZGVyLXBvbHlmaWxsKVtodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9hdWRpby1yZWNvcmRlci1wb2x5ZmlsbF0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcmVjb3JkZXIgPSBuZXcgVG9uZS5SZWNvcmRlcigpO1xuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLmNvbm5lY3QocmVjb3JkZXIpO1xuICogLy8gc3RhcnQgcmVjb3JkaW5nXG4gKiByZWNvcmRlci5zdGFydCgpO1xuICogLy8gZ2VuZXJhdGUgYSBmZXcgbm90ZXNcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzNcIiwgMC41KTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgMC41LCBcIisxXCIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNVwiLCAwLjUsIFwiKzJcIik7XG4gKiAvLyB3YWl0IGZvciB0aGUgbm90ZXMgdG8gZW5kIGFuZCBzdG9wIHRoZSByZWNvcmRpbmdcbiAqIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICogXHQvLyB0aGUgcmVjb3JkZWQgYXVkaW8gaXMgcmV0dXJuZWQgYXMgYSBibG9iXG4gKiBcdGNvbnN0IHJlY29yZGluZyA9IGF3YWl0IHJlY29yZGVyLnN0b3AoKTtcbiAqIFx0Ly8gZG93bmxvYWQgdGhlIHJlY29yZGluZyBieSBjcmVhdGluZyBhbiBhbmNob3IgZWxlbWVudCBhbmQgYmxvYiB1cmxcbiAqIFx0Y29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChyZWNvcmRpbmcpO1xuICogXHRjb25zdCBhbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKTtcbiAqIFx0YW5jaG9yLmRvd25sb2FkID0gXCJyZWNvcmRpbmcud2VibVwiO1xuICogXHRhbmNob3IuaHJlZiA9IHVybDtcbiAqIFx0YW5jaG9yLmNsaWNrKCk7XG4gKiB9LCA0MDAwKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFJlY29yZGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFJlY29yZGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlJlY29yZGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhSZWNvcmRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQoUmVjb3JkZXIuc3VwcG9ydGVkLCBcIk1lZGlhIFJlY29yZGVyIEFQSSBpcyBub3QgYXZhaWxhYmxlXCIpO1xuICAgICAgICB0aGlzLl9zdHJlYW0gPSB0aGlzLmNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fc3RyZWFtKTtcbiAgICAgICAgdGhpcy5fcmVjb3JkZXIgPSBuZXcgTWVkaWFSZWNvcmRlcih0aGlzLl9zdHJlYW0uc3RyZWFtLCB7XG4gICAgICAgICAgICBtaW1lVHlwZTogb3B0aW9ucy5taW1lVHlwZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWltZSB0eXBlIGlzIHRoZSBmb3JtYXQgdGhhdCB0aGUgYXVkaW8gaXMgZW5jb2RlZCBpbi4gRm9yIENocm9tZVxuICAgICAqIHRoYXQgaXMgdHlwaWNhbGx5IHdlYm0gZW5jb2RlZCBhcyBcInZvcmJpc1wiLlxuICAgICAqL1xuICAgIGdldCBtaW1lVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JlY29yZGVyLm1pbWVUeXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUZXN0IGlmIHlvdXIgcGxhdGZvcm0gc3VwcG9ydHMgdGhlIE1lZGlhIFJlY29yZGVyIEFQSS4gSWYgaXQncyBub3QgYXZhaWxhYmxlLFxuICAgICAqIHRyeSBpbnN0YWxsaW5nIHRoaXMgKHBvbHlmaWxsKVtodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9hdWRpby1yZWNvcmRlci1wb2x5ZmlsbF0uXG4gICAgICovXG4gICAgc3RhdGljIGdldCBzdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGVXaW5kb3cgIT09IG51bGwgJiYgUmVmbGVjdC5oYXModGhlV2luZG93LCBcIk1lZGlhUmVjb3JkZXJcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIFJlY29yZGVyLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiIG9yIFwicGF1c2VkXCJcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9yZWNvcmRlci5zdGF0ZSA9PT0gXCJpbmFjdGl2ZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fcmVjb3JkZXIuc3RhdGUgPT09IFwicGF1c2VkXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBcInBhdXNlZFwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFwic3RhcnRlZFwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBSZWNvcmRlci4gUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXNcbiAgICAgKiB3aGVuIHRoZSByZWNvcmRlciBoYXMgc3RhcnRlZC5cbiAgICAgKi9cbiAgICBzdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLnN0YXRlICE9PSBcInN0YXJ0ZWRcIiwgXCJSZWNvcmRlciBpcyBhbHJlYWR5IHN0YXJ0ZWRcIik7XG4gICAgICAgICAgICBjb25zdCBzdGFydFByb21pc2UgPSBuZXcgUHJvbWlzZShkb25lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVTdGFydCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInN0YXJ0XCIsIGhhbmRsZVN0YXJ0LCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJzdGFydFwiLCBoYW5kbGVTdGFydCwgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5zdGFydCgpO1xuICAgICAgICAgICAgcmV0dXJuIHlpZWxkIHN0YXJ0UHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHJlY29yZGVyLiBSZXR1cm5zIGEgcHJvbWlzZSB3aXRoIHRoZSByZWNvcmRlZCBjb250ZW50IHVudGlsIHRoaXMgcG9pbnRcbiAgICAgKiBlbmNvZGVkIGFzIFtbbWltZVR5cGVdXVxuICAgICAqL1xuICAgIHN0b3AoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5zdGF0ZSAhPT0gXCJzdG9wcGVkXCIsIFwiUmVjb3JkZXIgaXMgbm90IHN0YXJ0ZWRcIik7XG4gICAgICAgICAgICBjb25zdCBkYXRhUHJvbWlzZSA9IG5ldyBQcm9taXNlKGRvbmUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZURhdGEgPSAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5yZW1vdmVFdmVudExpc3RlbmVyKFwiZGF0YWF2YWlsYWJsZVwiLCBoYW5kbGVEYXRhLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUoZS5kYXRhKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLmFkZEV2ZW50TGlzdGVuZXIoXCJkYXRhYXZhaWxhYmxlXCIsIGhhbmRsZURhdGEsIGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuc3RvcCgpO1xuICAgICAgICAgICAgcmV0dXJuIHlpZWxkIGRhdGFQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUGF1c2UgdGhlIHJlY29yZGVyXG4gICAgICovXG4gICAgcGF1c2UoKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIiwgXCJSZWNvcmRlciBtdXN0IGJlIHN0YXJ0ZWRcIik7XG4gICAgICAgIHRoaXMuX3JlY29yZGVyLnBhdXNlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdHJlYW0uZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1SZWNvcmRlci5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBDb21wcmVzc29yIGlzIGEgdGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgV2ViIEF1ZGlvXG4gKiBbRHluYW1pY3NDb21wcmVzc29yTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtZHluYW1pY3Njb21wcmVzc29ybm9kZS1pbnRlcmZhY2UpLlxuICogQ29tcHJlc3Npb24gcmVkdWNlcyB0aGUgdm9sdW1lIG9mIGxvdWQgc291bmRzIG9yIGFtcGxpZmllcyBxdWlldCBzb3VuZHNcbiAqIGJ5IG5hcnJvd2luZyBvciBcImNvbXByZXNzaW5nXCIgYW4gYXVkaW8gc2lnbmFsJ3MgZHluYW1pYyByYW5nZS5cbiAqIFJlYWQgbW9yZSBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EeW5hbWljX3JhbmdlX2NvbXByZXNzaW9uKS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjb21wID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMzAsIDMpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ29tcHJlc3NvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwicmF0aW9cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb21wcmVzc29yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgY29tcHJlc3NvciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yID0gdGhpcy5jb250ZXh0LmNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fY29tcHJlc3NvcjtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9jb21wcmVzc29yO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInJhdGlvXCJdKTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IudGhyZXNob2xkLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3IudGhyZXNob2xkLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudGhyZXNob2xkLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IuYXR0YWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuYXR0YWNrLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIG1pblZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJlbGVhc2UubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IucmVsZWFzZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnJlbGVhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmtuZWUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3Iua25lZS5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLmtuZWUubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLmtuZWUsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMua25lZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmF0aW8gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmF0aW8ubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yYXRpby5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IucmF0aW8sXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmF0aW8sXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzZXQgdGhlIGRlZmF1bHRzXG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImtuZWVcIiwgXCJyZWxlYXNlXCIsIFwiYXR0YWNrXCIsIFwicmF0aW9cIiwgXCJ0aHJlc2hvbGRcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLjAwMyxcbiAgICAgICAgICAgIGtuZWU6IDMwLFxuICAgICAgICAgICAgcmF0aW86IDEyLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4yNSxcbiAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWFkLW9ubHkgZGVjaWJlbCB2YWx1ZSBmb3IgbWV0ZXJpbmcgcHVycG9zZXMsIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBhbW91bnQgb2YgZ2FpblxuICAgICAqIHJlZHVjdGlvbiB0aGF0IHRoZSBjb21wcmVzc29yIGlzIGFwcGx5aW5nIHRvIHRoZSBzaWduYWwuIElmIGZlZCBubyBzaWduYWwgdGhlIHZhbHVlIHdpbGwgYmUgMCAobm8gZ2FpbiByZWR1Y3Rpb24pLlxuICAgICAqL1xuICAgIGdldCByZWR1Y3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb21wcmVzc29yLnJlZHVjdGlvbjtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5hdHRhY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnJlbGVhc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRocmVzaG9sZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmF0aW8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmtuZWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9HcmVhdGVyVGhhblwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgRm9sbG93ZXIgfSBmcm9tIFwiLi4vYW5hbHlzaXMvRm9sbG93ZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuLyoqXG4gKiBHYXRlIG9ubHkgcGFzc2VzIGEgc2lnbmFsIHRocm91Z2ggd2hlbiB0aGUgaW5jb21pbmdcbiAqIHNpZ25hbCBleGNlZWRzIGEgc3BlY2lmaWVkIHRocmVzaG9sZC4gSXQgdXNlcyBbW0ZvbGxvd2VyXV0gdG8gZm9sbG93IHRoZSBhbXBsdGl1ZGVcbiAqIG9mIHRoZSBpbmNvbWluZyBzaWduYWwgYW5kIGNvbXBhcmVzIGl0IHRvIHRoZSBbW3RocmVzaG9sZF1dIHZhbHVlIHVzaW5nIFtbR3JlYXRlclRoYW5dXS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZ2F0ZSA9IG5ldyBUb25lLkdhdGUoLTMwLCAwLjIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpLmNvbm5lY3QoZ2F0ZSk7XG4gKiAvLyB0aGUgZ2F0ZSB3aWxsIG9ubHkgcGFzcyB0aHJvdWdoIHRoZSBpbmNvbWluZ1xuICogLy8gc2lnbmFsIHdoZW4gaXQncyBsb3VkZXIgdGhhbiAtMzBkYlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgR2F0ZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhdGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJzbW9vdGhpbmdcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR2F0ZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR2F0ZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInNtb290aGluZ1wiXSk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyID0gbmV3IEZvbGxvd2VyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHNtb290aGluZzogb3B0aW9ucy5zbW9vdGhpbmcsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9ndCA9IG5ldyBHcmVhdGVyVGhhbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogZGJUb0dhaW4ob3B0aW9ucy50aHJlc2hvbGQpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9nYXRlID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX2dhdGUpO1xuICAgICAgICAvLyB0aGUgY29udHJvbCBzaWduYWxcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9mb2xsb3dlciwgdGhpcy5fZ3QsIHRoaXMuX2dhdGUuZ2Fpbik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuMSxcbiAgICAgICAgICAgIHRocmVzaG9sZDogLTQwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGhyZXNob2xkIG9mIHRoZSBnYXRlIGluIGRlY2liZWxzXG4gICAgICovXG4gICAgZ2V0IHRocmVzaG9sZCgpIHtcbiAgICAgICAgcmV0dXJuIGdhaW5Ub0RiKHRoaXMuX2d0LnZhbHVlKTtcbiAgICB9XG4gICAgc2V0IHRocmVzaG9sZCh0aHJlc2gpIHtcbiAgICAgICAgdGhpcy5fZ3QudmFsdWUgPSBkYlRvR2Fpbih0aHJlc2gpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXR0YWNrL2RlY2F5IHNwZWVkIG9mIHRoZSBnYXRlLiBTZWUgW1tGb2xsb3dlci5zbW9vdGhpbmddXVxuICAgICAqL1xuICAgIGdldCBzbW9vdGhpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcoc21vb3RoaW5nVGltZSkge1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5zbW9vdGhpbmcgPSBzbW9vdGhpbmdUaW1lO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2d0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdhdGUuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBDb21wcmVzc29yIH0gZnJvbSBcIi4vQ29tcHJlc3NvclwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuO1xuLyoqXG4gKiBMaW1pdGVyIHdpbGwgbGltaXQgdGhlIGxvdWRuZXNzIG9mIGFuIGluY29taW5nIHNpZ25hbC5cbiAqIFVuZGVyIHRoZSBob29kIGl0J3MgY29tcG9zZWQgb2YgYSBbW0NvbXByZXNzb3JdXSB3aXRoIGEgZmFzdCBhdHRhY2tcbiAqIGFuZCByZWxlYXNlIGFuZCBtYXggY29tcHJlc3Npb24gcmF0aW8uXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGxpbWl0ZXIgPSBuZXcgVG9uZS5MaW1pdGVyKC0yMCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGxpbWl0ZXIpO1xuICogb3NjaWxsYXRvci5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTGltaXRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKExpbWl0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTGltaXRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTGltaXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiXSk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgQ29tcHJlc3Nvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICByYXRpbzogMjAsXG4gICAgICAgICAgICBhdHRhY2s6IDAuMDAzLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4wMSxcbiAgICAgICAgICAgIHRocmVzaG9sZDogb3B0aW9ucy50aHJlc2hvbGRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkID0gdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQ7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidGhyZXNob2xkXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdGhyZXNob2xkOiAtMTJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcmVhZC1vbmx5IGRlY2liZWwgdmFsdWUgZm9yIG1ldGVyaW5nIHB1cnBvc2VzLCByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgYW1vdW50IG9mIGdhaW5cbiAgICAgKiByZWR1Y3Rpb24gdGhhdCB0aGUgY29tcHJlc3NvciBpcyBhcHBseWluZyB0byB0aGUgc2lnbmFsLlxuICAgICAqL1xuICAgIGdldCByZWR1Y3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb21wcmVzc29yLnJlZHVjdGlvbjtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1MaW1pdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1pZFNpZGVTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL01pZFNpZGVTcGxpdFwiO1xuaW1wb3J0IHsgTWlkU2lkZU1lcmdlIH0gZnJvbSBcIi4uL2NoYW5uZWwvTWlkU2lkZU1lcmdlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIE1pZFNpZGVDb21wcmVzc29yIGFwcGxpZXMgdHdvIGRpZmZlcmVudCBjb21wcmVzc29ycyB0byB0aGUgW1ttaWRdXVxuICogYW5kIFtbc2lkZV1dIHNpZ25hbCBjb21wb25lbnRzIG9mIHRoZSBpbnB1dC4gU2VlIFtbTWlkU2lkZVNwbGl0XV0gYW5kIFtbTWlkU2lkZU1lcmdlXV0uXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlQ29tcHJlc3NvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlQ29tcHJlc3NvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZUNvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0ID0gdGhpcy5pbnB1dCA9IG5ldyBNaWRTaWRlU3BsaXQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IE1pZFNpZGVNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5taWQgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMubWlkLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuc2lkZSA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5zaWRlLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5taWQuY2hhaW4odGhpcy5taWQsIHRoaXMuX21pZFNpZGVNZXJnZS5taWQpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuc2lkZS5jaGFpbih0aGlzLnNpZGUsIHRoaXMuX21pZFNpZGVNZXJnZS5zaWRlKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibWlkXCIsIFwic2lkZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtaWQ6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNpZGU6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogNixcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0zMCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjI1LFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMyxcbiAgICAgICAgICAgICAgICBrbmVlOiAxMFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuc2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVDb21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpYmFuZFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbi8qKlxuICogQSBjb21wcmVzc29yIHdpdGggc2VwYXJhdGUgY29udHJvbHMgb3ZlciBsb3cvbWlkL2hpZ2ggZHluYW1pY3MuIFNlZSBbW0NvbXByZXNzb3JdXSBhbmQgW1tNdWx0aWJhbmRTcGxpdF1dXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG11bHRpYmFuZCA9IG5ldyBUb25lLk11bHRpYmFuZENvbXByZXNzb3Ioe1xuICogXHRsb3dGcmVxdWVuY3k6IDIwMCxcbiAqIFx0aGlnaEZyZXF1ZW5jeTogMTMwMCxcbiAqIFx0bG93OiB7XG4gKiBcdFx0dGhyZXNob2xkOiAtMTJcbiAqIFx0fVxuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNdWx0aWJhbmRDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGliYW5kQ29tcHJlc3NvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlciA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGliYW5kU3BsaXQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiBvcHRpb25zLmxvd0ZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kgPSB0aGlzLl9zcGxpdHRlci5sb3dGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IHRoaXMuX3NwbGl0dGVyLmhpZ2hGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMubG93ID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLmxvdywgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5taWQsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5oaWdoID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLmhpZ2gsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgY29tcHJlc3NvclxuICAgICAgICB0aGlzLl9zcGxpdHRlci5sb3cuY2hhaW4odGhpcy5sb3csIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIubWlkLmNoYWluKHRoaXMubWlkLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmhpZ2guY2hhaW4odGhpcy5oaWdoLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogMjUwLFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogMjAwMCxcbiAgICAgICAgICAgIGxvdzoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiA2LFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTMwLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAzLFxuICAgICAgICAgICAgICAgIGtuZWU6IDEwXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbWlkOiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDMsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4wMyxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDIsXG4gICAgICAgICAgICAgICAga25lZTogMTZcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBoaWdoOiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDMsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4wMyxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDIsXG4gICAgICAgICAgICAgICAga25lZTogMTZcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5sb3cuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGliYW5kQ29tcHJlc3Nvci5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aWJhbmRTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL011bHRpYmFuZFNwbGl0XCI7XG4vKipcbiAqIEVRMyBwcm92aWRlcyAzIGVxdWFsaXplciBiaW5zOiBMb3cvTWlkL0hpZ2guXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBFUTMgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRVEzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVRM1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRVEzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdCA9IG5ldyBNdWx0aWJhbmRTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiBvcHRpb25zLmhpZ2hGcmVxdWVuY3ksXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbG93R2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMubG93LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21pZEdhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLm1pZCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9oaWdoR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMuaGlnaCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvdyA9IHRoaXMuX2xvd0dhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5taWQgPSB0aGlzLl9taWRHYWluLmdhaW47XG4gICAgICAgIHRoaXMuaGlnaCA9IHRoaXMuX2hpZ2hHYWluLmdhaW47XG4gICAgICAgIHRoaXMuUSA9IHRoaXMuX211bHRpYmFuZFNwbGl0LlE7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gdGhpcy5fbXVsdGliYW5kU3BsaXQubG93RnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdC5oaWdoRnJlcXVlbmN5O1xuICAgICAgICAvLyB0aGUgZnJlcXVlbmN5IGJhbmRzXG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0Lmxvdy5jaGFpbih0aGlzLl9sb3dHYWluLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0Lm1pZC5jaGFpbih0aGlzLl9taWRHYWluLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0LmhpZ2guY2hhaW4odGhpcy5faGlnaEdhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiLCBcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuX211bHRpYmFuZFNwbGl0XTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGhpZ2g6IDAsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyNTAwLFxuICAgICAgICAgICAgbG93OiAwLFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiA0MDAsXG4gICAgICAgICAgICBtaWQ6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFtcImxvd1wiLCBcIm1pZFwiLCBcImhpZ2hcIiwgXCJsb3dGcmVxdWVuY3lcIiwgXCJoaWdoRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xvd0dhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRHYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5faGlnaEdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvdy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RVEzLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENvbnZvbHZlciBpcyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBOYXRpdmUgV2ViIEF1ZGlvXG4gKiBbQ29udm9sdmVyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtY29udm9sdmVybm9kZS1pbnRlcmZhY2UpLlxuICogQ29udm9sdXRpb24gaXMgdXNlZnVsIGZvciByZXZlcmIgYW5kIGZpbHRlciBlbXVsYXRpb24uIFJlYWQgbW9yZSBhYm91dCBjb252b2x1dGlvbiByZXZlcmIgb25cbiAqIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbnZvbHV0aW9uX3JldmVyYikuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemluZyB0aGUgY29udm9sdmVyIHdpdGggYW4gaW1wdWxzZSByZXNwb25zZVxuICogY29uc3QgY29udm9sdmVyID0gbmV3IFRvbmUuQ29udm9sdmVyKFwiLi9wYXRoL3RvL2lyLndhdlwiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDb252b2x2ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29udm9sdmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ29udm9sdmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmF0aXZlIENvbnZvbHZlck5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnZvbHZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbnZvbHZlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIob3B0aW9ucy51cmwsIGJ1ZmZlciA9PiB7XG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgICAgIG9wdGlvbnMub25sb2FkKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8vIHNldCBpZiBpdCdzIGFscmVhZHkgbG9hZGVkLCBzZXQgaXQgaW1tZWRpYXRlbHlcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gdGhpcy5fYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIC8vIGluaXRpYWxseSBzZXQgbm9ybWFsaXphdGlvblxuICAgICAgICB0aGlzLm5vcm1hbGl6ZSA9IG9wdGlvbnMubm9ybWFsaXplO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fY29udm9sdmVyLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBub3JtYWxpemU6IHRydWUsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2FkIGFuIGltcHVsc2UgcmVzcG9uc2UgdXJsIGFzIGFuIGF1ZGlvIGJ1ZmZlci5cbiAgICAgKiBEZWNvZGVzIHRoZSBhdWRpbyBhc3luY2hyb25vdXNseSBhbmQgaW52b2tlc1xuICAgICAqIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC4gZmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IHlpZWxkIHRoaXMuX2J1ZmZlci5sb2FkKHVybCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY29udm9sdmVyJ3MgYnVmZmVyXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgYnVmZmVyKGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgaXQncyBhbHJlYWR5IGdvdCBhIGJ1ZmZlciwgY3JlYXRlIGEgbmV3IG9uZVxuICAgICAgICBpZiAodGhpcy5fY29udm9sdmVyLmJ1ZmZlcikge1xuICAgICAgICAgICAgLy8gZGlzY29ubmVjdCB0aGUgb2xkIG9uZVxuICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgLy8gY3JlYXRlIGFuZCBjb25uZWN0IGEgbmV3IG9uZVxuICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9jb252b2x2ZXIsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBidWZmID0gdGhpcy5fYnVmZmVyLmdldCgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuYnVmZmVyID0gYnVmZiA/IGJ1ZmYgOiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbm9ybWFsaXplIHByb3BlcnR5IG9mIHRoZSBDb252b2x2ZXJOb2RlIGludGVyZmFjZSBpcyBhIGJvb2xlYW4gdGhhdFxuICAgICAqIGNvbnRyb2xzIHdoZXRoZXIgdGhlIGltcHVsc2UgcmVzcG9uc2UgZnJvbSB0aGUgYnVmZmVyIHdpbGwgYmUgc2NhbGVkIGJ5XG4gICAgICogYW4gZXF1YWwtcG93ZXIgbm9ybWFsaXphdGlvbiB3aGVuIHRoZSBidWZmZXIgYXR0cmlidXRlIGlzIHNldCwgb3Igbm90LlxuICAgICAqL1xuICAgIGdldCBub3JtYWxpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb252b2x2ZXIubm9ybWFsaXplO1xuICAgIH1cbiAgICBzZXQgbm9ybWFsaXplKG5vcm0pIHtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLm5vcm1hbGl6ZSA9IG5vcm07XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udm9sdmVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0FuYWx5c2VyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9NZXRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvRkZUXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9EQ01ldGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9XYXZlZm9ybVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvRm9sbG93ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvQ2hhbm5lbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWVyZ2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWlkU2lkZU1lcmdlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01pZFNpZGVTcGxpdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Nb25vXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL011bHRpYmFuZFNwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1Bhbm5lclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9QYW5uZXIzRFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9QYW5Wb2xcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUmVjb3JkZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvU29sb1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9TcGxpdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Wb2x1bWVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL0NvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL0dhdGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL0xpbWl0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL01pZFNpZGVDb21wcmVzc29yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9keW5hbWljcy9NdWx0aWJhbmRDb21wcmVzc29yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VudmVsb3BlL0ZyZXF1ZW5jeUVudmVsb3BlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRVEzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvT25lUG9sZUZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvQ29udm9sdmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvQmlxdWFkRmlsdGVyXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9jb3JlL2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zb3VyY2UvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NpZ25hbC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vaW5zdHJ1bWVudC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZXZlbnQvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VmZmVjdC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29tcG9uZW50L2luZGV4XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jbGFzc2VzLmpzLm1hcCIsImV4cG9ydCB7IGdldENvbnRleHQsIHNldENvbnRleHQgfSBmcm9tIFwiLi9jb3JlL0dsb2JhbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2xhc3Nlc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdmVyc2lvblwiO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5leHBvcnQgeyBzdGFydCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5leHBvcnQgeyBzdXBwb3J0ZWQgfSBmcm9tIFwiLi9jb3JlL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG4vKipcbiAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBvZiB0aGUgZ2xvYmFsIFtbQ29udGV4dF1dLlxuICogU2VlIFtbQ29udGV4dC5ub3ddXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdygpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLm5vdygpO1xufVxuLyoqXG4gKiBUaGUgY3VycmVudCBhdWRpbyBjb250ZXh0IHRpbWUgb2YgdGhlIGdsb2JhbCBbW0NvbnRleHRdXSB3aXRob3V0IHRoZSBbW0NvbnRleHQubG9va0FoZWFkXV1cbiAqIFNlZSBbW0NvbnRleHQuaW1tZWRpYXRlXV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbW1lZGlhdGUoKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5pbW1lZGlhdGUoKTtcbn1cbi8qKlxuICogVGhlIFRyYW5zcG9ydCBvYmplY3QgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbVHJhbnNwb3J0XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBUcmFuc3BvcnQgPSBnZXRDb250ZXh0KCkudHJhbnNwb3J0O1xuLyoqXG4gKiBUaGUgVHJhbnNwb3J0IG9iamVjdCBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tUcmFuc3BvcnRdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zcG9ydCgpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLnRyYW5zcG9ydDtcbn1cbi8qKlxuICogVGhlIERlc3RpbmF0aW9uIChvdXRwdXQpIGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW0Rlc3RpbmF0aW9uXV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBEZXN0aW5hdGlvbiA9IGdldENvbnRleHQoKS5kZXN0aW5hdGlvbjtcbi8qKlxuICogQGRlcHJlY2F0ZWQgVXNlIFtbRGVzdGluYXRpb25dXVxuICovXG5leHBvcnQgY29uc3QgTWFzdGVyID0gZ2V0Q29udGV4dCgpLmRlc3RpbmF0aW9uO1xuLyoqXG4gKiBUaGUgRGVzdGluYXRpb24gKG91dHB1dCkgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbRGVzdGluYXRpb25dXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlc3RpbmF0aW9uKCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkuZGVzdGluYXRpb247XG59XG4vKipcbiAqIFRoZSBbW0xpc3RlbmVyXV0gYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IExpc3RlbmVyID0gZ2V0Q29udGV4dCgpLmxpc3RlbmVyO1xuLyoqXG4gKiBUaGUgW1tMaXN0ZW5lcl1dIGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaXN0ZW5lcigpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmxpc3RlbmVyO1xufVxuLyoqXG4gKiBEcmF3IGlzIHVzZWQgdG8gc3luY2hyb25pemUgdGhlIGRyYXcgZnJhbWUgd2l0aCB0aGUgVHJhbnNwb3J0J3MgY2FsbGJhY2tzLlxuICogU2VlIFtbRHJhd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgRHJhdyA9IGdldENvbnRleHQoKS5kcmF3O1xuLyoqXG4gKiBHZXQgdGhlIHNpbmdsZXRvbiBhdHRhY2hlZCB0byB0aGUgZ2xvYmFsIGNvbnRleHQuXG4gKiBEcmF3IGlzIHVzZWQgdG8gc3luY2hyb25pemUgdGhlIGRyYXcgZnJhbWUgd2l0aCB0aGUgVHJhbnNwb3J0J3MgY2FsbGJhY2tzLlxuICogU2VlIFtbRHJhd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RHJhdygpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmRyYXc7XG59XG4vKipcbiAqIEEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgY29udGV4dFxuICogU2VlIFtbQ29udGV4dF1dXG4gKi9cbmV4cG9ydCBjb25zdCBjb250ZXh0ID0gZ2V0Q29udGV4dCgpO1xuLyoqXG4gKiBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gYWxsIG9mIHRoZSBsb2FkaW5nIHByb21pc2VzIGFyZSByZXNvbHZlZC5cbiAqIEFsaWFzIGZvciBzdGF0aWMgW1tUb25lQXVkaW9CdWZmZXIubG9hZGVkXV0gbWV0aG9kLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvYWRlZCgpIHtcbiAgICByZXR1cm4gVG9uZUF1ZGlvQnVmZmVyLmxvYWRlZCgpO1xufVxuLy8gdGhpcyBmaWxscyBpbiBuYW1lIGNoYW5nZXMgZnJvbSAxMy54IHRvIDE0LnhcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL3NvdXJjZS9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZVwiO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlciA9IFRvbmVBdWRpb0J1ZmZlcjtcbmV4cG9ydCBjb25zdCBCdWZmZXJzID0gVG9uZUF1ZGlvQnVmZmVycztcbmV4cG9ydCBjb25zdCBCdWZmZXJTb3VyY2UgPSBUb25lQnVmZmVyU291cmNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0ICogYXMgVG9uZSBmcm9tIFwidG9uZVwiO1xuaW1wb3J0IFN0YXJ0QXVkaW9Db250ZXh0IGZyb20gXCIuL3N0YXJ0QXVkaW9Db250ZXh0XCI7XG5cbmNvbnN0IGlzSXBob25lID1cbiAgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBob25lL2kpIHx8IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQb2QvaSk7XG5jb25zdCBpc0lwYWQgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGFkL2kpO1xuY29uc3QgaXNBbmRyb2lkID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvQW5kcm9pZC9pKTtcbmNvbnN0IGlzTW9iaWxlID0gaXNJcGhvbmUgfHwgaXNJcGFkIHx8IGlzQW5kcm9pZDtcbmNvbnN0IGlzRGVza3RvcCA9ICFpc01vYmlsZTtcblxuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKGlzTW9iaWxlID8gXCJtb2JpbGVcIiA6IFwiZGVza3RvcFwiKTtcblxuZXhwb3J0IGNvbnN0IGJyb3dzZXIgPSB7IGlzSXBob25lLCBpc0lwYWQsIGlzTW9iaWxlLCBpc0Rlc2t0b3AgfTtcbmV4cG9ydCBjb25zdCBjaG9pY2UgPSAoYSkgPT4gYVtNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBhLmxlbmd0aCldO1xuZXhwb3J0IGNvbnN0IG1vZCA9IChuLCBtKSA9PiBuIC0gbSAqIE1hdGguZmxvb3IobiAvIG0pO1xuZXhwb3J0IGNvbnN0IHJhbmRvbSA9ICgpID0+IE1hdGgucmFuZG9tKCk7XG5leHBvcnQgY29uc3QgcmFuZCA9IChuKSA9PiBNYXRoLnJhbmRvbSgpICogbjtcbmV4cG9ydCBjb25zdCByYW5kaW50ID0gKG4pID0+IHJhbmQobikgfCAwO1xuZXhwb3J0IGNvbnN0IHJhbmRyYW5nZSA9IChhLCBiKSA9PiBhICsgcmFuZChiIC0gYSk7XG5leHBvcnQgY29uc3QgcmFuZHNpZ24gPSAoKSA9PiAocmFuZG9tKCkgPj0gMC41ID8gLTEgOiAxKTtcbmV4cG9ydCBjb25zdCByYW5kbnVsbHNpZ24gPSAoKSA9PiB7XG4gIHZhciByID0gcmFuZG9tKCk7XG4gIHJldHVybiByIDwgMC4zMzMgPyAtMSA6IHIgPCAwLjY2NiA/IDAgOiAxO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcXVlc3RBdWRpb0NvbnRleHQoZm4pIHtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgY29uc3QgYnV0dG9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYnV0dG9uLmlubmVySFRNTCA9IFwiVGFwIHRvIHN0YXJ0IC0gcGxlYXNlIHVubXV0ZSB5b3VyIHBob25lXCI7XG4gIE9iamVjdC5hc3NpZ24oY29udGFpbmVyLnN0eWxlLCB7XG4gICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgd2lkdGg6IFwiMTAwJVwiLFxuICAgIGhlaWdodDogXCIxMDAlXCIsXG4gICAgekluZGV4OiBcIjEwMDAwXCIsXG4gICAgdG9wOiBcIjBweFwiLFxuICAgIGxlZnQ6IFwiMHB4XCIsXG4gICAgYmFja2dyb3VuZENvbG9yOiBcInJnYmEoMCwgMCwgMCwgMC44KVwiLFxuICB9KTtcbiAgT2JqZWN0LmFzc2lnbihidXR0b24uc3R5bGUsIHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICBsZWZ0OiBcIjUwJVwiLFxuICAgIHRvcDogXCI1MCVcIixcbiAgICBwYWRkaW5nOiBcIjIwcHhcIixcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IFwiIzdGMzNFRFwiLFxuICAgIGNvbG9yOiBcIndoaXRlXCIsXG4gICAgZm9udEZhbWlseTogXCJtb25vc3BhY2VcIixcbiAgICBib3JkZXJSYWRpdXM6IFwiM3B4XCIsXG4gICAgdHJhbnNmb3JtOiBcInRyYW5zbGF0ZTNEKC01MCUsLTUwJSwwKVwiLFxuICAgIHRleHRBbGlnbjogXCJjZW50ZXJcIixcbiAgICBsaW5lSGVpZ2h0OiBcIjEuNVwiLFxuICAgIHdpZHRoOiBcIjE1MHB4XCIsXG4gIH0pO1xuICBjb250YWluZXIuYXBwZW5kQ2hpbGQoYnV0dG9uKTtcbiAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0KFRvbmUuY29udGV4dCk7XG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGJ1dHRvbik7XG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uU3RhcnRlZCgoXykgPT4ge1xuICAgIGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICBmbigpO1xuICB9KTtcbn1cbiIsImltcG9ydCAqIGFzIFRvbmUgZnJvbSBcInRvbmVcIjtcblxuY29uc3QgY29tcHJlc3NvciA9IG5ldyBUb25lLkNvbXByZXNzb3IoLTMwLCAzKTtcbmNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKDAuMyk7XG5jb21wcmVzc29yLmNvbm5lY3QoZ2Fpbik7XG5nYWluLnRvRGVzdGluYXRpb24oKTtcblxuZXhwb3J0IGRlZmF1bHQgY29tcHJlc3NvcjtcbiIsImltcG9ydCAqIGFzIFRvbmUgZnJvbSBcInRvbmVcIjtcbmltcG9ydCB7IGNob2ljZSB9IGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCBvdXRwdXQgZnJvbSBcIi4vb3V0cHV0XCI7XG5cbmNvbnN0IHBsYXllcl9jb3VudCA9IDQ7XG5sZXQgcGxheWVyX2luZGV4ID0gMDtcblxuY29uc3Qgc2FtcGxlcyA9IFtcbiAgeyByb290OiAyMjYsIGZuOiBcInNhbXBsZXMvMzgwNzM3X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMS1hLXJhdy5tcDNcIiB9LFxuICB7IHJvb3Q6IDI2NywgZm46IFwic2FtcGxlcy8zODA3MzZfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAyLWMtcmF3Lm1wM1wiIH0sXG4gIHsgcm9vdDogMzQwLCBmbjogXCJzYW1wbGVzLzM4MDczNV9fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDMtZS1yYXcubXAzXCIgfSxcbiAgeyByb290OiA0NTIsIGZuOiBcInNhbXBsZXMvMzgwNzMzX19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wNi1hLTAyLXJhdy5tcDNcIiB9LFxuICAvLyAgeyByb290OiA1MDcsIGZuOiAnc2FtcGxlcy8zODA3MzRfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTA3LWItaC1yYXcud2F2JywgfSxcbiAgLy8gIHsgcm9vdDogNTM1LCBmbjogJ3NhbXBsZXMvMzgwNzMxX19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wOC1jLXJhdy53YXYnLCB9LFxuICAvLyAgeyByb290OiA2NzEsIGZuOiAnc2FtcGxlcy8zODA3MzJfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTA5LWUtcmF3LndhdicsIH0sXG5dO1xuXG5zYW1wbGVzLmZvckVhY2goKHNhbXBsZSkgPT4ge1xuICBzYW1wbGUucGxheWVycyA9IFtdO1xuICBzYW1wbGUuaW5kZXggPSAtMTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwbGF5ZXJfY291bnQ7IGkrKykge1xuICAgIGxldCBmbiA9IHNhbXBsZS5mbjtcbiAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL2FzZGYudXMvKSkge1xuICAgICAgZm4gPSBcIi8vYXNkZi51cy9rYWxpbWJhL1wiICsgZm47XG4gICAgfVxuICAgIGxldCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoe1xuICAgICAgdXJsOiBmbixcbiAgICAgIHJldHJpZ2dlcjogdHJ1ZSxcbiAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICB9KTtcbiAgICBwbGF5ZXIuY29ubmVjdChvdXRwdXQpO1xuICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKTtcbiAgfVxufSk7XG5cbmZ1bmN0aW9uIHBsYXkoZnJlcSwgdGltZSkge1xuICBjb25zdCBiZXN0ID0gY2hvaWNlKHNhbXBsZXMpO1xuICBiZXN0LmluZGV4ID0gKGJlc3QuaW5kZXggKyAxKSAlIHBsYXllcl9jb3VudDtcblxuICBjb25zdCBwbGF5ZXIgPSBiZXN0LnBsYXllcnNbYmVzdC5pbmRleF07XG4gIHBsYXllci5wbGF5YmFja1JhdGUgPSBmcmVxIC8gYmVzdC5yb290O1xuICBwbGF5ZXIuc3RhcnQodGltZSB8fCAwKTtcbn1cblxuZnVuY3Rpb24gcGF1c2UoKSB7XG4gIC8vIG5vLW9wXG59XG5cbmV4cG9ydCBkZWZhdWx0IHsgcGxheSwgcGF1c2UgfTtcbiIsImltcG9ydCAqIGFzIFRvbmUgZnJvbSBcInRvbmVcIjtcbmltcG9ydCBrYWxpbWJhIGZyb20gXCIuLi9saWIva2FsaW1iYVwiO1xuaW1wb3J0IHsgcmFuZHJhbmdlIH0gZnJvbSBcIi4uL2xpYi91dGlsXCI7XG5cbmNvbnN0IFRXT19QSSA9IDIgKiBNYXRoLlBJO1xuXG4vKipcbiAqIFdhdmUgZnVuY3Rpb25zXG4gKi9cbmNvbnN0IFdBVkVfRlVOQ1RJT05TID0ge1xuICBzaW5lOiBNYXRoLmNvcyxcbiAgdHJpYW5nbGU6ICh0aW1lKSA9PlxuICAgICg0IC8gVFdPX1BJKSAqXG4gICAgICBNYXRoLmFicyhcbiAgICAgICAgKCgoKHRpbWUgLSBUV09fUEkgLyA0KSAlIFRXT19QSSkgKyBUV09fUEkpICUgVFdPX1BJKSAtIFRXT19QSSAvIDJcbiAgICAgICkgLVxuICAgIDEsXG4gIHNxdWFyZTogKHRpbWUpID0+ICh0aW1lICUgVFdPX1BJIDwgTWF0aC5QSSA/IDEgOiAtMSksXG4gIHNhdzogKHRpbWUpID0+ICgodGltZSAlIFRXT19QSSkgLSBNYXRoLlBJKSAvIE1hdGguUEksXG59O1xuXG5jbGFzcyBSZWxhYmkge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSByZWxhYmkgZ2VuZXJhdG9yXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLnVwZGF0ZVRpbWUgPSAxLjA7XG4gICAgdGhpcy5zdGVwcyA9IDEwMDtcbiAgICB0aGlzLndhdmVzID0gW1xuICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC41LCAyKSB9LFxuICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC41LCAyKSB9LFxuICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMSwgMTApIH0sXG4gICAgICB7IHR5cGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IHJhbmRyYW5nZSg1LCAxMCkgfSxcbiAgICBdO1xuICAgIHRoaXMuYm91bmRzID0gWy0wLjUsIDAuNV07XG4gICAgdGhpcy5mcmVxdWVuY2llcyA9IFsyMjAsICgyMjAgKiAzKSAvIDIsIDQ0MCwgKDQ0MCAqIDMpIC8gMl07XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgdGhlIGdlbmVyYXRvclxuICAgKi9cbiAgc3RhcnQoKSB7XG4gICAgY29uc29sZS5sb2coXCJTdGFydCBSZWxhYmlcIik7XG4gICAgdGhpcy5zdG9wKCk7XG4gICAgdGhpcy5jbG9jayA9IG5ldyBUb25lLkNsb2NrKCh0aW1lKSA9PiB0aGlzLnN0ZXAodGltZSksIHRoaXMudXBkYXRlVGltZSk7XG4gICAgdGhpcy5jbG9jay5zdGFydCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0b3AgdGhlIGdlbmVyYXRvciBhbmQgcmVzZXQgaXRcbiAgICovXG4gIHN0b3AoKSB7XG4gICAgaWYgKHRoaXMuY2xvY2spIHtcbiAgICAgIHRoaXMuY2xvY2suc3RvcCgpO1xuICAgICAgdGhpcy5jbG9jay5kaXNwb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHJlbGFiaSBldmVudHNcbiAgICovXG4gIHN0ZXAodGltZSkge1xuICAgIGNvbnN0IHdhdmVDb3VudCA9IHRoaXMud2F2ZXMubGVuZ3RoO1xuICAgIGNvbnN0IGJvdW5kc0NvdW50ID0gdGhpcy5ib3VuZHMubGVuZ3RoO1xuICAgIGxldCBwcmV2aW91c1ZhbHVlID0gdGhpcy5wcmV2aW91c1ZhbHVlO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgdmFsdWU7XG4gICAgbGV0IG5vdGVDb3VudCA9IDA7XG5cbiAgICAvLyBHZW5lcmF0ZSBzZXZlcmFsIGV2ZW50cyBwZXIgc2Vjb25kXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gVGltZSBvZmZzZXQgZm9yIHRoaXMgZXZlbnRcbiAgICAgIGNvbnN0IG9mZnNldCA9IHRpbWUgKyAoc3RlcCAqIHRoaXMudXBkYXRlVGltZSkgLyB0aGlzLnN0ZXBzO1xuXG4gICAgICAvLyBJbml0aWFsaXplIHZhbHVlXG4gICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgIC8vIENvbXB1dGUgdGhlIHdhdmUgZnVuY3Rpb25zIGZvciB0aGlzIGV2ZW50XG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCB3YXZlQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgY29uc3Qgd2F2ZSA9IHRoaXMud2F2ZXNbaW5kZXhdO1xuICAgICAgICB2YWx1ZSArPSBXQVZFX0ZVTkNUSU9OU1t3YXZlLnR5cGVdKG9mZnNldCAqIHdhdmUuZnJlcXVlbmN5KTtcbiAgICAgIH1cblxuICAgICAgLy8gU2NhbGUgdG8gWy0xLCAxXVxuICAgICAgdmFsdWUgLz0gd2F2ZUNvdW50IC8gTWF0aC5QSTtcblxuICAgICAgLy8gQ29tcHV0ZSB3aGV0aGVyIHdlIGNyb3NzZWQgYSBib3VuZGFyeSwgYW5kIHdoaWNoIGRpcmVjdGlvblxuICAgICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgYm91bmRzQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgY29uc3QgYm91bmQgPSB0aGlzLmJvdW5kc1tpbmRleF07XG4gICAgICAgIGlmICh2YWx1ZSA8IGJvdW5kICYmIGJvdW5kIDwgcHJldmlvdXNWYWx1ZSkge1xuICAgICAgICAgIC8vIEdvaW5nIGRvd25cbiAgICAgICAgICB0aGlzLnRyaWdnZXIob2Zmc2V0LCBpbmRleCAqIDIpO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlID4gYm91bmQgJiYgYm91bmQgPiBwcmV2aW91c1ZhbHVlKSB7XG4gICAgICAgICAgLy8gR29pbmcgdXBcbiAgICAgICAgICB0aGlzLnRyaWdnZXIob2Zmc2V0LCBpbmRleCAqIDIgKyAxKTtcbiAgICAgICAgICBub3RlQ291bnQgKz0gMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBVcGRhdGUgdGhlIHByZXZpb3VzIHZhbHVlXG4gICAgICBwcmV2aW91c1ZhbHVlID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gU3RvcmUgdGhlIGxhdGVzdCB2YWx1ZVxuICAgIHRoaXMucHJldmlvdXNWYWx1ZSA9IHZhbHVlO1xuXG4gICAgY29uc29sZS5sb2coYFRpY2sgJHtNYXRoLmZsb29yKHRpbWUpfSwgcGxheWVkICR7bm90ZUNvdW50fSBub3Rlc2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyaWdnZXIgYW4gZXZlbnRcbiAgICovXG4gIHRyaWdnZXIodGltZSwgaW5kZXgpIHtcbiAgICAvLyBjb25zb2xlLmxvZyhcInRyaWdnZXIgaW5kZXhcIiwgaW5kZXgsIHRpbWUpO1xuICAgIGthbGltYmEucGxheSh0aGlzLmZyZXF1ZW5jaWVzW2luZGV4XSwgdGltZSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUmVsYWJpO1xuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBjcmVhdGVSb290IH0gZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIjtcbmltcG9ydCB7IHJlcXVlc3RBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi9saWIvdXRpbFwiO1xuaW1wb3J0IFJlbGFiaSBmcm9tIFwiLi9yZWxhYmlcIjtcblxuZG9jdW1lbnQuYm9keS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcIiMxMTFcIjtcbmRvY3VtZW50LmJvZHkuc3R5bGUuY29sb3IgPSBcIiNmZmZcIjtcblxucmVxdWVzdEF1ZGlvQ29udGV4dCgoKSA9PiB7XG4gIGRvY3VtZW50LmJvZHkuaW5uZXJIVE1MID0gJzxkaXYgaWQ9XCJhcHBcIj48L2Rpdj4nO1xuICBjb25zdCByZWxhYmkgPSBuZXcgUmVsYWJpKCk7XG4gIHJlbGFiaS5zdGFydCgpO1xuXG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYXBwXCIpKTtcbiAgcm9vdC5yZW5kZXIoPGgxPlJlbGFiaSBnZW5lcmF0b3I8L2gxPik7XG59KTtcbiJdLCJuYW1lcyI6WyJUb25lIiwiU3RhcnRBdWRpb0NvbnRleHQiLCJpc0lwaG9uZSIsIm5hdmlnYXRvciIsInVzZXJBZ2VudCIsIm1hdGNoIiwiaXNJcGFkIiwiaXNBbmRyb2lkIiwiaXNNb2JpbGUiLCJpc0Rlc2t0b3AiLCJkb2N1bWVudCIsImJvZHkiLCJjbGFzc0xpc3QiLCJhZGQiLCJicm93c2VyIiwiY2hvaWNlIiwiYSIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsImxlbmd0aCIsIm1vZCIsIm4iLCJtIiwicmFuZCIsInJhbmRpbnQiLCJyYW5kcmFuZ2UiLCJiIiwicmFuZHNpZ24iLCJyYW5kbnVsbHNpZ24iLCJyIiwicmVxdWVzdEF1ZGlvQ29udGV4dCIsImZuIiwiY29udGFpbmVyIiwiY3JlYXRlRWxlbWVudCIsImJ1dHRvbiIsImlubmVySFRNTCIsIk9iamVjdCIsImFzc2lnbiIsInN0eWxlIiwiZGlzcGxheSIsInBvc2l0aW9uIiwid2lkdGgiLCJoZWlnaHQiLCJ6SW5kZXgiLCJ0b3AiLCJsZWZ0IiwiYmFja2dyb3VuZENvbG9yIiwicGFkZGluZyIsImNvbG9yIiwiZm9udEZhbWlseSIsImJvcmRlclJhZGl1cyIsInRyYW5zZm9ybSIsInRleHRBbGlnbiIsImxpbmVIZWlnaHQiLCJhcHBlbmRDaGlsZCIsInNldENvbnRleHQiLCJjb250ZXh0Iiwib24iLCJvblN0YXJ0ZWQiLCJfIiwicmVtb3ZlIiwiY29tcHJlc3NvciIsIkNvbXByZXNzb3IiLCJnYWluIiwiR2FpbiIsImNvbm5lY3QiLCJ0b0Rlc3RpbmF0aW9uIiwib3V0cHV0IiwicGxheWVyX2NvdW50IiwicGxheWVyX2luZGV4Iiwic2FtcGxlcyIsInJvb3QiLCJmb3JFYWNoIiwic2FtcGxlIiwicGxheWVycyIsImluZGV4IiwiaSIsIndpbmRvdyIsImxvY2F0aW9uIiwiaHJlZiIsInBsYXllciIsIlBsYXllciIsInVybCIsInJldHJpZ2dlciIsInBsYXliYWNrUmF0ZSIsInB1c2giLCJwbGF5IiwiZnJlcSIsInRpbWUiLCJiZXN0Iiwic3RhcnQiLCJwYXVzZSIsImthbGltYmEiLCJUV09fUEkiLCJQSSIsIldBVkVfRlVOQ1RJT05TIiwic2luZSIsImNvcyIsInRyaWFuZ2xlIiwiYWJzIiwic3F1YXJlIiwic2F3IiwiUmVsYWJpIiwiX2NsYXNzQ2FsbENoZWNrIiwidXBkYXRlVGltZSIsInN0ZXBzIiwid2F2ZXMiLCJ0eXBlIiwiZnJlcXVlbmN5IiwiYm91bmRzIiwiZnJlcXVlbmNpZXMiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsIl90aGlzIiwiY29uc29sZSIsImxvZyIsInN0b3AiLCJjbG9jayIsIkNsb2NrIiwic3RlcCIsImRpc3Bvc2UiLCJ3YXZlQ291bnQiLCJib3VuZHNDb3VudCIsInByZXZpb3VzVmFsdWUiLCJub3RlQ291bnQiLCJvZmZzZXQiLCJ3YXZlIiwiYm91bmQiLCJ0cmlnZ2VyIiwiY29uY2F0IiwiUmVhY3QiLCJjcmVhdGVSb290IiwicmVsYWJpIiwiZ2V0RWxlbWVudEJ5SWQiLCJyZW5kZXIiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///209\n')},631:function(module,exports){eval('var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }\n/**\n * StartAudioContext.js\n * @author Yotam Mann\n * @license http://opensource.org/licenses/MIT MIT License\n * @copyright 2016 Yotam Mann\n */\n\n(function (root, factory) {\n if (true) {\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === \'function\' ?\n\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(this, function () {\n /**\n * The StartAudioContext object\n */\n var StartAudioContext = {\n /**\n * The audio context passed in by the user\n * @type {AudioContext}\n */\n context: null,\n /**\n * The TapListeners bound to the elements\n * @type {Array}\n * @private\n */\n _tapListeners: [],\n /**\n * Callbacks to invoke when the audio context is started\n * @type {Array}\n * @private\n */\n _onStarted: []\n };\n\n /**\n * Set the context\n * @param {AudioContext} ctx\n * @returns {StartAudioContext}\n */\n StartAudioContext.setContext = function (ctx) {\n StartAudioContext.context = ctx;\n return StartAudioContext;\n };\n\n /**\n * Add a tap listener to the audio context\n * @param {Array|Element|String|jQuery} element\n * @returns {StartAudioContext}\n */\n StartAudioContext.on = function (element) {\n if (Array.isArray(element) || NodeList && element instanceof NodeList) {\n for (var i = 0; i < element.length; i++) {\n StartAudioContext.on(element[i]);\n }\n } else if (typeof element === "string") {\n StartAudioContext.on(document.querySelectorAll(element));\n } else if (element.jquery && typeof element.toArray === "function") {\n StartAudioContext.on(element.toArray());\n } else if (Element && element instanceof Element) {\n //if it\'s an element, create a TapListener\n var tap = new TapListener(element, onTap);\n StartAudioContext._tapListeners.push(tap);\n }\n return StartAudioContext;\n };\n\n /**\n * Bind a callback to when the audio context is started.\n * @param {Function} cb\n * @return {StartAudioContext}\n */\n StartAudioContext.onStarted = function (cb) {\n //if it\'s already started, invoke the callback\n if (StartAudioContext.isStarted()) {\n cb();\n } else {\n StartAudioContext._onStarted.push(cb);\n }\n return StartAudioContext;\n };\n\n /**\n * returns true if the context is started\n * @return {Boolean}\n */\n StartAudioContext.isStarted = function () {\n return StartAudioContext.context !== null && StartAudioContext.context.state === "running";\n };\n\n /**\n * @class Listens for non-dragging tap ends on the given element\n * @param {Element} element\n * @internal\n */\n var TapListener = function TapListener(element) {\n this._dragged = false;\n this._element = element;\n this._bindedMove = this._moved.bind(this);\n this._bindedEnd = this._ended.bind(this);\n element.addEventListener("touchmove", this._bindedMove);\n element.addEventListener("touchend", this._bindedEnd);\n element.addEventListener("mouseup", this._bindedEnd);\n };\n\n /**\n * drag move event\n */\n TapListener.prototype._moved = function (e) {\n this._dragged = true;\n };\n\n /**\n * tap ended listener\n */\n TapListener.prototype._ended = function (e) {\n if (!this._dragged) {\n onTap();\n }\n this._dragged = false;\n };\n\n /**\n * remove all the bound events\n */\n TapListener.prototype.dispose = function () {\n this._element.removeEventListener("touchmove", this._bindedMove);\n this._element.removeEventListener("touchend", this._bindedEnd);\n this._element.removeEventListener("mouseup", this._bindedEnd);\n this._bindedMove = null;\n this._bindedEnd = null;\n this._element = null;\n };\n\n /**\n * Invoked the first time of the elements is tapped.\n * Creates a silent oscillator when a non-dragging touchend\n * event has been triggered.\n */\n function onTap() {\n //start the audio context with a silent oscillator\n if (StartAudioContext.context && !StartAudioContext.isStarted()) {\n var osc = StartAudioContext.context.createOscillator();\n var silent = StartAudioContext.context.createGain();\n silent.gain.value = 0;\n osc.connect(silent);\n silent.connect(StartAudioContext.context.destination);\n var now = StartAudioContext.context.currentTime;\n osc.start(now);\n osc.stop(now + 0.5);\n }\n\n //dispose all the tap listeners\n if (StartAudioContext._tapListeners) {\n for (var i = 0; i < StartAudioContext._tapListeners.length; i++) {\n StartAudioContext._tapListeners[i].dispose();\n }\n StartAudioContext._tapListeners = null;\n }\n //the onstarted callbacks\n if (StartAudioContext._onStarted) {\n for (var j = 0; j < StartAudioContext._onStarted.length; j++) {\n StartAudioContext._onStarted[j]();\n }\n StartAudioContext._onStarted = null;\n }\n }\n return StartAudioContext;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q1MsQ0FBQyxDQUFDLENBQUN5QixPQUFPLENBQUMsQ0FBQztNQUM5QztNQUNBcEMsaUJBQWlCLENBQUNFLGFBQWEsR0FBRyxJQUFJO0lBQ3hDO0lBQ0E7SUFDQSxJQUFJRixpQkFBaUIsQ0FBQ0csVUFBVSxFQUFFO01BQ2hDLEtBQUssSUFBSStDLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBR2xELGlCQUFpQixDQUFDRyxVQUFVLENBQUNTLE1BQU0sRUFBRXNDLENBQUMsRUFBRSxFQUFFO1FBQzVEbEQsaUJBQWlCLENBQUNHLFVBQVUsQ0FBQytDLENBQUMsQ0FBQyxDQUFDLENBQUM7TUFDbkM7TUFDQWxELGlCQUFpQixDQUFDRyxVQUFVLEdBQUcsSUFBSTtJQUNyQztFQUNGO0VBRUEsT0FBT0gsaUJBQWlCO0FBQzFCLENBQUMsQ0FBQyIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL3NyYy9saWIvc3RhcnRBdWRpb0NvbnRleHQuanM/NmViZiJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqICBTdGFydEF1ZGlvQ29udGV4dC5qc1xuICogIEBhdXRob3IgWW90YW0gTWFublxuICogIEBsaWNlbnNlIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQgTUlUIExpY2Vuc2VcbiAqICBAY29weXJpZ2h0IDIwMTYgWW90YW0gTWFublxuICovXG5cbihmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkge1xuICBpZiAodHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIHtcbiAgICBkZWZpbmUoW10sIGZhY3RvcnkpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgbW9kdWxlLmV4cG9ydHMpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcbiAgfSBlbHNlIHtcbiAgICByb290LlN0YXJ0QXVkaW9Db250ZXh0ID0gZmFjdG9yeSgpO1xuICB9XG59KSh0aGlzLCBmdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBUaGUgU3RhcnRBdWRpb0NvbnRleHQgb2JqZWN0XG4gICAqL1xuICB2YXIgU3RhcnRBdWRpb0NvbnRleHQgPSB7XG4gICAgLyoqXG4gICAgICogVGhlIGF1ZGlvIGNvbnRleHQgcGFzc2VkIGluIGJ5IHRoZSB1c2VyXG4gICAgICogQHR5cGUge0F1ZGlvQ29udGV4dH1cbiAgICAgKi9cbiAgICBjb250ZXh0OiBudWxsLFxuICAgIC8qKlxuICAgICAqIFRoZSBUYXBMaXN0ZW5lcnMgYm91bmQgdG8gdGhlIGVsZW1lbnRzXG4gICAgICogQHR5cGUge0FycmF5fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3RhcExpc3RlbmVyczogW10sXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2tzIHRvIGludm9rZSB3aGVuIHRoZSBhdWRpbyBjb250ZXh0IGlzIHN0YXJ0ZWRcbiAgICAgKiBAdHlwZSB7QXJyYXl9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfb25TdGFydGVkOiBbXSxcbiAgfTtcblxuICAvKipcbiAgICogU2V0IHRoZSBjb250ZXh0XG4gICAqIEBwYXJhbSB7QXVkaW9Db250ZXh0fSBjdHhcbiAgICogQHJldHVybnMge1N0YXJ0QXVkaW9Db250ZXh0fVxuICAgKi9cbiAgU3RhcnRBdWRpb0NvbnRleHQuc2V0Q29udGV4dCA9IGZ1bmN0aW9uIChjdHgpIHtcbiAgICBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ID0gY3R4O1xuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogQWRkIGEgdGFwIGxpc3RlbmVyIHRvIHRoZSBhdWRpbyBjb250ZXh0XG4gICAqIEBwYXJhbSAge0FycmF5fEVsZW1lbnR8U3RyaW5nfGpRdWVyeX0gZWxlbWVudFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5vbiA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZWxlbWVudCkgfHwgKE5vZGVMaXN0ICYmIGVsZW1lbnQgaW5zdGFuY2VvZiBOb2RlTGlzdCkpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudC5sZW5ndGg7IGkrKykge1xuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5vbihlbGVtZW50W2ldKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbGVtZW50ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5vbihkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGVsZW1lbnQpKTtcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnQuanF1ZXJ5ICYmIHR5cGVvZiBlbGVtZW50LnRvQXJyYXkgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQub24oZWxlbWVudC50b0FycmF5KCkpO1xuICAgIH0gZWxzZSBpZiAoRWxlbWVudCAmJiBlbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgLy9pZiBpdCdzIGFuIGVsZW1lbnQsIGNyZWF0ZSBhIFRhcExpc3RlbmVyXG4gICAgICB2YXIgdGFwID0gbmV3IFRhcExpc3RlbmVyKGVsZW1lbnQsIG9uVGFwKTtcbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMucHVzaCh0YXApO1xuICAgIH1cbiAgICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIEJpbmQgYSBjYWxsYmFjayB0byB3aGVuIHRoZSBhdWRpbyBjb250ZXh0IGlzIHN0YXJ0ZWQuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiXG4gICAqIEByZXR1cm4ge1N0YXJ0QXVkaW9Db250ZXh0fVxuICAgKi9cbiAgU3RhcnRBdWRpb0NvbnRleHQub25TdGFydGVkID0gZnVuY3Rpb24gKGNiKSB7XG4gICAgLy9pZiBpdCdzIGFscmVhZHkgc3RhcnRlZCwgaW52b2tlIHRoZSBjYWxsYmFja1xuICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5pc1N0YXJ0ZWQoKSkge1xuICAgICAgY2IoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZC5wdXNoKGNiKTtcbiAgICB9XG4gICAgcmV0dXJuIFN0YXJ0QXVkaW9Db250ZXh0O1xuICB9O1xuXG4gIC8qKlxuICAgKiByZXR1cm5zIHRydWUgaWYgdGhlIGNvbnRleHQgaXMgc3RhcnRlZFxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgU3RhcnRBdWRpb0NvbnRleHQuaXNTdGFydGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoXG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICE9PSBudWxsICYmXG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0LnN0YXRlID09PSBcInJ1bm5pbmdcIlxuICAgICk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEBjbGFzcyAgTGlzdGVucyBmb3Igbm9uLWRyYWdnaW5nIHRhcCBlbmRzIG9uIHRoZSBnaXZlbiBlbGVtZW50XG4gICAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHZhciBUYXBMaXN0ZW5lciA9IGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgdGhpcy5fZHJhZ2dlZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgICB0aGlzLl9iaW5kZWRNb3ZlID0gdGhpcy5fbW92ZWQuYmluZCh0aGlzKTtcbiAgICB0aGlzLl9iaW5kZWRFbmQgPSB0aGlzLl9lbmRlZC5iaW5kKHRoaXMpO1xuXG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX2JpbmRlZE1vdmUpO1xuICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLl9iaW5kZWRFbmQpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBkcmFnIG1vdmUgZXZlbnRcbiAgICovXG4gIFRhcExpc3RlbmVyLnByb3RvdHlwZS5fbW92ZWQgPSBmdW5jdGlvbiAoZSkge1xuICAgIHRoaXMuX2RyYWdnZWQgPSB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiB0YXAgZW5kZWQgbGlzdGVuZXJcbiAgICovXG4gIFRhcExpc3RlbmVyLnByb3RvdHlwZS5fZW5kZWQgPSBmdW5jdGlvbiAoZSkge1xuICAgIGlmICghdGhpcy5fZHJhZ2dlZCkge1xuICAgICAgb25UYXAoKTtcbiAgICB9XG4gICAgdGhpcy5fZHJhZ2dlZCA9IGZhbHNlO1xuICB9O1xuXG4gIC8qKlxuICAgKiByZW1vdmUgYWxsIHRoZSBib3VuZCBldmVudHNcbiAgICovXG4gIFRhcExpc3RlbmVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCB0aGlzLl9iaW5kZWRNb3ZlKTtcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCB0aGlzLl9iaW5kZWRFbmQpO1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICB0aGlzLl9iaW5kZWRNb3ZlID0gbnVsbDtcbiAgICB0aGlzLl9iaW5kZWRFbmQgPSBudWxsO1xuICAgIHRoaXMuX2VsZW1lbnQgPSBudWxsO1xuICB9O1xuXG4gIC8qKlxuICAgKiBJbnZva2VkIHRoZSBmaXJzdCB0aW1lIG9mIHRoZSBlbGVtZW50cyBpcyB0YXBwZWQuXG4gICAqIENyZWF0ZXMgYSBzaWxlbnQgb3NjaWxsYXRvciB3aGVuIGEgbm9uLWRyYWdnaW5nIHRvdWNoZW5kXG4gICAqIGV2ZW50IGhhcyBiZWVuIHRyaWdnZXJlZC5cbiAgICovXG4gIGZ1bmN0aW9uIG9uVGFwKCkge1xuICAgIC8vc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQgd2l0aCBhIHNpbGVudCBvc2NpbGxhdG9yXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQgJiYgIVN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCgpKSB7XG4gICAgICB2YXIgb3NjID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICB2YXIgc2lsZW50ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICBzaWxlbnQuZ2Fpbi52YWx1ZSA9IDA7XG4gICAgICBvc2MuY29ubmVjdChzaWxlbnQpO1xuICAgICAgc2lsZW50LmNvbm5lY3QoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICB2YXIgbm93ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgIG9zYy5zdGFydChub3cpO1xuICAgICAgb3NjLnN0b3Aobm93ICsgMC41KTtcbiAgICB9XG5cbiAgICAvL2Rpc3Bvc2UgYWxsIHRoZSB0YXAgbGlzdGVuZXJzXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fdGFwTGlzdGVuZXJzW2ldLmRpc3Bvc2UoKTtcbiAgICAgIH1cbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMgPSBudWxsO1xuICAgIH1cbiAgICAvL3RoZSBvbnN0YXJ0ZWQgY2FsbGJhY2tzXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWQpIHtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZC5sZW5ndGg7IGorKykge1xuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkW2pdKCk7XG4gICAgICB9XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG59KTtcbiJdLCJuYW1lcyI6WyJyb290IiwiZmFjdG9yeSIsImRlZmluZSIsImFtZCIsIm1vZHVsZSIsIl90eXBlb2YiLCJleHBvcnRzIiwiU3RhcnRBdWRpb0NvbnRleHQiLCJjb250ZXh0IiwiX3RhcExpc3RlbmVycyIsIl9vblN0YXJ0ZWQiLCJzZXRDb250ZXh0IiwiY3R4Iiwib24iLCJlbGVtZW50IiwiQXJyYXkiLCJpc0FycmF5IiwiTm9kZUxpc3QiLCJpIiwibGVuZ3RoIiwiZG9jdW1lbnQiLCJxdWVyeVNlbGVjdG9yQWxsIiwianF1ZXJ5IiwidG9BcnJheSIsIkVsZW1lbnQiLCJ0YXAiLCJUYXBMaXN0ZW5lciIsIm9uVGFwIiwicHVzaCIsIm9uU3RhcnRlZCIsImNiIiwiaXNTdGFydGVkIiwic3RhdGUiLCJfZHJhZ2dlZCIsIl9lbGVtZW50IiwiX2JpbmRlZE1vdmUiLCJfbW92ZWQiLCJiaW5kIiwiX2JpbmRlZEVuZCIsIl9lbmRlZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJwcm90b3R5cGUiLCJlIiwiZGlzcG9zZSIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJvc2MiLCJjcmVhdGVPc2NpbGxhdG9yIiwic2lsZW50IiwiY3JlYXRlR2FpbiIsImdhaW4iLCJ2YWx1ZSIsImNvbm5lY3QiLCJkZXN0aW5hdGlvbiIsIm5vdyIsImN1cnJlbnRUaW1lIiwic3RhcnQiLCJzdG9wIiwiaiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///631\n')},448:(__unused_webpack_module,exports,__webpack_require__)=>{"use strict";eval('/**\n * @license React\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\nvar aa=__webpack_require__(294),ca=__webpack_require__(840);function p(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;c<arguments.length;c++)b+="&args[]="+encodeURIComponent(arguments[c]);return"Minified React error #"+a+"; visit "+b+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var da=new Set,ea={};function fa(a,b){ha(a,b);ha(a+"Capture",b)}\nfunction ha(a,b){ea[a]=b;for(a=0;a<b.length;a++)da.add(b[a])}\nvar ia=!("undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement),ja=Object.prototype.hasOwnProperty,ka=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,la=\n{},ma={};function oa(a){if(ja.call(ma,a))return!0;if(ja.call(la,a))return!1;if(ka.test(a))return ma[a]=!0;la[a]=!0;return!1}function pa(a,b,c,d){if(null!==c&&0===c.type)return!1;switch(typeof b){case "function":case "symbol":return!0;case "boolean":if(d)return!1;if(null!==c)return!c.acceptsBooleans;a=a.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}\nfunction qa(a,b,c,d){if(null===b||"undefined"===typeof b||pa(a,b,c,d))return!0;if(d)return!1;if(null!==c)switch(c.type){case 3:return!b;case 4:return!1===b;case 5:return isNaN(b);case 6:return isNaN(b)||1>b}return!1}function v(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}var z={};\n"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){z[a]=new v(a,0,!1,a,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];z[b]=new v(b,1,!1,a[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){z[a]=new v(a,2,!1,a.toLowerCase(),null,!1,!1)});\n["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){z[a]=new v(a,2,!1,a,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){z[a]=new v(a,3,!1,a.toLowerCase(),null,!1,!1)});\n["checked","multiple","muted","selected"].forEach(function(a){z[a]=new v(a,3,!0,a,null,!1,!1)});["capture","download"].forEach(function(a){z[a]=new v(a,4,!1,a,null,!1,!1)});["cols","rows","size","span"].forEach(function(a){z[a]=new v(a,6,!1,a,null,!1,!1)});["rowSpan","start"].forEach(function(a){z[a]=new v(a,5,!1,a.toLowerCase(),null,!1,!1)});var ra=/[\\-:]([a-z])/g;function sa(a){return a[1].toUpperCase()}\n"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=a.replace(ra,\nsa);z[b]=new v(b,1,!1,a,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!1,!1)});\nz.xlinkHref=new v("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!0,!0)});\nfunction ta(a,b,c,d){var e=z.hasOwnProperty(b)?z[b]:null;if(null!==e?0!==e.type:d||!(2<b.length)||"o"!==b[0]&&"O"!==b[0]||"n"!==b[1]&&"N"!==b[1])qa(b,c,e,d)&&(c=null),d||null===e?oa(b)&&(null===c?a.removeAttribute(b):a.setAttribute(b,""+c)):e.mustUseProperty?a[e.propertyName]=null===c?3===e.type?!1:"":c:(b=e.attributeName,d=e.attributeNamespace,null===c?a.removeAttribute(b):(e=e.type,c=3===e||4===e&&!0===c?"":""+c,d?a.setAttributeNS(d,b,c):a.setAttribute(b,c)))}\nvar ua=aa.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,va=Symbol.for("react.element"),wa=Symbol.for("react.portal"),ya=Symbol.for("react.fragment"),za=Symbol.for("react.strict_mode"),Aa=Symbol.for("react.profiler"),Ba=Symbol.for("react.provider"),Ca=Symbol.for("react.context"),Da=Symbol.for("react.forward_ref"),Ea=Symbol.for("react.suspense"),Fa=Symbol.for("react.suspense_list"),Ga=Symbol.for("react.memo"),Ha=Symbol.for("react.lazy");Symbol.for("react.scope");Symbol.for("react.debug_trace_mode");\nvar Ia=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden");Symbol.for("react.cache");Symbol.for("react.tracing_marker");var Ja=Symbol.iterator;function Ka(a){if(null===a||"object"!==typeof a)return null;a=Ja&&a[Ja]||a["@@iterator"];return"function"===typeof a?a:null}var A=Object.assign,La;function Ma(a){if(void 0===La)try{throw Error();}catch(c){var b=c.stack.trim().match(/\\n( *(at )?)/);La=b&&b[1]||""}return"\\n"+La+a}var Na=!1;\nfunction Oa(a,b){if(!a||Na)return"";Na=!0;var c=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(b)if(b=function(){throw Error();},Object.defineProperty(b.prototype,"props",{set:function(){throw Error();}}),"object"===typeof Reflect&&Reflect.construct){try{Reflect.construct(b,[])}catch(l){var d=l}Reflect.construct(a,[],b)}else{try{b.call()}catch(l){d=l}a.call(b.prototype)}else{try{throw Error();}catch(l){d=l}a()}}catch(l){if(l&&d&&"string"===typeof l.stack){for(var e=l.stack.split("\\n"),\nf=d.stack.split("\\n"),g=e.length-1,h=f.length-1;1<=g&&0<=h&&e[g]!==f[h];)h--;for(;1<=g&&0<=h;g--,h--)if(e[g]!==f[h]){if(1!==g||1!==h){do if(g--,h--,0>h||e[g]!==f[h]){var k="\\n"+e[g].replace(" at new "," at ");a.displayName&&k.includes("<anonymous>")&&(k=k.replace("<anonymous>",a.displayName));return k}while(1<=g&&0<=h)}break}}}finally{Na=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:"")?Ma(a):""}\nfunction Pa(a){switch(a.tag){case 5:return Ma(a.type);case 16:return Ma("Lazy");case 13:return Ma("Suspense");case 19:return Ma("SuspenseList");case 0:case 2:case 15:return a=Oa(a.type,!1),a;case 11:return a=Oa(a.type.render,!1),a;case 1:return a=Oa(a.type,!0),a;default:return""}}\nfunction Qa(a){if(null==a)return null;if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case ya:return"Fragment";case wa:return"Portal";case Aa:return"Profiler";case za:return"StrictMode";case Ea:return"Suspense";case Fa:return"SuspenseList"}if("object"===typeof a)switch(a.$$typeof){case Ca:return(a.displayName||"Context")+".Consumer";case Ba:return(a._context.displayName||"Context")+".Provider";case Da:var b=a.render;a=a.displayName;a||(a=b.displayName||\nb.name||"",a=""!==a?"ForwardRef("+a+")":"ForwardRef");return a;case Ga:return b=a.displayName||null,null!==b?b:Qa(a.type)||"Memo";case Ha:b=a._payload;a=a._init;try{return Qa(a(b))}catch(c){}}return null}\nfunction Ra(a){var b=a.type;switch(a.tag){case 24:return"Cache";case 9:return(b.displayName||"Context")+".Consumer";case 10:return(b._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return a=b.render,a=a.displayName||a.name||"",b.displayName||(""!==a?"ForwardRef("+a+")":"ForwardRef");case 7:return"Fragment";case 5:return b;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Qa(b);case 8:return b===za?"StrictMode":"Mode";case 22:return"Offscreen";\ncase 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"===typeof b)return b.displayName||b.name||null;if("string"===typeof b)return b}return null}function Sa(a){switch(typeof a){case "boolean":case "number":case "string":case "undefined":return a;case "object":return a;default:return""}}\nfunction Ta(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)}\nfunction Ua(a){var b=Ta(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a,b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker=\nnull;delete a[b]}}}}function Va(a){a._valueTracker||(a._valueTracker=Ua(a))}function Wa(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=Ta(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Xa(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}}\nfunction Ya(a,b){var c=b.checked;return A({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Za(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Sa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function ab(a,b){b=b.checked;null!=b&&ta(a,"checked",b,!1)}\nfunction bb(a,b){ab(a,b);var c=Sa(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?cb(a,b.type,c):b.hasOwnProperty("defaultValue")&&cb(a,b.type,Sa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)}\nfunction db(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d=b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)}\nfunction cb(a,b,c){if("number"!==b||Xa(a.ownerDocument)!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}var eb=Array.isArray;\nfunction fb(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e<c.length;e++)b["$"+c[e]]=!0;for(c=0;c<a.length;c++)e=b.hasOwnProperty("$"+a[c].value),a[c].selected!==e&&(a[c].selected=e),e&&d&&(a[c].defaultSelected=!0)}else{c=""+Sa(c);b=null;for(e=0;e<a.length;e++){if(a[e].value===c){a[e].selected=!0;d&&(a[e].defaultSelected=!0);return}null!==b||a[e].disabled||(b=a[e])}null!==b&&(b.selected=!0)}}\nfunction gb(a,b){if(null!=b.dangerouslySetInnerHTML)throw Error(p(91));return A({},b,{value:void 0,defaultValue:void 0,children:""+a._wrapperState.initialValue})}function hb(a,b){var c=b.value;if(null==c){c=b.children;b=b.defaultValue;if(null!=c){if(null!=b)throw Error(p(92));if(eb(c)){if(1<c.length)throw Error(p(93));c=c[0]}b=c}null==b&&(b="");c=b}a._wrapperState={initialValue:Sa(c)}}\nfunction ib(a,b){var c=Sa(b.value),d=Sa(b.defaultValue);null!=c&&(c=""+c,c!==a.value&&(a.value=c),null==b.defaultValue&&a.defaultValue!==c&&(a.defaultValue=c));null!=d&&(a.defaultValue=""+d)}function jb(a){var b=a.textContent;b===a._wrapperState.initialValue&&""!==b&&null!==b&&(a.value=b)}function kb(a){switch(a){case "svg":return"http://www.w3.org/2000/svg";case "math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}\nfunction lb(a,b){return null==a||"http://www.w3.org/1999/xhtml"===a?kb(b):"http://www.w3.org/2000/svg"===a&&"foreignObject"===b?"http://www.w3.org/1999/xhtml":a}\nvar mb,nb=function(a){return"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(b,c,d,e){MSApp.execUnsafeLocalFunction(function(){return a(b,c,d,e)})}:a}(function(a,b){if("http://www.w3.org/2000/svg"!==a.namespaceURI||"innerHTML"in a)a.innerHTML=b;else{mb=mb||document.createElement("div");mb.innerHTML="<svg>"+b.valueOf().toString()+"</svg>";for(b=mb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}});\nfunction ob(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b}\nvar pb={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,\nzoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qb=["Webkit","ms","Moz","O"];Object.keys(pb).forEach(function(a){qb.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);pb[b]=pb[a]})});function rb(a,b,c){return null==b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||pb.hasOwnProperty(a)&&pb[a]?(""+b).trim():b+"px"}\nfunction sb(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=rb(c,b[c],d);"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}var tb=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});\nfunction ub(a,b){if(b){if(tb[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(p(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(p(60));if("object"!==typeof b.dangerouslySetInnerHTML||!("__html"in b.dangerouslySetInnerHTML))throw Error(p(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(p(62));}}\nfunction vb(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;default:return!0}}var wb=null;function xb(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}var yb=null,zb=null,Ab=null;\nfunction Bb(a){if(a=Cb(a)){if("function"!==typeof yb)throw Error(p(280));var b=a.stateNode;b&&(b=Db(b),yb(a.stateNode,a.type,b))}}function Eb(a){zb?Ab?Ab.push(a):Ab=[a]:zb=a}function Fb(){if(zb){var a=zb,b=Ab;Ab=zb=null;Bb(a);if(b)for(a=0;a<b.length;a++)Bb(b[a])}}function Gb(a,b){return a(b)}function Hb(){}var Ib=!1;function Jb(a,b,c){if(Ib)return a(b,c);Ib=!0;try{return Gb(a,b,c)}finally{if(Ib=!1,null!==zb||null!==Ab)Hb(),Fb()}}\nfunction Kb(a,b){var c=a.stateNode;if(null===c)return null;var d=Db(c);if(null===d)return null;c=d[b];a:switch(b){case "onClick":case "onClickCapture":case "onDoubleClick":case "onDoubleClickCapture":case "onMouseDown":case "onMouseDownCapture":case "onMouseMove":case "onMouseMoveCapture":case "onMouseUp":case "onMouseUpCapture":case "onMouseEnter":(d=!d.disabled)||(a=a.type,d=!("button"===a||"input"===a||"select"===a||"textarea"===a));a=!d;break a;default:a=!1}if(a)return null;if(c&&"function"!==\ntypeof c)throw Error(p(231,b,typeof c));return c}var Lb=!1;if(ia)try{var Mb={};Object.defineProperty(Mb,"passive",{get:function(){Lb=!0}});window.addEventListener("test",Mb,Mb);window.removeEventListener("test",Mb,Mb)}catch(a){Lb=!1}function Nb(a,b,c,d,e,f,g,h,k){var l=Array.prototype.slice.call(arguments,3);try{b.apply(c,l)}catch(m){this.onError(m)}}var Ob=!1,Pb=null,Qb=!1,Rb=null,Sb={onError:function(a){Ob=!0;Pb=a}};function Tb(a,b,c,d,e,f,g,h,k){Ob=!1;Pb=null;Nb.apply(Sb,arguments)}\nfunction Ub(a,b,c,d,e,f,g,h,k){Tb.apply(this,arguments);if(Ob){if(Ob){var l=Pb;Ob=!1;Pb=null}else throw Error(p(198));Qb||(Qb=!0,Rb=l)}}function Vb(a){var b=a,c=a;if(a.alternate)for(;b.return;)b=b.return;else{a=b;do b=a,0!==(b.flags&4098)&&(c=b.return),a=b.return;while(a)}return 3===b.tag?c:null}function Wb(a){if(13===a.tag){var b=a.memoizedState;null===b&&(a=a.alternate,null!==a&&(b=a.memoizedState));if(null!==b)return b.dehydrated}return null}function Xb(a){if(Vb(a)!==a)throw Error(p(188));}\nfunction Yb(a){var b=a.alternate;if(!b){b=Vb(a);if(null===b)throw Error(p(188));return b!==a?null:a}for(var c=a,d=b;;){var e=c.return;if(null===e)break;var f=e.alternate;if(null===f){d=e.return;if(null!==d){c=d;continue}break}if(e.child===f.child){for(f=e.child;f;){if(f===c)return Xb(e),a;if(f===d)return Xb(e),b;f=f.sibling}throw Error(p(188));}if(c.return!==d.return)c=e,d=f;else{for(var g=!1,h=e.child;h;){if(h===c){g=!0;c=e;d=f;break}if(h===d){g=!0;d=e;c=f;break}h=h.sibling}if(!g){for(h=f.child;h;){if(h===\nc){g=!0;c=f;d=e;break}if(h===d){g=!0;d=f;c=e;break}h=h.sibling}if(!g)throw Error(p(189));}}if(c.alternate!==d)throw Error(p(190));}if(3!==c.tag)throw Error(p(188));return c.stateNode.current===c?a:b}function Zb(a){a=Yb(a);return null!==a?$b(a):null}function $b(a){if(5===a.tag||6===a.tag)return a;for(a=a.child;null!==a;){var b=$b(a);if(null!==b)return b;a=a.sibling}return null}\nvar ac=ca.unstable_scheduleCallback,bc=ca.unstable_cancelCallback,cc=ca.unstable_shouldYield,dc=ca.unstable_requestPaint,B=ca.unstable_now,ec=ca.unstable_getCurrentPriorityLevel,fc=ca.unstable_ImmediatePriority,gc=ca.unstable_UserBlockingPriority,hc=ca.unstable_NormalPriority,ic=ca.unstable_LowPriority,jc=ca.unstable_IdlePriority,kc=null,lc=null;function mc(a){if(lc&&"function"===typeof lc.onCommitFiberRoot)try{lc.onCommitFiberRoot(kc,a,void 0,128===(a.current.flags&128))}catch(b){}}\nvar oc=Math.clz32?Math.clz32:nc,pc=Math.log,qc=Math.LN2;function nc(a){a>>>=0;return 0===a?32:31-(pc(a)/qc|0)|0}var rc=64,sc=4194304;\nfunction tc(a){switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;\ndefault:return a}}function uc(a,b){var c=a.pendingLanes;if(0===c)return 0;var d=0,e=a.suspendedLanes,f=a.pingedLanes,g=c&268435455;if(0!==g){var h=g&~e;0!==h?d=tc(h):(f&=g,0!==f&&(d=tc(f)))}else g=c&~e,0!==g?d=tc(g):0!==f&&(d=tc(f));if(0===d)return 0;if(0!==b&&b!==d&&0===(b&e)&&(e=d&-d,f=b&-b,e>=f||16===e&&0!==(f&4194240)))return b;0!==(d&4)&&(d|=c&16);b=a.entangledLanes;if(0!==b)for(a=a.entanglements,b&=d;0<b;)c=31-oc(b),e=1<<c,d|=a[c],b&=~e;return d}\nfunction vc(a,b){switch(a){case 1:case 2:case 4:return b+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return b+5E3;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return-1;case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}\nfunction wc(a,b){for(var c=a.suspendedLanes,d=a.pingedLanes,e=a.expirationTimes,f=a.pendingLanes;0<f;){var g=31-oc(f),h=1<<g,k=e[g];if(-1===k){if(0===(h&c)||0!==(h&d))e[g]=vc(h,b)}else k<=b&&(a.expiredLanes|=h);f&=~h}}function xc(a){a=a.pendingLanes&-1073741825;return 0!==a?a:a&1073741824?1073741824:0}function yc(){var a=rc;rc<<=1;0===(rc&4194240)&&(rc=64);return a}function zc(a){for(var b=[],c=0;31>c;c++)b.push(a);return b}\nfunction Ac(a,b,c){a.pendingLanes|=b;536870912!==b&&(a.suspendedLanes=0,a.pingedLanes=0);a=a.eventTimes;b=31-oc(b);a[b]=c}function Bc(a,b){var c=a.pendingLanes&~b;a.pendingLanes=b;a.suspendedLanes=0;a.pingedLanes=0;a.expiredLanes&=b;a.mutableReadLanes&=b;a.entangledLanes&=b;b=a.entanglements;var d=a.eventTimes;for(a=a.expirationTimes;0<c;){var e=31-oc(c),f=1<<e;b[e]=0;d[e]=-1;a[e]=-1;c&=~f}}\nfunction Cc(a,b){var c=a.entangledLanes|=b;for(a=a.entanglements;c;){var d=31-oc(c),e=1<<d;e&b|a[d]&b&&(a[d]|=b);c&=~e}}var C=0;function Dc(a){a&=-a;return 1<a?4<a?0!==(a&268435455)?16:536870912:4:1}var Ec,Fc,Gc,Hc,Ic,Jc=!1,Kc=[],Lc=null,Mc=null,Nc=null,Oc=new Map,Pc=new Map,Qc=[],Rc="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");\nfunction Sc(a,b){switch(a){case "focusin":case "focusout":Lc=null;break;case "dragenter":case "dragleave":Mc=null;break;case "mouseover":case "mouseout":Nc=null;break;case "pointerover":case "pointerout":Oc.delete(b.pointerId);break;case "gotpointercapture":case "lostpointercapture":Pc.delete(b.pointerId)}}\nfunction Tc(a,b,c,d,e,f){if(null===a||a.nativeEvent!==f)return a={blockedOn:b,domEventName:c,eventSystemFlags:d,nativeEvent:f,targetContainers:[e]},null!==b&&(b=Cb(b),null!==b&&Fc(b)),a;a.eventSystemFlags|=d;b=a.targetContainers;null!==e&&-1===b.indexOf(e)&&b.push(e);return a}\nfunction Uc(a,b,c,d,e){switch(b){case "focusin":return Lc=Tc(Lc,a,b,c,d,e),!0;case "dragenter":return Mc=Tc(Mc,a,b,c,d,e),!0;case "mouseover":return Nc=Tc(Nc,a,b,c,d,e),!0;case "pointerover":var f=e.pointerId;Oc.set(f,Tc(Oc.get(f)||null,a,b,c,d,e));return!0;case "gotpointercapture":return f=e.pointerId,Pc.set(f,Tc(Pc.get(f)||null,a,b,c,d,e)),!0}return!1}\nfunction Vc(a){var b=Wc(a.target);if(null!==b){var c=Vb(b);if(null!==c)if(b=c.tag,13===b){if(b=Wb(c),null!==b){a.blockedOn=b;Ic(a.priority,function(){Gc(c)});return}}else if(3===b&&c.stateNode.current.memoizedState.isDehydrated){a.blockedOn=3===c.tag?c.stateNode.containerInfo:null;return}}a.blockedOn=null}\nfunction Xc(a){if(null!==a.blockedOn)return!1;for(var b=a.targetContainers;0<b.length;){var c=Yc(a.domEventName,a.eventSystemFlags,b[0],a.nativeEvent);if(null===c){c=a.nativeEvent;var d=new c.constructor(c.type,c);wb=d;c.target.dispatchEvent(d);wb=null}else return b=Cb(c),null!==b&&Fc(b),a.blockedOn=c,!1;b.shift()}return!0}function Zc(a,b,c){Xc(a)&&c.delete(b)}function $c(){Jc=!1;null!==Lc&&Xc(Lc)&&(Lc=null);null!==Mc&&Xc(Mc)&&(Mc=null);null!==Nc&&Xc(Nc)&&(Nc=null);Oc.forEach(Zc);Pc.forEach(Zc)}\nfunction ad(a,b){a.blockedOn===b&&(a.blockedOn=null,Jc||(Jc=!0,ca.unstable_scheduleCallback(ca.unstable_NormalPriority,$c)))}\nfunction bd(a){function b(b){return ad(b,a)}if(0<Kc.length){ad(Kc[0],a);for(var c=1;c<Kc.length;c++){var d=Kc[c];d.blockedOn===a&&(d.blockedOn=null)}}null!==Lc&&ad(Lc,a);null!==Mc&&ad(Mc,a);null!==Nc&&ad(Nc,a);Oc.forEach(b);Pc.forEach(b);for(c=0;c<Qc.length;c++)d=Qc[c],d.blockedOn===a&&(d.blockedOn=null);for(;0<Qc.length&&(c=Qc[0],null===c.blockedOn);)Vc(c),null===c.blockedOn&&Qc.shift()}var cd=ua.ReactCurrentBatchConfig,dd=!0;\nfunction ed(a,b,c,d){var e=C,f=cd.transition;cd.transition=null;try{C=1,fd(a,b,c,d)}finally{C=e,cd.transition=f}}function gd(a,b,c,d){var e=C,f=cd.transition;cd.transition=null;try{C=4,fd(a,b,c,d)}finally{C=e,cd.transition=f}}\nfunction fd(a,b,c,d){if(dd){var e=Yc(a,b,c,d);if(null===e)hd(a,b,d,id,c),Sc(a,d);else if(Uc(e,a,b,c,d))d.stopPropagation();else if(Sc(a,d),b&4&&-1<Rc.indexOf(a)){for(;null!==e;){var f=Cb(e);null!==f&&Ec(f);f=Yc(a,b,c,d);null===f&&hd(a,b,d,id,c);if(f===e)break;e=f}null!==e&&d.stopPropagation()}else hd(a,b,d,null,c)}}var id=null;\nfunction Yc(a,b,c,d){id=null;a=xb(d);a=Wc(a);if(null!==a)if(b=Vb(a),null===b)a=null;else if(c=b.tag,13===c){a=Wb(b);if(null!==a)return a;a=null}else if(3===c){if(b.stateNode.current.memoizedState.isDehydrated)return 3===b.tag?b.stateNode.containerInfo:null;a=null}else b!==a&&(a=null);id=a;return null}\nfunction jd(a){switch(a){case "cancel":case "click":case "close":case "contextmenu":case "copy":case "cut":case "auxclick":case "dblclick":case "dragend":case "dragstart":case "drop":case "focusin":case "focusout":case "input":case "invalid":case "keydown":case "keypress":case "keyup":case "mousedown":case "mouseup":case "paste":case "pause":case "play":case "pointercancel":case "pointerdown":case "pointerup":case "ratechange":case "reset":case "resize":case "seeked":case "submit":case "touchcancel":case "touchend":case "touchstart":case "volumechange":case "change":case "selectionchange":case "textInput":case "compositionstart":case "compositionend":case "compositionupdate":case "beforeblur":case "afterblur":case "beforeinput":case "blur":case "fullscreenchange":case "focus":case "hashchange":case "popstate":case "select":case "selectstart":return 1;case "drag":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "mousemove":case "mouseout":case "mouseover":case "pointermove":case "pointerout":case "pointerover":case "scroll":case "toggle":case "touchmove":case "wheel":case "mouseenter":case "mouseleave":case "pointerenter":case "pointerleave":return 4;\ncase "message":switch(ec()){case fc:return 1;case gc:return 4;case hc:case ic:return 16;case jc:return 536870912;default:return 16}default:return 16}}var kd=null,ld=null,md=null;function nd(){if(md)return md;var a,b=ld,c=b.length,d,e="value"in kd?kd.value:kd.textContent,f=e.length;for(a=0;a<c&&b[a]===e[a];a++);var g=c-a;for(d=1;d<=g&&b[c-d]===e[f-d];d++);return md=e.slice(a,1<d?1-d:void 0)}\nfunction od(a){var b=a.keyCode;"charCode"in a?(a=a.charCode,0===a&&13===b&&(a=13)):a=b;10===a&&(a=13);return 32<=a||13===a?a:0}function pd(){return!0}function qd(){return!1}\nfunction rd(a){function b(b,d,e,f,g){this._reactName=b;this._targetInst=e;this.type=d;this.nativeEvent=f;this.target=g;this.currentTarget=null;for(var c in a)a.hasOwnProperty(c)&&(b=a[c],this[c]=b?b(f):f[c]);this.isDefaultPrevented=(null!=f.defaultPrevented?f.defaultPrevented:!1===f.returnValue)?pd:qd;this.isPropagationStopped=qd;return this}A(b.prototype,{preventDefault:function(){this.defaultPrevented=!0;var a=this.nativeEvent;a&&(a.preventDefault?a.preventDefault():"unknown"!==typeof a.returnValue&&\n(a.returnValue=!1),this.isDefaultPrevented=pd)},stopPropagation:function(){var a=this.nativeEvent;a&&(a.stopPropagation?a.stopPropagation():"unknown"!==typeof a.cancelBubble&&(a.cancelBubble=!0),this.isPropagationStopped=pd)},persist:function(){},isPersistent:pd});return b}\nvar sd={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(a){return a.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},td=rd(sd),ud=A({},sd,{view:0,detail:0}),vd=rd(ud),wd,xd,yd,Ad=A({},ud,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:zd,button:0,buttons:0,relatedTarget:function(a){return void 0===a.relatedTarget?a.fromElement===a.srcElement?a.toElement:a.fromElement:a.relatedTarget},movementX:function(a){if("movementX"in\na)return a.movementX;a!==yd&&(yd&&"mousemove"===a.type?(wd=a.screenX-yd.screenX,xd=a.screenY-yd.screenY):xd=wd=0,yd=a);return wd},movementY:function(a){return"movementY"in a?a.movementY:xd}}),Bd=rd(Ad),Cd=A({},Ad,{dataTransfer:0}),Dd=rd(Cd),Ed=A({},ud,{relatedTarget:0}),Fd=rd(Ed),Gd=A({},sd,{animationName:0,elapsedTime:0,pseudoElement:0}),Hd=rd(Gd),Id=A({},sd,{clipboardData:function(a){return"clipboardData"in a?a.clipboardData:window.clipboardData}}),Jd=rd(Id),Kd=A({},sd,{data:0}),Ld=rd(Kd),Md={Esc:"Escape",\nSpacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Nd={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",\n119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Od={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Pd(a){var b=this.nativeEvent;return b.getModifierState?b.getModifierState(a):(a=Od[a])?!!b[a]:!1}function zd(){return Pd}\nvar Qd=A({},ud,{key:function(a){if(a.key){var b=Md[a.key]||a.key;if("Unidentified"!==b)return b}return"keypress"===a.type?(a=od(a),13===a?"Enter":String.fromCharCode(a)):"keydown"===a.type||"keyup"===a.type?Nd[a.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:zd,charCode:function(a){return"keypress"===a.type?od(a):0},keyCode:function(a){return"keydown"===a.type||"keyup"===a.type?a.keyCode:0},which:function(a){return"keypress"===\na.type?od(a):"keydown"===a.type||"keyup"===a.type?a.keyCode:0}}),Rd=rd(Qd),Sd=A({},Ad,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),Td=rd(Sd),Ud=A({},ud,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:zd}),Vd=rd(Ud),Wd=A({},sd,{propertyName:0,elapsedTime:0,pseudoElement:0}),Xd=rd(Wd),Yd=A({},Ad,{deltaX:function(a){return"deltaX"in a?a.deltaX:"wheelDeltaX"in a?-a.wheelDeltaX:0},\ndeltaY:function(a){return"deltaY"in a?a.deltaY:"wheelDeltaY"in a?-a.wheelDeltaY:"wheelDelta"in a?-a.wheelDelta:0},deltaZ:0,deltaMode:0}),Zd=rd(Yd),$d=[9,13,27,32],ae=ia&&"CompositionEvent"in window,be=null;ia&&"documentMode"in document&&(be=document.documentMode);var ce=ia&&"TextEvent"in window&&!be,de=ia&&(!ae||be&&8<be&&11>=be),ee=String.fromCharCode(32),fe=!1;\nfunction ge(a,b){switch(a){case "keyup":return-1!==$d.indexOf(b.keyCode);case "keydown":return 229!==b.keyCode;case "keypress":case "mousedown":case "focusout":return!0;default:return!1}}function he(a){a=a.detail;return"object"===typeof a&&"data"in a?a.data:null}var ie=!1;function je(a,b){switch(a){case "compositionend":return he(b);case "keypress":if(32!==b.which)return null;fe=!0;return ee;case "textInput":return a=b.data,a===ee&&fe?null:a;default:return null}}\nfunction ke(a,b){if(ie)return"compositionend"===a||!ae&&ge(a,b)?(a=nd(),md=ld=kd=null,ie=!1,a):null;switch(a){case "paste":return null;case "keypress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1<b.char.length)return b.char;if(b.which)return String.fromCharCode(b.which)}return null;case "compositionend":return de&&"ko"!==b.locale?null:b.data;default:return null}}\nvar le={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function me(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return"input"===b?!!le[a.type]:"textarea"===b?!0:!1}function ne(a,b,c,d){Eb(d);b=oe(b,"onChange");0<b.length&&(c=new td("onChange","change",null,c,d),a.push({event:c,listeners:b}))}var pe=null,qe=null;function re(a){se(a,0)}function te(a){var b=ue(a);if(Wa(b))return a}\nfunction ve(a,b){if("change"===a)return b}var we=!1;if(ia){var xe;if(ia){var ye="oninput"in document;if(!ye){var ze=document.createElement("div");ze.setAttribute("oninput","return;");ye="function"===typeof ze.oninput}xe=ye}else xe=!1;we=xe&&(!document.documentMode||9<document.documentMode)}function Ae(){pe&&(pe.detachEvent("onpropertychange",Be),qe=pe=null)}function Be(a){if("value"===a.propertyName&&te(qe)){var b=[];ne(b,qe,a,xb(a));Jb(re,b)}}\nfunction Ce(a,b,c){"focusin"===a?(Ae(),pe=b,qe=c,pe.attachEvent("onpropertychange",Be)):"focusout"===a&&Ae()}function De(a){if("selectionchange"===a||"keyup"===a||"keydown"===a)return te(qe)}function Ee(a,b){if("click"===a)return te(b)}function Fe(a,b){if("input"===a||"change"===a)return te(b)}function Ge(a,b){return a===b&&(0!==a||1/a===1/b)||a!==a&&b!==b}var He="function"===typeof Object.is?Object.is:Ge;\nfunction Ie(a,b){if(He(a,b))return!0;if("object"!==typeof a||null===a||"object"!==typeof b||null===b)return!1;var c=Object.keys(a),d=Object.keys(b);if(c.length!==d.length)return!1;for(d=0;d<c.length;d++){var e=c[d];if(!ja.call(b,e)||!He(a[e],b[e]))return!1}return!0}function Je(a){for(;a&&a.firstChild;)a=a.firstChild;return a}\nfunction Ke(a,b){var c=Je(a);a=0;for(var d;c;){if(3===c.nodeType){d=a+c.textContent.length;if(a<=b&&d>=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Je(c)}}function Le(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?Le(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1}\nfunction Me(){for(var a=window,b=Xa();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Xa(a.document)}return b}function Ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)}\nfunction Oe(a){var b=Me(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&Le(c.ownerDocument.documentElement,c)){if(null!==d&&Ne(c))if(b=d.start,a=d.end,void 0===a&&(a=b),"selectionStart"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=Ke(c,f);var g=Ke(c,\nd);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});"function"===typeof c.focus&&c.focus();for(c=0;c<b.length;c++)a=b[c],a.element.scrollLeft=a.left,a.element.scrollTop=a.top}}\nvar Pe=ia&&"documentMode"in document&&11>=document.documentMode,Qe=null,Re=null,Se=null,Te=!1;\nfunction Ue(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;Te||null==Qe||Qe!==Xa(d)||(d=Qe,"selectionStart"in d&&Ne(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Se&&Ie(Se,d)||(Se=d,d=oe(Re,"onSelect"),0<d.length&&(b=new td("onSelect","select",null,b,c),a.push({event:b,listeners:d}),b.target=Qe)))}\nfunction Ve(a,b){var c={};c[a.toLowerCase()]=b.toLowerCase();c["Webkit"+a]="webkit"+b;c["Moz"+a]="moz"+b;return c}var We={animationend:Ve("Animation","AnimationEnd"),animationiteration:Ve("Animation","AnimationIteration"),animationstart:Ve("Animation","AnimationStart"),transitionend:Ve("Transition","TransitionEnd")},Xe={},Ye={};\nia&&(Ye=document.createElement("div").style,"AnimationEvent"in window||(delete We.animationend.animation,delete We.animationiteration.animation,delete We.animationstart.animation),"TransitionEvent"in window||delete We.transitionend.transition);function Ze(a){if(Xe[a])return Xe[a];if(!We[a])return a;var b=We[a],c;for(c in b)if(b.hasOwnProperty(c)&&c in Ye)return Xe[a]=b[c];return a}var $e=Ze("animationend"),af=Ze("animationiteration"),bf=Ze("animationstart"),cf=Ze("transitionend"),df=new Map,ef="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");\nfunction ff(a,b){df.set(a,b);fa(b,[a])}for(var gf=0;gf<ef.length;gf++){var hf=ef[gf],jf=hf.toLowerCase(),kf=hf[0].toUpperCase()+hf.slice(1);ff(jf,"on"+kf)}ff($e,"onAnimationEnd");ff(af,"onAnimationIteration");ff(bf,"onAnimationStart");ff("dblclick","onDoubleClick");ff("focusin","onFocus");ff("focusout","onBlur");ff(cf,"onTransitionEnd");ha("onMouseEnter",["mouseout","mouseover"]);ha("onMouseLeave",["mouseout","mouseover"]);ha("onPointerEnter",["pointerout","pointerover"]);\nha("onPointerLeave",["pointerout","pointerover"]);fa("onChange","change click focusin focusout input keydown keyup selectionchange".split(" "));fa("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" "));fa("onBeforeInput",["compositionend","keypress","textInput","paste"]);fa("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" "));fa("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" "));\nfa("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var lf="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),mf=new Set("cancel close invalid load scroll toggle".split(" ").concat(lf));\nfunction nf(a,b,c){var d=a.type||"unknown-event";a.currentTarget=c;Ub(d,b,void 0,a);a.currentTarget=null}\nfunction se(a,b){b=0!==(b&4);for(var c=0;c<a.length;c++){var d=a[c],e=d.event;d=d.listeners;a:{var f=void 0;if(b)for(var g=d.length-1;0<=g;g--){var h=d[g],k=h.instance,l=h.currentTarget;h=h.listener;if(k!==f&&e.isPropagationStopped())break a;nf(e,h,l);f=k}else for(g=0;g<d.length;g++){h=d[g];k=h.instance;l=h.currentTarget;h=h.listener;if(k!==f&&e.isPropagationStopped())break a;nf(e,h,l);f=k}}}if(Qb)throw a=Rb,Qb=!1,Rb=null,a;}\nfunction D(a,b){var c=b[of];void 0===c&&(c=b[of]=new Set);var d=a+"__bubble";c.has(d)||(pf(b,a,2,!1),c.add(d))}function qf(a,b,c){var d=0;b&&(d|=4);pf(c,a,d,b)}var rf="_reactListening"+Math.random().toString(36).slice(2);function sf(a){if(!a[rf]){a[rf]=!0;da.forEach(function(b){"selectionchange"!==b&&(mf.has(b)||qf(b,!1,a),qf(b,!0,a))});var b=9===a.nodeType?a:a.ownerDocument;null===b||b[rf]||(b[rf]=!0,qf("selectionchange",!1,b))}}\nfunction pf(a,b,c,d){switch(jd(b)){case 1:var e=ed;break;case 4:e=gd;break;default:e=fd}c=e.bind(null,b,c,a);e=void 0;!Lb||"touchstart"!==b&&"touchmove"!==b&&"wheel"!==b||(e=!0);d?void 0!==e?a.addEventListener(b,c,{capture:!0,passive:e}):a.addEventListener(b,c,!0):void 0!==e?a.addEventListener(b,c,{passive:e}):a.addEventListener(b,c,!1)}\nfunction hd(a,b,c,d,e){var f=d;if(0===(b&1)&&0===(b&2)&&null!==d)a:for(;;){if(null===d)return;var g=d.tag;if(3===g||4===g){var h=d.stateNode.containerInfo;if(h===e||8===h.nodeType&&h.parentNode===e)break;if(4===g)for(g=d.return;null!==g;){var k=g.tag;if(3===k||4===k)if(k=g.stateNode.containerInfo,k===e||8===k.nodeType&&k.parentNode===e)return;g=g.return}for(;null!==h;){g=Wc(h);if(null===g)return;k=g.tag;if(5===k||6===k){d=f=g;continue a}h=h.parentNode}}d=d.return}Jb(function(){var d=f,e=xb(c),g=[];\na:{var h=df.get(a);if(void 0!==h){var k=td,n=a;switch(a){case "keypress":if(0===od(c))break a;case "keydown":case "keyup":k=Rd;break;case "focusin":n="focus";k=Fd;break;case "focusout":n="blur";k=Fd;break;case "beforeblur":case "afterblur":k=Fd;break;case "click":if(2===c.button)break a;case "auxclick":case "dblclick":case "mousedown":case "mousemove":case "mouseup":case "mouseout":case "mouseover":case "contextmenu":k=Bd;break;case "drag":case "dragend":case "dragenter":case "dragexit":case "dragleave":case "dragover":case "dragstart":case "drop":k=\nDd;break;case "touchcancel":case "touchend":case "touchmove":case "touchstart":k=Vd;break;case $e:case af:case bf:k=Hd;break;case cf:k=Xd;break;case "scroll":k=vd;break;case "wheel":k=Zd;break;case "copy":case "cut":case "paste":k=Jd;break;case "gotpointercapture":case "lostpointercapture":case "pointercancel":case "pointerdown":case "pointermove":case "pointerout":case "pointerover":case "pointerup":k=Td}var t=0!==(b&4),J=!t&&"scroll"===a,x=t?null!==h?h+"Capture":null:h;t=[];for(var w=d,u;null!==\nw;){u=w;var F=u.stateNode;5===u.tag&&null!==F&&(u=F,null!==x&&(F=Kb(w,x),null!=F&&t.push(tf(w,F,u))));if(J)break;w=w.return}0<t.length&&(h=new k(h,n,null,c,e),g.push({event:h,listeners:t}))}}if(0===(b&7)){a:{h="mouseover"===a||"pointerover"===a;k="mouseout"===a||"pointerout"===a;if(h&&c!==wb&&(n=c.relatedTarget||c.fromElement)&&(Wc(n)||n[uf]))break a;if(k||h){h=e.window===e?e:(h=e.ownerDocument)?h.defaultView||h.parentWindow:window;if(k){if(n=c.relatedTarget||c.toElement,k=d,n=n?Wc(n):null,null!==\nn&&(J=Vb(n),n!==J||5!==n.tag&&6!==n.tag))n=null}else k=null,n=d;if(k!==n){t=Bd;F="onMouseLeave";x="onMouseEnter";w="mouse";if("pointerout"===a||"pointerover"===a)t=Td,F="onPointerLeave",x="onPointerEnter",w="pointer";J=null==k?h:ue(k);u=null==n?h:ue(n);h=new t(F,w+"leave",k,c,e);h.target=J;h.relatedTarget=u;F=null;Wc(e)===d&&(t=new t(x,w+"enter",n,c,e),t.target=u,t.relatedTarget=J,F=t);J=F;if(k&&n)b:{t=k;x=n;w=0;for(u=t;u;u=vf(u))w++;u=0;for(F=x;F;F=vf(F))u++;for(;0<w-u;)t=vf(t),w--;for(;0<u-w;)x=\nvf(x),u--;for(;w--;){if(t===x||null!==x&&t===x.alternate)break b;t=vf(t);x=vf(x)}t=null}else t=null;null!==k&&wf(g,h,k,t,!1);null!==n&&null!==J&&wf(g,J,n,t,!0)}}}a:{h=d?ue(d):window;k=h.nodeName&&h.nodeName.toLowerCase();if("select"===k||"input"===k&&"file"===h.type)var na=ve;else if(me(h))if(we)na=Fe;else{na=De;var xa=Ce}else(k=h.nodeName)&&"input"===k.toLowerCase()&&("checkbox"===h.type||"radio"===h.type)&&(na=Ee);if(na&&(na=na(a,d))){ne(g,na,c,e);break a}xa&&xa(a,h,d);"focusout"===a&&(xa=h._wrapperState)&&\nxa.controlled&&"number"===h.type&&cb(h,"number",h.value)}xa=d?ue(d):window;switch(a){case "focusin":if(me(xa)||"true"===xa.contentEditable)Qe=xa,Re=d,Se=null;break;case "focusout":Se=Re=Qe=null;break;case "mousedown":Te=!0;break;case "contextmenu":case "mouseup":case "dragend":Te=!1;Ue(g,c,e);break;case "selectionchange":if(Pe)break;case "keydown":case "keyup":Ue(g,c,e)}var $a;if(ae)b:{switch(a){case "compositionstart":var ba="onCompositionStart";break b;case "compositionend":ba="onCompositionEnd";\nbreak b;case "compositionupdate":ba="onCompositionUpdate";break b}ba=void 0}else ie?ge(a,c)&&(ba="onCompositionEnd"):"keydown"===a&&229===c.keyCode&&(ba="onCompositionStart");ba&&(de&&"ko"!==c.locale&&(ie||"onCompositionStart"!==ba?"onCompositionEnd"===ba&&ie&&($a=nd()):(kd=e,ld="value"in kd?kd.value:kd.textContent,ie=!0)),xa=oe(d,ba),0<xa.length&&(ba=new Ld(ba,a,null,c,e),g.push({event:ba,listeners:xa}),$a?ba.data=$a:($a=he(c),null!==$a&&(ba.data=$a))));if($a=ce?je(a,c):ke(a,c))d=oe(d,"onBeforeInput"),\n0<d.length&&(e=new Ld("onBeforeInput","beforeinput",null,c,e),g.push({event:e,listeners:d}),e.data=$a)}se(g,b)})}function tf(a,b,c){return{instance:a,listener:b,currentTarget:c}}function oe(a,b){for(var c=b+"Capture",d=[];null!==a;){var e=a,f=e.stateNode;5===e.tag&&null!==f&&(e=f,f=Kb(a,c),null!=f&&d.unshift(tf(a,f,e)),f=Kb(a,b),null!=f&&d.push(tf(a,f,e)));a=a.return}return d}function vf(a){if(null===a)return null;do a=a.return;while(a&&5!==a.tag);return a?a:null}\nfunction wf(a,b,c,d,e){for(var f=b._reactName,g=[];null!==c&&c!==d;){var h=c,k=h.alternate,l=h.stateNode;if(null!==k&&k===d)break;5===h.tag&&null!==l&&(h=l,e?(k=Kb(c,f),null!=k&&g.unshift(tf(c,k,h))):e||(k=Kb(c,f),null!=k&&g.push(tf(c,k,h))));c=c.return}0!==g.length&&a.push({event:b,listeners:g})}var xf=/\\r\\n?/g,yf=/\\u0000|\\uFFFD/g;function zf(a){return("string"===typeof a?a:""+a).replace(xf,"\\n").replace(yf,"")}function Af(a,b,c){b=zf(b);if(zf(a)!==b&&c)throw Error(p(425));}function Bf(){}\nvar Cf=null,Df=null;function Ef(a,b){return"textarea"===a||"noscript"===a||"string"===typeof b.children||"number"===typeof b.children||"object"===typeof b.dangerouslySetInnerHTML&&null!==b.dangerouslySetInnerHTML&&null!=b.dangerouslySetInnerHTML.__html}\nvar Ff="function"===typeof setTimeout?setTimeout:void 0,Gf="function"===typeof clearTimeout?clearTimeout:void 0,Hf="function"===typeof Promise?Promise:void 0,Jf="function"===typeof queueMicrotask?queueMicrotask:"undefined"!==typeof Hf?function(a){return Hf.resolve(null).then(a).catch(If)}:Ff;function If(a){setTimeout(function(){throw a;})}\nfunction Kf(a,b){var c=b,d=0;do{var e=c.nextSibling;a.removeChild(c);if(e&&8===e.nodeType)if(c=e.data,"/$"===c){if(0===d){a.removeChild(e);bd(b);return}d--}else"$"!==c&&"$?"!==c&&"$!"!==c||d++;c=e}while(c);bd(b)}function Lf(a){for(;null!=a;a=a.nextSibling){var b=a.nodeType;if(1===b||3===b)break;if(8===b){b=a.data;if("$"===b||"$!"===b||"$?"===b)break;if("/$"===b)return null}}return a}\nfunction Mf(a){a=a.previousSibling;for(var b=0;a;){if(8===a.nodeType){var c=a.data;if("$"===c||"$!"===c||"$?"===c){if(0===b)return a;b--}else"/$"===c&&b++}a=a.previousSibling}return null}var Nf=Math.random().toString(36).slice(2),Of="__reactFiber$"+Nf,Pf="__reactProps$"+Nf,uf="__reactContainer$"+Nf,of="__reactEvents$"+Nf,Qf="__reactListeners$"+Nf,Rf="__reactHandles$"+Nf;\nfunction Wc(a){var b=a[Of];if(b)return b;for(var c=a.parentNode;c;){if(b=c[uf]||c[Of]){c=b.alternate;if(null!==b.child||null!==c&&null!==c.child)for(a=Mf(a);null!==a;){if(c=a[Of])return c;a=Mf(a)}return b}a=c;c=a.parentNode}return null}function Cb(a){a=a[Of]||a[uf];return!a||5!==a.tag&&6!==a.tag&&13!==a.tag&&3!==a.tag?null:a}function ue(a){if(5===a.tag||6===a.tag)return a.stateNode;throw Error(p(33));}function Db(a){return a[Pf]||null}var Sf=[],Tf=-1;function Uf(a){return{current:a}}\nfunction E(a){0>Tf||(a.current=Sf[Tf],Sf[Tf]=null,Tf--)}function G(a,b){Tf++;Sf[Tf]=a.current;a.current=b}var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a,b){var c=a.type.contextTypes;if(!c)return Vf;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e}\nfunction Zf(a){a=a.childContextTypes;return null!==a&&void 0!==a}function $f(){E(Wf);E(H)}function ag(a,b,c){if(H.current!==Vf)throw Error(p(168));G(H,b);G(Wf,c)}function bg(a,b,c){var d=a.stateNode;b=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in b))throw Error(p(108,Ra(a)||"Unknown",e));return A({},c,d)}\nfunction cg(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Vf;Xf=H.current;G(H,a);G(Wf,Wf.current);return!0}function dg(a,b,c){var d=a.stateNode;if(!d)throw Error(p(169));c?(a=bg(a,b,Xf),d.__reactInternalMemoizedMergedChildContext=a,E(Wf),E(H),G(H,a)):E(Wf);G(Wf,c)}var eg=null,fg=!1,gg=!1;function hg(a){null===eg?eg=[a]:eg.push(a)}function ig(a){fg=!0;hg(a)}\nfunction jg(){if(!gg&&null!==eg){gg=!0;var a=0,b=C;try{var c=eg;for(C=1;a<c.length;a++){var d=c[a];do d=d(!0);while(null!==d)}eg=null;fg=!1}catch(e){throw null!==eg&&(eg=eg.slice(a+1)),ac(fc,jg),e;}finally{C=b,gg=!1}}return null}var kg=[],lg=0,mg=null,ng=0,og=[],pg=0,qg=null,rg=1,sg="";function tg(a,b){kg[lg++]=ng;kg[lg++]=mg;mg=a;ng=b}\nfunction ug(a,b,c){og[pg++]=rg;og[pg++]=sg;og[pg++]=qg;qg=a;var d=rg;a=sg;var e=32-oc(d)-1;d&=~(1<<e);c+=1;var f=32-oc(b)+e;if(30<f){var g=e-e%5;f=(d&(1<<g)-1).toString(32);d>>=g;e-=g;rg=1<<32-oc(b)+e|c<<e|d;sg=f+a}else rg=1<<f|c<<e|d,sg=a}function vg(a){null!==a.return&&(tg(a,1),ug(a,1,0))}function wg(a){for(;a===mg;)mg=kg[--lg],kg[lg]=null,ng=kg[--lg],kg[lg]=null;for(;a===qg;)qg=og[--pg],og[pg]=null,sg=og[--pg],og[pg]=null,rg=og[--pg],og[pg]=null}var xg=null,yg=null,I=!1,zg=null;\nfunction Ag(a,b){var c=Bg(5,null,null,0);c.elementType="DELETED";c.stateNode=b;c.return=a;b=a.deletions;null===b?(a.deletions=[c],a.flags|=16):b.push(c)}\nfunction Cg(a,b){switch(a.tag){case 5:var c=a.type;b=1!==b.nodeType||c.toLowerCase()!==b.nodeName.toLowerCase()?null:b;return null!==b?(a.stateNode=b,xg=a,yg=Lf(b.firstChild),!0):!1;case 6:return b=""===a.pendingProps||3!==b.nodeType?null:b,null!==b?(a.stateNode=b,xg=a,yg=null,!0):!1;case 13:return b=8!==b.nodeType?null:b,null!==b?(c=null!==qg?{id:rg,overflow:sg}:null,a.memoizedState={dehydrated:b,treeContext:c,retryLane:1073741824},c=Bg(18,null,null,0),c.stateNode=b,c.return=a,a.child=c,xg=a,yg=\nnull,!0):!1;default:return!1}}function Dg(a){return 0!==(a.mode&1)&&0===(a.flags&128)}function Eg(a){if(I){var b=yg;if(b){var c=b;if(!Cg(a,b)){if(Dg(a))throw Error(p(418));b=Lf(c.nextSibling);var d=xg;b&&Cg(a,b)?Ag(d,c):(a.flags=a.flags&-4097|2,I=!1,xg=a)}}else{if(Dg(a))throw Error(p(418));a.flags=a.flags&-4097|2;I=!1;xg=a}}}function Fg(a){for(a=a.return;null!==a&&5!==a.tag&&3!==a.tag&&13!==a.tag;)a=a.return;xg=a}\nfunction Gg(a){if(a!==xg)return!1;if(!I)return Fg(a),I=!0,!1;var b;(b=3!==a.tag)&&!(b=5!==a.tag)&&(b=a.type,b="head"!==b&&"body"!==b&&!Ef(a.type,a.memoizedProps));if(b&&(b=yg)){if(Dg(a))throw Hg(),Error(p(418));for(;b;)Ag(a,b),b=Lf(b.nextSibling)}Fg(a);if(13===a.tag){a=a.memoizedState;a=null!==a?a.dehydrated:null;if(!a)throw Error(p(317));a:{a=a.nextSibling;for(b=0;a;){if(8===a.nodeType){var c=a.data;if("/$"===c){if(0===b){yg=Lf(a.nextSibling);break a}b--}else"$"!==c&&"$!"!==c&&"$?"!==c||b++}a=a.nextSibling}yg=\nnull}}else yg=xg?Lf(a.stateNode.nextSibling):null;return!0}function Hg(){for(var a=yg;a;)a=Lf(a.nextSibling)}function Ig(){yg=xg=null;I=!1}function Jg(a){null===zg?zg=[a]:zg.push(a)}var Kg=ua.ReactCurrentBatchConfig;function Lg(a,b){if(a&&a.defaultProps){b=A({},b);a=a.defaultProps;for(var c in a)void 0===b[c]&&(b[c]=a[c]);return b}return b}var Mg=Uf(null),Ng=null,Og=null,Pg=null;function Qg(){Pg=Og=Ng=null}function Rg(a){var b=Mg.current;E(Mg);a._currentValue=b}\nfunction Sg(a,b,c){for(;null!==a;){var d=a.alternate;(a.childLanes&b)!==b?(a.childLanes|=b,null!==d&&(d.childLanes|=b)):null!==d&&(d.childLanes&b)!==b&&(d.childLanes|=b);if(a===c)break;a=a.return}}function Tg(a,b){Ng=a;Pg=Og=null;a=a.dependencies;null!==a&&null!==a.firstContext&&(0!==(a.lanes&b)&&(Ug=!0),a.firstContext=null)}\nfunction Vg(a){var b=a._currentValue;if(Pg!==a)if(a={context:a,memoizedValue:b,next:null},null===Og){if(null===Ng)throw Error(p(308));Og=a;Ng.dependencies={lanes:0,firstContext:a}}else Og=Og.next=a;return b}var Wg=null;function Xg(a){null===Wg?Wg=[a]:Wg.push(a)}function Yg(a,b,c,d){var e=b.interleaved;null===e?(c.next=c,Xg(b)):(c.next=e.next,e.next=c);b.interleaved=c;return Zg(a,d)}\nfunction Zg(a,b){a.lanes|=b;var c=a.alternate;null!==c&&(c.lanes|=b);c=a;for(a=a.return;null!==a;)a.childLanes|=b,c=a.alternate,null!==c&&(c.childLanes|=b),c=a,a=a.return;return 3===c.tag?c.stateNode:null}var $g=!1;function ah(a){a.updateQueue={baseState:a.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}\nfunction bh(a,b){a=a.updateQueue;b.updateQueue===a&&(b.updateQueue={baseState:a.baseState,firstBaseUpdate:a.firstBaseUpdate,lastBaseUpdate:a.lastBaseUpdate,shared:a.shared,effects:a.effects})}function ch(a,b){return{eventTime:a,lane:b,tag:0,payload:null,callback:null,next:null}}\nfunction dh(a,b,c){var d=a.updateQueue;if(null===d)return null;d=d.shared;if(0!==(K&2)){var e=d.pending;null===e?b.next=b:(b.next=e.next,e.next=b);d.pending=b;return Zg(a,c)}e=d.interleaved;null===e?(b.next=b,Xg(d)):(b.next=e.next,e.next=b);d.interleaved=b;return Zg(a,c)}function eh(a,b,c){b=b.updateQueue;if(null!==b&&(b=b.shared,0!==(c&4194240))){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nfunction fh(a,b){var c=a.updateQueue,d=a.alternate;if(null!==d&&(d=d.updateQueue,c===d)){var e=null,f=null;c=c.firstBaseUpdate;if(null!==c){do{var g={eventTime:c.eventTime,lane:c.lane,tag:c.tag,payload:c.payload,callback:c.callback,next:null};null===f?e=f=g:f=f.next=g;c=c.next}while(null!==c);null===f?e=f=b:f=f.next=b}else e=f=b;c={baseState:d.baseState,firstBaseUpdate:e,lastBaseUpdate:f,shared:d.shared,effects:d.effects};a.updateQueue=c;return}a=c.lastBaseUpdate;null===a?c.firstBaseUpdate=b:a.next=\nb;c.lastBaseUpdate=b}\nfunction gh(a,b,c,d){var e=a.updateQueue;$g=!1;var f=e.firstBaseUpdate,g=e.lastBaseUpdate,h=e.shared.pending;if(null!==h){e.shared.pending=null;var k=h,l=k.next;k.next=null;null===g?f=l:g.next=l;g=k;var m=a.alternate;null!==m&&(m=m.updateQueue,h=m.lastBaseUpdate,h!==g&&(null===h?m.firstBaseUpdate=l:h.next=l,m.lastBaseUpdate=k))}if(null!==f){var q=e.baseState;g=0;m=l=k=null;h=f;do{var r=h.lane,y=h.eventTime;if((d&r)===r){null!==m&&(m=m.next={eventTime:y,lane:0,tag:h.tag,payload:h.payload,callback:h.callback,\nnext:null});a:{var n=a,t=h;r=b;y=c;switch(t.tag){case 1:n=t.payload;if("function"===typeof n){q=n.call(y,q,r);break a}q=n;break a;case 3:n.flags=n.flags&-65537|128;case 0:n=t.payload;r="function"===typeof n?n.call(y,q,r):n;if(null===r||void 0===r)break a;q=A({},q,r);break a;case 2:$g=!0}}null!==h.callback&&0!==h.lane&&(a.flags|=64,r=e.effects,null===r?e.effects=[h]:r.push(h))}else y={eventTime:y,lane:r,tag:h.tag,payload:h.payload,callback:h.callback,next:null},null===m?(l=m=y,k=q):m=m.next=y,g|=r;\nh=h.next;if(null===h)if(h=e.shared.pending,null===h)break;else r=h,h=r.next,r.next=null,e.lastBaseUpdate=r,e.shared.pending=null}while(1);null===m&&(k=q);e.baseState=k;e.firstBaseUpdate=l;e.lastBaseUpdate=m;b=e.shared.interleaved;if(null!==b){e=b;do g|=e.lane,e=e.next;while(e!==b)}else null===f&&(e.shared.lanes=0);hh|=g;a.lanes=g;a.memoizedState=q}}\nfunction ih(a,b,c){a=b.effects;b.effects=null;if(null!==a)for(b=0;b<a.length;b++){var d=a[b],e=d.callback;if(null!==e){d.callback=null;d=c;if("function"!==typeof e)throw Error(p(191,e));e.call(d)}}}var jh=(new aa.Component).refs;function kh(a,b,c,d){b=a.memoizedState;c=c(d,b);c=null===c||void 0===c?b:A({},b,c);a.memoizedState=c;0===a.lanes&&(a.updateQueue.baseState=c)}\nvar nh={isMounted:function(a){return(a=a._reactInternals)?Vb(a)===a:!1},enqueueSetState:function(a,b,c){a=a._reactInternals;var d=L(),e=lh(a),f=ch(d,e);f.payload=b;void 0!==c&&null!==c&&(f.callback=c);b=dh(a,f,e);null!==b&&(mh(b,a,e,d),eh(b,a,e))},enqueueReplaceState:function(a,b,c){a=a._reactInternals;var d=L(),e=lh(a),f=ch(d,e);f.tag=1;f.payload=b;void 0!==c&&null!==c&&(f.callback=c);b=dh(a,f,e);null!==b&&(mh(b,a,e,d),eh(b,a,e))},enqueueForceUpdate:function(a,b){a=a._reactInternals;var c=L(),d=\nlh(a),e=ch(c,d);e.tag=2;void 0!==b&&null!==b&&(e.callback=b);b=dh(a,e,d);null!==b&&(mh(b,a,d,c),eh(b,a,d))}};function oh(a,b,c,d,e,f,g){a=a.stateNode;return"function"===typeof a.shouldComponentUpdate?a.shouldComponentUpdate(d,f,g):b.prototype&&b.prototype.isPureReactComponent?!Ie(c,d)||!Ie(e,f):!0}\nfunction ph(a,b,c){var d=!1,e=Vf;var f=b.contextType;"object"===typeof f&&null!==f?f=Vg(f):(e=Zf(b)?Xf:H.current,d=b.contextTypes,f=(d=null!==d&&void 0!==d)?Yf(a,e):Vf);b=new b(c,f);a.memoizedState=null!==b.state&&void 0!==b.state?b.state:null;b.updater=nh;a.stateNode=b;b._reactInternals=a;d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=e,a.__reactInternalMemoizedMaskedChildContext=f);return b}\nfunction qh(a,b,c,d){a=b.state;"function"===typeof b.componentWillReceiveProps&&b.componentWillReceiveProps(c,d);"function"===typeof b.UNSAFE_componentWillReceiveProps&&b.UNSAFE_componentWillReceiveProps(c,d);b.state!==a&&nh.enqueueReplaceState(b,b.state,null)}\nfunction rh(a,b,c,d){var e=a.stateNode;e.props=c;e.state=a.memoizedState;e.refs=jh;ah(a);var f=b.contextType;"object"===typeof f&&null!==f?e.context=Vg(f):(f=Zf(b)?Xf:H.current,e.context=Yf(a,f));e.state=a.memoizedState;f=b.getDerivedStateFromProps;"function"===typeof f&&(kh(a,b,f,c),e.state=a.memoizedState);"function"===typeof b.getDerivedStateFromProps||"function"===typeof e.getSnapshotBeforeUpdate||"function"!==typeof e.UNSAFE_componentWillMount&&"function"!==typeof e.componentWillMount||(b=e.state,\n"function"===typeof e.componentWillMount&&e.componentWillMount(),"function"===typeof e.UNSAFE_componentWillMount&&e.UNSAFE_componentWillMount(),b!==e.state&&nh.enqueueReplaceState(e,e.state,null),gh(a,c,e,d),e.state=a.memoizedState);"function"===typeof e.componentDidMount&&(a.flags|=4194308)}\nfunction sh(a,b,c){a=c.ref;if(null!==a&&"function"!==typeof a&&"object"!==typeof a){if(c._owner){c=c._owner;if(c){if(1!==c.tag)throw Error(p(309));var d=c.stateNode}if(!d)throw Error(p(147,a));var e=d,f=""+a;if(null!==b&&null!==b.ref&&"function"===typeof b.ref&&b.ref._stringRef===f)return b.ref;b=function(a){var b=e.refs;b===jh&&(b=e.refs={});null===a?delete b[f]:b[f]=a};b._stringRef=f;return b}if("string"!==typeof a)throw Error(p(284));if(!c._owner)throw Error(p(290,a));}return a}\nfunction th(a,b){a=Object.prototype.toString.call(b);throw Error(p(31,"[object Object]"===a?"object with keys {"+Object.keys(b).join(", ")+"}":a));}function uh(a){var b=a._init;return b(a._payload)}\nfunction vh(a){function b(b,c){if(a){var d=b.deletions;null===d?(b.deletions=[c],b.flags|=16):d.push(c)}}function c(c,d){if(!a)return null;for(;null!==d;)b(c,d),d=d.sibling;return null}function d(a,b){for(a=new Map;null!==b;)null!==b.key?a.set(b.key,b):a.set(b.index,b),b=b.sibling;return a}function e(a,b){a=wh(a,b);a.index=0;a.sibling=null;return a}function f(b,c,d){b.index=d;if(!a)return b.flags|=1048576,c;d=b.alternate;if(null!==d)return d=d.index,d<c?(b.flags|=2,c):d;b.flags|=2;return c}function g(b){a&&\nnull===b.alternate&&(b.flags|=2);return b}function h(a,b,c,d){if(null===b||6!==b.tag)return b=xh(c,a.mode,d),b.return=a,b;b=e(b,c);b.return=a;return b}function k(a,b,c,d){var f=c.type;if(f===ya)return m(a,b,c.props.children,d,c.key);if(null!==b&&(b.elementType===f||"object"===typeof f&&null!==f&&f.$$typeof===Ha&&uh(f)===b.type))return d=e(b,c.props),d.ref=sh(a,b,c),d.return=a,d;d=yh(c.type,c.key,c.props,null,a.mode,d);d.ref=sh(a,b,c);d.return=a;return d}function l(a,b,c,d){if(null===b||4!==b.tag||\nb.stateNode.containerInfo!==c.containerInfo||b.stateNode.implementation!==c.implementation)return b=zh(c,a.mode,d),b.return=a,b;b=e(b,c.children||[]);b.return=a;return b}function m(a,b,c,d,f){if(null===b||7!==b.tag)return b=Ah(c,a.mode,d,f),b.return=a,b;b=e(b,c);b.return=a;return b}function q(a,b,c){if("string"===typeof b&&""!==b||"number"===typeof b)return b=xh(""+b,a.mode,c),b.return=a,b;if("object"===typeof b&&null!==b){switch(b.$$typeof){case va:return c=yh(b.type,b.key,b.props,null,a.mode,c),\nc.ref=sh(a,null,b),c.return=a,c;case wa:return b=zh(b,a.mode,c),b.return=a,b;case Ha:var d=b._init;return q(a,d(b._payload),c)}if(eb(b)||Ka(b))return b=Ah(b,a.mode,c,null),b.return=a,b;th(a,b)}return null}function r(a,b,c,d){var e=null!==b?b.key:null;if("string"===typeof c&&""!==c||"number"===typeof c)return null!==e?null:h(a,b,""+c,d);if("object"===typeof c&&null!==c){switch(c.$$typeof){case va:return c.key===e?k(a,b,c,d):null;case wa:return c.key===e?l(a,b,c,d):null;case Ha:return e=c._init,r(a,\nb,e(c._payload),d)}if(eb(c)||Ka(c))return null!==e?null:m(a,b,c,d,null);th(a,c)}return null}function y(a,b,c,d,e){if("string"===typeof d&&""!==d||"number"===typeof d)return a=a.get(c)||null,h(b,a,""+d,e);if("object"===typeof d&&null!==d){switch(d.$$typeof){case va:return a=a.get(null===d.key?c:d.key)||null,k(b,a,d,e);case wa:return a=a.get(null===d.key?c:d.key)||null,l(b,a,d,e);case Ha:var f=d._init;return y(a,b,c,f(d._payload),e)}if(eb(d)||Ka(d))return a=a.get(c)||null,m(b,a,d,e,null);th(b,d)}return null}\nfunction n(e,g,h,k){for(var l=null,m=null,u=g,w=g=0,x=null;null!==u&&w<h.length;w++){u.index>w?(x=u,u=null):x=u.sibling;var n=r(e,u,h[w],k);if(null===n){null===u&&(u=x);break}a&&u&&null===n.alternate&&b(e,u);g=f(n,g,w);null===m?l=n:m.sibling=n;m=n;u=x}if(w===h.length)return c(e,u),I&&tg(e,w),l;if(null===u){for(;w<h.length;w++)u=q(e,h[w],k),null!==u&&(g=f(u,g,w),null===m?l=u:m.sibling=u,m=u);I&&tg(e,w);return l}for(u=d(e,u);w<h.length;w++)x=y(u,e,w,h[w],k),null!==x&&(a&&null!==x.alternate&&u.delete(null===\nx.key?w:x.key),g=f(x,g,w),null===m?l=x:m.sibling=x,m=x);a&&u.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function t(e,g,h,k){var l=Ka(h);if("function"!==typeof l)throw Error(p(150));h=l.call(h);if(null==h)throw Error(p(151));for(var u=l=null,m=g,w=g=0,x=null,n=h.next();null!==m&&!n.done;w++,n=h.next()){m.index>w?(x=m,m=null):x=m.sibling;var t=r(e,m,n.value,k);if(null===t){null===m&&(m=x);break}a&&m&&null===t.alternate&&b(e,m);g=f(t,g,w);null===u?l=t:u.sibling=t;u=t;m=x}if(n.done)return c(e,\nm),I&&tg(e,w),l;if(null===m){for(;!n.done;w++,n=h.next())n=q(e,n.value,k),null!==n&&(g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);I&&tg(e,w);return l}for(m=d(e,m);!n.done;w++,n=h.next())n=y(m,e,w,n.value,k),null!==n&&(a&&null!==n.alternate&&m.delete(null===n.key?w:n.key),g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);a&&m.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function J(a,d,f,h){"object"===typeof f&&null!==f&&f.type===ya&&null===f.key&&(f=f.props.children);if("object"===typeof f&&null!==f){switch(f.$$typeof){case va:a:{for(var k=\nf.key,l=d;null!==l;){if(l.key===k){k=f.type;if(k===ya){if(7===l.tag){c(a,l.sibling);d=e(l,f.props.children);d.return=a;a=d;break a}}else if(l.elementType===k||"object"===typeof k&&null!==k&&k.$$typeof===Ha&&uh(k)===l.type){c(a,l.sibling);d=e(l,f.props);d.ref=sh(a,l,f);d.return=a;a=d;break a}c(a,l);break}else b(a,l);l=l.sibling}f.type===ya?(d=Ah(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=yh(f.type,f.key,f.props,null,a.mode,h),h.ref=sh(a,d,f),h.return=a,a=h)}return g(a);case wa:a:{for(l=f.key;null!==\nd;){if(d.key===l)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=zh(f,a.mode,h);d.return=a;a=d}return g(a);case Ha:return l=f._init,J(a,d,l(f._payload),h)}if(eb(f))return n(a,d,f,h);if(Ka(f))return t(a,d,f,h);th(a,f)}return"string"===typeof f&&""!==f||"number"===typeof f?(f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d):\n(c(a,d),d=xh(f,a.mode,h),d.return=a,a=d),g(a)):c(a,d)}return J}var Bh=vh(!0),Ch=vh(!1),Dh={},Eh=Uf(Dh),Fh=Uf(Dh),Gh=Uf(Dh);function Hh(a){if(a===Dh)throw Error(p(174));return a}function Ih(a,b){G(Gh,b);G(Fh,a);G(Eh,Dh);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:lb(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=lb(b,a)}E(Eh);G(Eh,b)}function Jh(){E(Eh);E(Fh);E(Gh)}\nfunction Kh(a){Hh(Gh.current);var b=Hh(Eh.current);var c=lb(b,a.type);b!==c&&(G(Fh,a),G(Eh,c))}function Lh(a){Fh.current===a&&(E(Eh),E(Fh))}var M=Uf(0);\nfunction Mh(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||"$?"===c.data||"$!"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&128))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}var Nh=[];\nfunction Oh(){for(var a=0;a<Nh.length;a++)Nh[a]._workInProgressVersionPrimary=null;Nh.length=0}var Ph=ua.ReactCurrentDispatcher,Qh=ua.ReactCurrentBatchConfig,Rh=0,N=null,O=null,P=null,Sh=!1,Th=!1,Uh=0,Vh=0;function Q(){throw Error(p(321));}function Wh(a,b){if(null===b)return!1;for(var c=0;c<b.length&&c<a.length;c++)if(!He(a[c],b[c]))return!1;return!0}\nfunction Xh(a,b,c,d,e,f){Rh=f;N=b;b.memoizedState=null;b.updateQueue=null;b.lanes=0;Ph.current=null===a||null===a.memoizedState?Yh:Zh;a=c(d,e);if(Th){f=0;do{Th=!1;Uh=0;if(25<=f)throw Error(p(301));f+=1;P=O=null;b.updateQueue=null;Ph.current=$h;a=c(d,e)}while(Th)}Ph.current=ai;b=null!==O&&null!==O.next;Rh=0;P=O=N=null;Sh=!1;if(b)throw Error(p(300));return a}function bi(){var a=0!==Uh;Uh=0;return a}\nfunction ci(){var a={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};null===P?N.memoizedState=P=a:P=P.next=a;return P}function di(){if(null===O){var a=N.alternate;a=null!==a?a.memoizedState:null}else a=O.next;var b=null===P?N.memoizedState:P.next;if(null!==b)P=b,O=a;else{if(null===a)throw Error(p(310));O=a;a={memoizedState:O.memoizedState,baseState:O.baseState,baseQueue:O.baseQueue,queue:O.queue,next:null};null===P?N.memoizedState=P=a:P=P.next=a}return P}\nfunction ei(a,b){return"function"===typeof b?b(a):b}\nfunction fi(a){var b=di(),c=b.queue;if(null===c)throw Error(p(311));c.lastRenderedReducer=a;var d=O,e=d.baseQueue,f=c.pending;if(null!==f){if(null!==e){var g=e.next;e.next=f.next;f.next=g}d.baseQueue=e=f;c.pending=null}if(null!==e){f=e.next;d=d.baseState;var h=g=null,k=null,l=f;do{var m=l.lane;if((Rh&m)===m)null!==k&&(k=k.next={lane:0,action:l.action,hasEagerState:l.hasEagerState,eagerState:l.eagerState,next:null}),d=l.hasEagerState?l.eagerState:a(d,l.action);else{var q={lane:m,action:l.action,hasEagerState:l.hasEagerState,\neagerState:l.eagerState,next:null};null===k?(h=k=q,g=d):k=k.next=q;N.lanes|=m;hh|=m}l=l.next}while(null!==l&&l!==f);null===k?g=d:k.next=h;He(d,b.memoizedState)||(Ug=!0);b.memoizedState=d;b.baseState=g;b.baseQueue=k;c.lastRenderedState=d}a=c.interleaved;if(null!==a){e=a;do f=e.lane,N.lanes|=f,hh|=f,e=e.next;while(e!==a)}else null===e&&(c.lanes=0);return[b.memoizedState,c.dispatch]}\nfunction gi(a){var b=di(),c=b.queue;if(null===c)throw Error(p(311));c.lastRenderedReducer=a;var d=c.dispatch,e=c.pending,f=b.memoizedState;if(null!==e){c.pending=null;var g=e=e.next;do f=a(f,g.action),g=g.next;while(g!==e);He(f,b.memoizedState)||(Ug=!0);b.memoizedState=f;null===b.baseQueue&&(b.baseState=f);c.lastRenderedState=f}return[f,d]}function hi(){}\nfunction ii(a,b){var c=N,d=di(),e=b(),f=!He(d.memoizedState,e);f&&(d.memoizedState=e,Ug=!0);d=d.queue;ji(ki.bind(null,c,d,a),[a]);if(d.getSnapshot!==b||f||null!==P&&P.memoizedState.tag&1){c.flags|=2048;li(9,mi.bind(null,c,d,e,b),void 0,null);if(null===R)throw Error(p(349));0!==(Rh&30)||ni(c,b,e)}return e}function ni(a,b,c){a.flags|=16384;a={getSnapshot:b,value:c};b=N.updateQueue;null===b?(b={lastEffect:null,stores:null},N.updateQueue=b,b.stores=[a]):(c=b.stores,null===c?b.stores=[a]:c.push(a))}\nfunction mi(a,b,c,d){b.value=c;b.getSnapshot=d;oi(b)&&pi(a)}function ki(a,b,c){return c(function(){oi(b)&&pi(a)})}function oi(a){var b=a.getSnapshot;a=a.value;try{var c=b();return!He(a,c)}catch(d){return!0}}function pi(a){var b=Zg(a,1);null!==b&&mh(b,a,1,-1)}\nfunction qi(a){var b=ci();"function"===typeof a&&(a=a());b.memoizedState=b.baseState=a;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:ei,lastRenderedState:a};b.queue=a;a=a.dispatch=ri.bind(null,N,a);return[b.memoizedState,a]}\nfunction li(a,b,c,d){a={tag:a,create:b,destroy:c,deps:d,next:null};b=N.updateQueue;null===b?(b={lastEffect:null,stores:null},N.updateQueue=b,b.lastEffect=a.next=a):(c=b.lastEffect,null===c?b.lastEffect=a.next=a:(d=c.next,c.next=a,a.next=d,b.lastEffect=a));return a}function si(){return di().memoizedState}function ti(a,b,c,d){var e=ci();N.flags|=a;e.memoizedState=li(1|b,c,void 0,void 0===d?null:d)}\nfunction ui(a,b,c,d){var e=di();d=void 0===d?null:d;var f=void 0;if(null!==O){var g=O.memoizedState;f=g.destroy;if(null!==d&&Wh(d,g.deps)){e.memoizedState=li(b,c,f,d);return}}N.flags|=a;e.memoizedState=li(1|b,c,f,d)}function vi(a,b){return ti(8390656,8,a,b)}function ji(a,b){return ui(2048,8,a,b)}function wi(a,b){return ui(4,2,a,b)}function xi(a,b){return ui(4,4,a,b)}\nfunction yi(a,b){if("function"===typeof b)return a=a(),b(a),function(){b(null)};if(null!==b&&void 0!==b)return a=a(),b.current=a,function(){b.current=null}}function zi(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ui(4,4,yi.bind(null,b,a),c)}function Ai(){}function Bi(a,b){var c=di();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&Wh(b,d[1]))return d[0];c.memoizedState=[a,b];return a}\nfunction Ci(a,b){var c=di();b=void 0===b?null:b;var d=c.memoizedState;if(null!==d&&null!==b&&Wh(b,d[1]))return d[0];a=a();c.memoizedState=[a,b];return a}function Di(a,b,c){if(0===(Rh&21))return a.baseState&&(a.baseState=!1,Ug=!0),a.memoizedState=c;He(c,b)||(c=yc(),N.lanes|=c,hh|=c,a.baseState=!0);return b}function Ei(a,b){var c=C;C=0!==c&&4>c?c:4;a(!0);var d=Qh.transition;Qh.transition={};try{a(!1),b()}finally{C=c,Qh.transition=d}}function Fi(){return di().memoizedState}\nfunction Gi(a,b,c){var d=lh(a);c={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,c);else if(c=Yg(a,b,c,d),null!==c){var e=L();mh(c,a,d,e);Ji(c,b,d)}}\nfunction ri(a,b,c){var d=lh(a),e={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,e);else{var f=a.alternate;if(0===a.lanes&&(null===f||0===f.lanes)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,h=f(g,c);e.hasEagerState=!0;e.eagerState=h;if(He(h,g)){var k=b.interleaved;null===k?(e.next=e,Xg(b)):(e.next=k.next,k.next=e);b.interleaved=e;return}}catch(l){}finally{}c=Yg(a,b,e,d);null!==c&&(e=L(),mh(c,a,d,e),Ji(c,b,d))}}\nfunction Hi(a){var b=a.alternate;return a===N||null!==b&&b===N}function Ii(a,b){Th=Sh=!0;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}function Ji(a,b,c){if(0!==(c&4194240)){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}}\nvar ai={readContext:Vg,useCallback:Q,useContext:Q,useEffect:Q,useImperativeHandle:Q,useInsertionEffect:Q,useLayoutEffect:Q,useMemo:Q,useReducer:Q,useRef:Q,useState:Q,useDebugValue:Q,useDeferredValue:Q,useTransition:Q,useMutableSource:Q,useSyncExternalStore:Q,useId:Q,unstable_isNewReconciler:!1},Yh={readContext:Vg,useCallback:function(a,b){ci().memoizedState=[a,void 0===b?null:b];return a},useContext:Vg,useEffect:vi,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ti(4194308,\n4,yi.bind(null,b,a),c)},useLayoutEffect:function(a,b){return ti(4194308,4,a,b)},useInsertionEffect:function(a,b){return ti(4,2,a,b)},useMemo:function(a,b){var c=ci();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=ci();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};d.queue=a;a=a.dispatch=Gi.bind(null,N,a);return[d.memoizedState,a]},useRef:function(a){var b=\nci();a={current:a};return b.memoizedState=a},useState:qi,useDebugValue:Ai,useDeferredValue:function(a){return ci().memoizedState=a},useTransition:function(){var a=qi(!1),b=a[0];a=Ei.bind(null,a[1]);ci().memoizedState=a;return[b,a]},useMutableSource:function(){},useSyncExternalStore:function(a,b,c){var d=N,e=ci();if(I){if(void 0===c)throw Error(p(407));c=c()}else{c=b();if(null===R)throw Error(p(349));0!==(Rh&30)||ni(d,b,c)}e.memoizedState=c;var f={value:c,getSnapshot:b};e.queue=f;vi(ki.bind(null,d,\nf,a),[a]);d.flags|=2048;li(9,mi.bind(null,d,f,c,b),void 0,null);return c},useId:function(){var a=ci(),b=R.identifierPrefix;if(I){var c=sg;var d=rg;c=(d&~(1<<32-oc(d)-1)).toString(32)+c;b=":"+b+"R"+c;c=Uh++;0<c&&(b+="H"+c.toString(32));b+=":"}else c=Vh++,b=":"+b+"r"+c.toString(32)+":";return a.memoizedState=b},unstable_isNewReconciler:!1},Zh={readContext:Vg,useCallback:Bi,useContext:Vg,useEffect:ji,useImperativeHandle:zi,useInsertionEffect:wi,useLayoutEffect:xi,useMemo:Ci,useReducer:fi,useRef:si,useState:function(){return fi(ei)},\nuseDebugValue:Ai,useDeferredValue:function(a){var b=di();return Di(b,O.memoizedState,a)},useTransition:function(){var a=fi(ei)[0],b=di().memoizedState;return[a,b]},useMutableSource:hi,useSyncExternalStore:ii,useId:Fi,unstable_isNewReconciler:!1},$h={readContext:Vg,useCallback:Bi,useContext:Vg,useEffect:ji,useImperativeHandle:zi,useInsertionEffect:wi,useLayoutEffect:xi,useMemo:Ci,useReducer:gi,useRef:si,useState:function(){return gi(ei)},useDebugValue:Ai,useDeferredValue:function(a){var b=di();return null===\nO?b.memoizedState=a:Di(b,O.memoizedState,a)},useTransition:function(){var a=gi(ei)[0],b=di().memoizedState;return[a,b]},useMutableSource:hi,useSyncExternalStore:ii,useId:Fi,unstable_isNewReconciler:!1};function Ki(a,b){try{var c="",d=b;do c+=Pa(d),d=d.return;while(d);var e=c}catch(f){e="\\nError generating stack: "+f.message+"\\n"+f.stack}return{value:a,source:b,stack:e,digest:null}}function Li(a,b,c){return{value:a,source:null,stack:null!=c?c:null,digest:null!=b?b:null}}\nfunction Mi(a,b){try{console.error(b.value)}catch(c){setTimeout(function(){throw c;})}}var Ni="function"===typeof WeakMap?WeakMap:Map;function Oi(a,b,c){c=ch(-1,c);c.tag=3;c.payload={element:null};var d=b.value;c.callback=function(){Pi||(Pi=!0,Qi=d);Mi(a,b)};return c}\nfunction Ri(a,b,c){c=ch(-1,c);c.tag=3;var d=a.type.getDerivedStateFromError;if("function"===typeof d){var e=b.value;c.payload=function(){return d(e)};c.callback=function(){Mi(a,b)}}var f=a.stateNode;null!==f&&"function"===typeof f.componentDidCatch&&(c.callback=function(){Mi(a,b);"function"!==typeof d&&(null===Si?Si=new Set([this]):Si.add(this));var c=b.stack;this.componentDidCatch(b.value,{componentStack:null!==c?c:""})});return c}\nfunction Ti(a,b,c){var d=a.pingCache;if(null===d){d=a.pingCache=new Ni;var e=new Set;d.set(b,e)}else e=d.get(b),void 0===e&&(e=new Set,d.set(b,e));e.has(c)||(e.add(c),a=Ui.bind(null,a,b,c),b.then(a,a))}function Vi(a){do{var b;if(b=13===a.tag)b=a.memoizedState,b=null!==b?null!==b.dehydrated?!0:!1:!0;if(b)return a;a=a.return}while(null!==a);return null}\nfunction Wi(a,b,c,d,e){if(0===(a.mode&1))return a===b?a.flags|=65536:(a.flags|=128,c.flags|=131072,c.flags&=-52805,1===c.tag&&(null===c.alternate?c.tag=17:(b=ch(-1,1),b.tag=2,dh(c,b,1))),c.lanes|=1),a;a.flags|=65536;a.lanes=e;return a}var Xi=ua.ReactCurrentOwner,Ug=!1;function Yi(a,b,c,d){b.child=null===a?Ch(b,null,c,d):Bh(b,a.child,c,d)}\nfunction Zi(a,b,c,d,e){c=c.render;var f=b.ref;Tg(b,e);d=Xh(a,b,c,d,f,e);c=bi();if(null!==a&&!Ug)return b.updateQueue=a.updateQueue,b.flags&=-2053,a.lanes&=~e,$i(a,b,e);I&&c&&vg(b);b.flags|=1;Yi(a,b,d,e);return b.child}\nfunction aj(a,b,c,d,e){if(null===a){var f=c.type;if("function"===typeof f&&!bj(f)&&void 0===f.defaultProps&&null===c.compare&&void 0===c.defaultProps)return b.tag=15,b.type=f,cj(a,b,f,d,e);a=yh(c.type,null,d,b,b.mode,e);a.ref=b.ref;a.return=b;return b.child=a}f=a.child;if(0===(a.lanes&e)){var g=f.memoizedProps;c=c.compare;c=null!==c?c:Ie;if(c(g,d)&&a.ref===b.ref)return $i(a,b,e)}b.flags|=1;a=wh(f,d);a.ref=b.ref;a.return=b;return b.child=a}\nfunction cj(a,b,c,d,e){if(null!==a){var f=a.memoizedProps;if(Ie(f,d)&&a.ref===b.ref)if(Ug=!1,b.pendingProps=d=f,0!==(a.lanes&e))0!==(a.flags&131072)&&(Ug=!0);else return b.lanes=a.lanes,$i(a,b,e)}return dj(a,b,c,d,e)}\nfunction ej(a,b,c){var d=b.pendingProps,e=d.children,f=null!==a?a.memoizedState:null;if("hidden"===d.mode)if(0===(b.mode&1))b.memoizedState={baseLanes:0,cachePool:null,transitions:null},G(fj,gj),gj|=c;else{if(0===(c&1073741824))return a=null!==f?f.baseLanes|c:c,b.lanes=b.childLanes=1073741824,b.memoizedState={baseLanes:a,cachePool:null,transitions:null},b.updateQueue=null,G(fj,gj),gj|=a,null;b.memoizedState={baseLanes:0,cachePool:null,transitions:null};d=null!==f?f.baseLanes:c;G(fj,gj);gj|=d}else null!==\nf?(d=f.baseLanes|c,b.memoizedState=null):d=c,G(fj,gj),gj|=d;Yi(a,b,e,c);return b.child}function hj(a,b){var c=b.ref;if(null===a&&null!==c||null!==a&&a.ref!==c)b.flags|=512,b.flags|=2097152}function dj(a,b,c,d,e){var f=Zf(c)?Xf:H.current;f=Yf(b,f);Tg(b,e);c=Xh(a,b,c,d,f,e);d=bi();if(null!==a&&!Ug)return b.updateQueue=a.updateQueue,b.flags&=-2053,a.lanes&=~e,$i(a,b,e);I&&d&&vg(b);b.flags|=1;Yi(a,b,c,e);return b.child}\nfunction ij(a,b,c,d,e){if(Zf(c)){var f=!0;cg(b)}else f=!1;Tg(b,e);if(null===b.stateNode)jj(a,b),ph(b,c,d),rh(b,c,d,e),d=!0;else if(null===a){var g=b.stateNode,h=b.memoizedProps;g.props=h;var k=g.context,l=c.contextType;"object"===typeof l&&null!==l?l=Vg(l):(l=Zf(c)?Xf:H.current,l=Yf(b,l));var m=c.getDerivedStateFromProps,q="function"===typeof m||"function"===typeof g.getSnapshotBeforeUpdate;q||"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||\n(h!==d||k!==l)&&qh(b,g,d,l);$g=!1;var r=b.memoizedState;g.state=r;gh(b,d,g,e);k=b.memoizedState;h!==d||r!==k||Wf.current||$g?("function"===typeof m&&(kh(b,c,m,d),k=b.memoizedState),(h=$g||oh(b,c,h,d,r,k,l))?(q||"function"!==typeof g.UNSAFE_componentWillMount&&"function"!==typeof g.componentWillMount||("function"===typeof g.componentWillMount&&g.componentWillMount(),"function"===typeof g.UNSAFE_componentWillMount&&g.UNSAFE_componentWillMount()),"function"===typeof g.componentDidMount&&(b.flags|=4194308)):\n("function"===typeof g.componentDidMount&&(b.flags|=4194308),b.memoizedProps=d,b.memoizedState=k),g.props=d,g.state=k,g.context=l,d=h):("function"===typeof g.componentDidMount&&(b.flags|=4194308),d=!1)}else{g=b.stateNode;bh(a,b);h=b.memoizedProps;l=b.type===b.elementType?h:Lg(b.type,h);g.props=l;q=b.pendingProps;r=g.context;k=c.contextType;"object"===typeof k&&null!==k?k=Vg(k):(k=Zf(c)?Xf:H.current,k=Yf(b,k));var y=c.getDerivedStateFromProps;(m="function"===typeof y||"function"===typeof g.getSnapshotBeforeUpdate)||\n"function"!==typeof g.UNSAFE_componentWillReceiveProps&&"function"!==typeof g.componentWillReceiveProps||(h!==q||r!==k)&&qh(b,g,d,k);$g=!1;r=b.memoizedState;g.state=r;gh(b,d,g,e);var n=b.memoizedState;h!==q||r!==n||Wf.current||$g?("function"===typeof y&&(kh(b,c,y,d),n=b.memoizedState),(l=$g||oh(b,c,l,d,r,n,k)||!1)?(m||"function"!==typeof g.UNSAFE_componentWillUpdate&&"function"!==typeof g.componentWillUpdate||("function"===typeof g.componentWillUpdate&&g.componentWillUpdate(d,n,k),"function"===typeof g.UNSAFE_componentWillUpdate&&\ng.UNSAFE_componentWillUpdate(d,n,k)),"function"===typeof g.componentDidUpdate&&(b.flags|=4),"function"===typeof g.getSnapshotBeforeUpdate&&(b.flags|=1024)):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=1024),b.memoizedProps=d,b.memoizedState=n),g.props=d,g.state=n,g.context=k,d=l):("function"!==typeof g.componentDidUpdate||h===a.memoizedProps&&r===\na.memoizedState||(b.flags|=4),"function"!==typeof g.getSnapshotBeforeUpdate||h===a.memoizedProps&&r===a.memoizedState||(b.flags|=1024),d=!1)}return kj(a,b,c,d,f,e)}\nfunction kj(a,b,c,d,e,f){hj(a,b);var g=0!==(b.flags&128);if(!d&&!g)return e&&dg(b,c,!1),$i(a,b,f);d=b.stateNode;Xi.current=b;var h=g&&"function"!==typeof c.getDerivedStateFromError?null:d.render();b.flags|=1;null!==a&&g?(b.child=Bh(b,a.child,null,f),b.child=Bh(b,null,h,f)):Yi(a,b,h,f);b.memoizedState=d.state;e&&dg(b,c,!0);return b.child}function lj(a){var b=a.stateNode;b.pendingContext?ag(a,b.pendingContext,b.pendingContext!==b.context):b.context&&ag(a,b.context,!1);Ih(a,b.containerInfo)}\nfunction mj(a,b,c,d,e){Ig();Jg(e);b.flags|=256;Yi(a,b,c,d);return b.child}var nj={dehydrated:null,treeContext:null,retryLane:0};function oj(a){return{baseLanes:a,cachePool:null,transitions:null}}\nfunction pj(a,b,c){var d=b.pendingProps,e=M.current,f=!1,g=0!==(b.flags&128),h;(h=g)||(h=null!==a&&null===a.memoizedState?!1:0!==(e&2));if(h)f=!0,b.flags&=-129;else if(null===a||null!==a.memoizedState)e|=1;G(M,e&1);if(null===a){Eg(b);a=b.memoizedState;if(null!==a&&(a=a.dehydrated,null!==a))return 0===(b.mode&1)?b.lanes=1:"$!"===a.data?b.lanes=8:b.lanes=1073741824,null;g=d.children;a=d.fallback;return f?(d=b.mode,f=b.child,g={mode:"hidden",children:g},0===(d&1)&&null!==f?(f.childLanes=0,f.pendingProps=\ng):f=qj(g,d,0,null),a=Ah(a,d,c,null),f.return=b,a.return=b,f.sibling=a,b.child=f,b.child.memoizedState=oj(c),b.memoizedState=nj,a):rj(b,g)}e=a.memoizedState;if(null!==e&&(h=e.dehydrated,null!==h))return sj(a,b,g,d,h,e,c);if(f){f=d.fallback;g=b.mode;e=a.child;h=e.sibling;var k={mode:"hidden",children:d.children};0===(g&1)&&b.child!==e?(d=b.child,d.childLanes=0,d.pendingProps=k,b.deletions=null):(d=wh(e,k),d.subtreeFlags=e.subtreeFlags&14680064);null!==h?f=wh(h,f):(f=Ah(f,g,c,null),f.flags|=2);f.return=\nb;d.return=b;d.sibling=f;b.child=d;d=f;f=b.child;g=a.child.memoizedState;g=null===g?oj(c):{baseLanes:g.baseLanes|c,cachePool:null,transitions:g.transitions};f.memoizedState=g;f.childLanes=a.childLanes&~c;b.memoizedState=nj;return d}f=a.child;a=f.sibling;d=wh(f,{mode:"visible",children:d.children});0===(b.mode&1)&&(d.lanes=c);d.return=b;d.sibling=null;null!==a&&(c=b.deletions,null===c?(b.deletions=[a],b.flags|=16):c.push(a));b.child=d;b.memoizedState=null;return d}\nfunction rj(a,b){b=qj({mode:"visible",children:b},a.mode,0,null);b.return=a;return a.child=b}function tj(a,b,c,d){null!==d&&Jg(d);Bh(b,a.child,null,c);a=rj(b,b.pendingProps.children);a.flags|=2;b.memoizedState=null;return a}\nfunction sj(a,b,c,d,e,f,g){if(c){if(b.flags&256)return b.flags&=-257,d=Li(Error(p(422))),tj(a,b,g,d);if(null!==b.memoizedState)return b.child=a.child,b.flags|=128,null;f=d.fallback;e=b.mode;d=qj({mode:"visible",children:d.children},e,0,null);f=Ah(f,e,g,null);f.flags|=2;d.return=b;f.return=b;d.sibling=f;b.child=d;0!==(b.mode&1)&&Bh(b,a.child,null,g);b.child.memoizedState=oj(g);b.memoizedState=nj;return f}if(0===(b.mode&1))return tj(a,b,g,null);if("$!"===e.data){d=e.nextSibling&&e.nextSibling.dataset;\nif(d)var h=d.dgst;d=h;f=Error(p(419));d=Li(f,d,void 0);return tj(a,b,g,d)}h=0!==(g&a.childLanes);if(Ug||h){d=R;if(null!==d){switch(g&-g){case 4:e=2;break;case 16:e=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:e=32;break;case 536870912:e=268435456;break;default:e=0}e=0!==(e&(d.suspendedLanes|g))?0:e;\n0!==e&&e!==f.retryLane&&(f.retryLane=e,Zg(a,e),mh(d,a,e,-1))}uj();d=Li(Error(p(421)));return tj(a,b,g,d)}if("$?"===e.data)return b.flags|=128,b.child=a.child,b=vj.bind(null,a),e._reactRetry=b,null;a=f.treeContext;yg=Lf(e.nextSibling);xg=b;I=!0;zg=null;null!==a&&(og[pg++]=rg,og[pg++]=sg,og[pg++]=qg,rg=a.id,sg=a.overflow,qg=b);b=rj(b,d.children);b.flags|=4096;return b}function wj(a,b,c){a.lanes|=b;var d=a.alternate;null!==d&&(d.lanes|=b);Sg(a.return,b,c)}\nfunction xj(a,b,c,d,e){var f=a.memoizedState;null===f?a.memoizedState={isBackwards:b,rendering:null,renderingStartTime:0,last:d,tail:c,tailMode:e}:(f.isBackwards=b,f.rendering=null,f.renderingStartTime=0,f.last=d,f.tail=c,f.tailMode=e)}\nfunction yj(a,b,c){var d=b.pendingProps,e=d.revealOrder,f=d.tail;Yi(a,b,d.children,c);d=M.current;if(0!==(d&2))d=d&1|2,b.flags|=128;else{if(null!==a&&0!==(a.flags&128))a:for(a=b.child;null!==a;){if(13===a.tag)null!==a.memoizedState&&wj(a,c,b);else if(19===a.tag)wj(a,c,b);else if(null!==a.child){a.child.return=a;a=a.child;continue}if(a===b)break a;for(;null===a.sibling;){if(null===a.return||a.return===b)break a;a=a.return}a.sibling.return=a.return;a=a.sibling}d&=1}G(M,d);if(0===(b.mode&1))b.memoizedState=\nnull;else switch(e){case "forwards":c=b.child;for(e=null;null!==c;)a=c.alternate,null!==a&&null===Mh(a)&&(e=c),c=c.sibling;c=e;null===c?(e=b.child,b.child=null):(e=c.sibling,c.sibling=null);xj(b,!1,e,c,f);break;case "backwards":c=null;e=b.child;for(b.child=null;null!==e;){a=e.alternate;if(null!==a&&null===Mh(a)){b.child=e;break}a=e.sibling;e.sibling=c;c=e;e=a}xj(b,!0,c,null,f);break;case "together":xj(b,!1,null,null,void 0);break;default:b.memoizedState=null}return b.child}\nfunction jj(a,b){0===(b.mode&1)&&null!==a&&(a.alternate=null,b.alternate=null,b.flags|=2)}function $i(a,b,c){null!==a&&(b.dependencies=a.dependencies);hh|=b.lanes;if(0===(c&b.childLanes))return null;if(null!==a&&b.child!==a.child)throw Error(p(153));if(null!==b.child){a=b.child;c=wh(a,a.pendingProps);b.child=c;for(c.return=b;null!==a.sibling;)a=a.sibling,c=c.sibling=wh(a,a.pendingProps),c.return=b;c.sibling=null}return b.child}\nfunction zj(a,b,c){switch(b.tag){case 3:lj(b);Ig();break;case 5:Kh(b);break;case 1:Zf(b.type)&&cg(b);break;case 4:Ih(b,b.stateNode.containerInfo);break;case 10:var d=b.type._context,e=b.memoizedProps.value;G(Mg,d._currentValue);d._currentValue=e;break;case 13:d=b.memoizedState;if(null!==d){if(null!==d.dehydrated)return G(M,M.current&1),b.flags|=128,null;if(0!==(c&b.child.childLanes))return pj(a,b,c);G(M,M.current&1);a=$i(a,b,c);return null!==a?a.sibling:null}G(M,M.current&1);break;case 19:d=0!==(c&\nb.childLanes);if(0!==(a.flags&128)){if(d)return yj(a,b,c);b.flags|=128}e=b.memoizedState;null!==e&&(e.rendering=null,e.tail=null,e.lastEffect=null);G(M,M.current);if(d)break;else return null;case 22:case 23:return b.lanes=0,ej(a,b,c)}return $i(a,b,c)}var Aj,Bj,Cj,Dj;\nAj=function(a,b){for(var c=b.child;null!==c;){if(5===c.tag||6===c.tag)a.appendChild(c.stateNode);else if(4!==c.tag&&null!==c.child){c.child.return=c;c=c.child;continue}if(c===b)break;for(;null===c.sibling;){if(null===c.return||c.return===b)return;c=c.return}c.sibling.return=c.return;c=c.sibling}};Bj=function(){};\nCj=function(a,b,c,d){var e=a.memoizedProps;if(e!==d){a=b.stateNode;Hh(Eh.current);var f=null;switch(c){case "input":e=Ya(a,e);d=Ya(a,d);f=[];break;case "select":e=A({},e,{value:void 0});d=A({},d,{value:void 0});f=[];break;case "textarea":e=gb(a,e);d=gb(a,d);f=[];break;default:"function"!==typeof e.onClick&&"function"===typeof d.onClick&&(a.onclick=Bf)}ub(c,d);var g;c=null;for(l in e)if(!d.hasOwnProperty(l)&&e.hasOwnProperty(l)&&null!=e[l])if("style"===l){var h=e[l];for(g in h)h.hasOwnProperty(g)&&\n(c||(c={}),c[g]="")}else"dangerouslySetInnerHTML"!==l&&"children"!==l&&"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&"autoFocus"!==l&&(ea.hasOwnProperty(l)?f||(f=[]):(f=f||[]).push(l,null));for(l in d){var k=d[l];h=null!=e?e[l]:void 0;if(d.hasOwnProperty(l)&&k!==h&&(null!=k||null!=h))if("style"===l)if(h){for(g in h)!h.hasOwnProperty(g)||k&&k.hasOwnProperty(g)||(c||(c={}),c[g]="");for(g in k)k.hasOwnProperty(g)&&h[g]!==k[g]&&(c||(c={}),c[g]=k[g])}else c||(f||(f=[]),f.push(l,\nc)),c=k;else"dangerouslySetInnerHTML"===l?(k=k?k.__html:void 0,h=h?h.__html:void 0,null!=k&&h!==k&&(f=f||[]).push(l,k)):"children"===l?"string"!==typeof k&&"number"!==typeof k||(f=f||[]).push(l,""+k):"suppressContentEditableWarning"!==l&&"suppressHydrationWarning"!==l&&(ea.hasOwnProperty(l)?(null!=k&&"onScroll"===l&&D("scroll",a),f||h===k||(f=[])):(f=f||[]).push(l,k))}c&&(f=f||[]).push("style",c);var l=f;if(b.updateQueue=l)b.flags|=4}};Dj=function(a,b,c,d){c!==d&&(b.flags|=4)};\nfunction Ej(a,b){if(!I)switch(a.tailMode){case "hidden":b=a.tail;for(var c=null;null!==b;)null!==b.alternate&&(c=b),b=b.sibling;null===c?a.tail=null:c.sibling=null;break;case "collapsed":c=a.tail;for(var d=null;null!==c;)null!==c.alternate&&(d=c),c=c.sibling;null===d?b||null===a.tail?a.tail=null:a.tail.sibling=null:d.sibling=null}}\nfunction S(a){var b=null!==a.alternate&&a.alternate.child===a.child,c=0,d=0;if(b)for(var e=a.child;null!==e;)c|=e.lanes|e.childLanes,d|=e.subtreeFlags&14680064,d|=e.flags&14680064,e.return=a,e=e.sibling;else for(e=a.child;null!==e;)c|=e.lanes|e.childLanes,d|=e.subtreeFlags,d|=e.flags,e.return=a,e=e.sibling;a.subtreeFlags|=d;a.childLanes=c;return b}\nfunction Fj(a,b,c){var d=b.pendingProps;wg(b);switch(b.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return S(b),null;case 1:return Zf(b.type)&&$f(),S(b),null;case 3:d=b.stateNode;Jh();E(Wf);E(H);Oh();d.pendingContext&&(d.context=d.pendingContext,d.pendingContext=null);if(null===a||null===a.child)Gg(b)?b.flags|=4:null===a||a.memoizedState.isDehydrated&&0===(b.flags&256)||(b.flags|=1024,null!==zg&&(Gj(zg),zg=null));Bj(a,b);S(b);return null;case 5:Lh(b);var e=Hh(Gh.current);\nc=b.type;if(null!==a&&null!=b.stateNode)Cj(a,b,c,d,e),a.ref!==b.ref&&(b.flags|=512,b.flags|=2097152);else{if(!d){if(null===b.stateNode)throw Error(p(166));S(b);return null}a=Hh(Eh.current);if(Gg(b)){d=b.stateNode;c=b.type;var f=b.memoizedProps;d[Of]=b;d[Pf]=f;a=0!==(b.mode&1);switch(c){case "dialog":D("cancel",d);D("close",d);break;case "iframe":case "object":case "embed":D("load",d);break;case "video":case "audio":for(e=0;e<lf.length;e++)D(lf[e],d);break;case "source":D("error",d);break;case "img":case "image":case "link":D("error",\nd);D("load",d);break;case "details":D("toggle",d);break;case "input":Za(d,f);D("invalid",d);break;case "select":d._wrapperState={wasMultiple:!!f.multiple};D("invalid",d);break;case "textarea":hb(d,f),D("invalid",d)}ub(c,f);e=null;for(var g in f)if(f.hasOwnProperty(g)){var h=f[g];"children"===g?"string"===typeof h?d.textContent!==h&&(!0!==f.suppressHydrationWarning&&Af(d.textContent,h,a),e=["children",h]):"number"===typeof h&&d.textContent!==""+h&&(!0!==f.suppressHydrationWarning&&Af(d.textContent,\nh,a),e=["children",""+h]):ea.hasOwnProperty(g)&&null!=h&&"onScroll"===g&&D("scroll",d)}switch(c){case "input":Va(d);db(d,f,!0);break;case "textarea":Va(d);jb(d);break;case "select":case "option":break;default:"function"===typeof f.onClick&&(d.onclick=Bf)}d=e;b.updateQueue=d;null!==d&&(b.flags|=4)}else{g=9===e.nodeType?e:e.ownerDocument;"http://www.w3.org/1999/xhtml"===a&&(a=kb(c));"http://www.w3.org/1999/xhtml"===a?"script"===c?(a=g.createElement("div"),a.innerHTML="<script>\\x3c/script>",a=a.removeChild(a.firstChild)):\n"string"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),"select"===c&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Of]=b;a[Pf]=d;Aj(a,b,!1,!1);b.stateNode=a;a:{g=vb(c,d);switch(c){case "dialog":D("cancel",a);D("close",a);e=d;break;case "iframe":case "object":case "embed":D("load",a);e=d;break;case "video":case "audio":for(e=0;e<lf.length;e++)D(lf[e],a);e=d;break;case "source":D("error",a);e=d;break;case "img":case "image":case "link":D("error",\na);D("load",a);e=d;break;case "details":D("toggle",a);e=d;break;case "input":Za(a,d);e=Ya(a,d);D("invalid",a);break;case "option":e=d;break;case "select":a._wrapperState={wasMultiple:!!d.multiple};e=A({},d,{value:void 0});D("invalid",a);break;case "textarea":hb(a,d);e=gb(a,d);D("invalid",a);break;default:e=d}ub(c,e);h=e;for(f in h)if(h.hasOwnProperty(f)){var k=h[f];"style"===f?sb(a,k):"dangerouslySetInnerHTML"===f?(k=k?k.__html:void 0,null!=k&&nb(a,k)):"children"===f?"string"===typeof k?("textarea"!==\nc||""!==k)&&ob(a,k):"number"===typeof k&&ob(a,""+k):"suppressContentEditableWarning"!==f&&"suppressHydrationWarning"!==f&&"autoFocus"!==f&&(ea.hasOwnProperty(f)?null!=k&&"onScroll"===f&&D("scroll",a):null!=k&&ta(a,f,k,g))}switch(c){case "input":Va(a);db(a,d,!1);break;case "textarea":Va(a);jb(a);break;case "option":null!=d.value&&a.setAttribute("value",""+Sa(d.value));break;case "select":a.multiple=!!d.multiple;f=d.value;null!=f?fb(a,!!d.multiple,f,!1):null!=d.defaultValue&&fb(a,!!d.multiple,d.defaultValue,\n!0);break;default:"function"===typeof e.onClick&&(a.onclick=Bf)}switch(c){case "button":case "input":case "select":case "textarea":d=!!d.autoFocus;break a;case "img":d=!0;break a;default:d=!1}}d&&(b.flags|=4)}null!==b.ref&&(b.flags|=512,b.flags|=2097152)}S(b);return null;case 6:if(a&&null!=b.stateNode)Dj(a,b,a.memoizedProps,d);else{if("string"!==typeof d&&null===b.stateNode)throw Error(p(166));c=Hh(Gh.current);Hh(Eh.current);if(Gg(b)){d=b.stateNode;c=b.memoizedProps;d[Of]=b;if(f=d.nodeValue!==c)if(a=\nxg,null!==a)switch(a.tag){case 3:Af(d.nodeValue,c,0!==(a.mode&1));break;case 5:!0!==a.memoizedProps.suppressHydrationWarning&&Af(d.nodeValue,c,0!==(a.mode&1))}f&&(b.flags|=4)}else d=(9===c.nodeType?c:c.ownerDocument).createTextNode(d),d[Of]=b,b.stateNode=d}S(b);return null;case 13:E(M);d=b.memoizedState;if(null===a||null!==a.memoizedState&&null!==a.memoizedState.dehydrated){if(I&&null!==yg&&0!==(b.mode&1)&&0===(b.flags&128))Hg(),Ig(),b.flags|=98560,f=!1;else if(f=Gg(b),null!==d&&null!==d.dehydrated){if(null===\na){if(!f)throw Error(p(318));f=b.memoizedState;f=null!==f?f.dehydrated:null;if(!f)throw Error(p(317));f[Of]=b}else Ig(),0===(b.flags&128)&&(b.memoizedState=null),b.flags|=4;S(b);f=!1}else null!==zg&&(Gj(zg),zg=null),f=!0;if(!f)return b.flags&65536?b:null}if(0!==(b.flags&128))return b.lanes=c,b;d=null!==d;d!==(null!==a&&null!==a.memoizedState)&&d&&(b.child.flags|=8192,0!==(b.mode&1)&&(null===a||0!==(M.current&1)?0===T&&(T=3):uj()));null!==b.updateQueue&&(b.flags|=4);S(b);return null;case 4:return Jh(),\nBj(a,b),null===a&&sf(b.stateNode.containerInfo),S(b),null;case 10:return Rg(b.type._context),S(b),null;case 17:return Zf(b.type)&&$f(),S(b),null;case 19:E(M);f=b.memoizedState;if(null===f)return S(b),null;d=0!==(b.flags&128);g=f.rendering;if(null===g)if(d)Ej(f,!1);else{if(0!==T||null!==a&&0!==(a.flags&128))for(a=b.child;null!==a;){g=Mh(a);if(null!==g){b.flags|=128;Ej(f,!1);d=g.updateQueue;null!==d&&(b.updateQueue=d,b.flags|=4);b.subtreeFlags=0;d=c;for(c=b.child;null!==c;)f=c,a=d,f.flags&=14680066,\ng=f.alternate,null===g?(f.childLanes=0,f.lanes=a,f.child=null,f.subtreeFlags=0,f.memoizedProps=null,f.memoizedState=null,f.updateQueue=null,f.dependencies=null,f.stateNode=null):(f.childLanes=g.childLanes,f.lanes=g.lanes,f.child=g.child,f.subtreeFlags=0,f.deletions=null,f.memoizedProps=g.memoizedProps,f.memoizedState=g.memoizedState,f.updateQueue=g.updateQueue,f.type=g.type,a=g.dependencies,f.dependencies=null===a?null:{lanes:a.lanes,firstContext:a.firstContext}),c=c.sibling;G(M,M.current&1|2);return b.child}a=\na.sibling}null!==f.tail&&B()>Hj&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304)}else{if(!d)if(a=Mh(g),null!==a){if(b.flags|=128,d=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),Ej(f,!0),null===f.tail&&"hidden"===f.tailMode&&!g.alternate&&!I)return S(b),null}else 2*B()-f.renderingStartTime>Hj&&1073741824!==c&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304);f.isBackwards?(g.sibling=b.child,b.child=g):(c=f.last,null!==c?c.sibling=g:b.child=g,f.last=g)}if(null!==f.tail)return b=f.tail,f.rendering=\nb,f.tail=b.sibling,f.renderingStartTime=B(),b.sibling=null,c=M.current,G(M,d?c&1|2:c&1),b;S(b);return null;case 22:case 23:return Ij(),d=null!==b.memoizedState,null!==a&&null!==a.memoizedState!==d&&(b.flags|=8192),d&&0!==(b.mode&1)?0!==(gj&1073741824)&&(S(b),b.subtreeFlags&6&&(b.flags|=8192)):S(b),null;case 24:return null;case 25:return null}throw Error(p(156,b.tag));}\nfunction Jj(a,b){wg(b);switch(b.tag){case 1:return Zf(b.type)&&$f(),a=b.flags,a&65536?(b.flags=a&-65537|128,b):null;case 3:return Jh(),E(Wf),E(H),Oh(),a=b.flags,0!==(a&65536)&&0===(a&128)?(b.flags=a&-65537|128,b):null;case 5:return Lh(b),null;case 13:E(M);a=b.memoizedState;if(null!==a&&null!==a.dehydrated){if(null===b.alternate)throw Error(p(340));Ig()}a=b.flags;return a&65536?(b.flags=a&-65537|128,b):null;case 19:return E(M),null;case 4:return Jh(),null;case 10:return Rg(b.type._context),null;case 22:case 23:return Ij(),\nnull;case 24:return null;default:return null}}var Kj=!1,U=!1,Lj="function"===typeof WeakSet?WeakSet:Set,V=null;function Mj(a,b){var c=a.ref;if(null!==c)if("function"===typeof c)try{c(null)}catch(d){W(a,b,d)}else c.current=null}function Nj(a,b,c){try{c()}catch(d){W(a,b,d)}}var Oj=!1;\nfunction Pj(a,b){Cf=dd;a=Me();if(Ne(a)){if("selectionStart"in a)var c={start:a.selectionStart,end:a.selectionEnd};else a:{c=(c=a.ownerDocument)&&c.defaultView||window;var d=c.getSelection&&c.getSelection();if(d&&0!==d.rangeCount){c=d.anchorNode;var e=d.anchorOffset,f=d.focusNode;d=d.focusOffset;try{c.nodeType,f.nodeType}catch(F){c=null;break a}var g=0,h=-1,k=-1,l=0,m=0,q=a,r=null;b:for(;;){for(var y;;){q!==c||0!==e&&3!==q.nodeType||(h=g+e);q!==f||0!==d&&3!==q.nodeType||(k=g+d);3===q.nodeType&&(g+=\nq.nodeValue.length);if(null===(y=q.firstChild))break;r=q;q=y}for(;;){if(q===a)break b;r===c&&++l===e&&(h=g);r===f&&++m===d&&(k=g);if(null!==(y=q.nextSibling))break;q=r;r=q.parentNode}q=y}c=-1===h||-1===k?null:{start:h,end:k}}else c=null}c=c||{start:0,end:0}}else c=null;Df={focusedElem:a,selectionRange:c};dd=!1;for(V=b;null!==V;)if(b=V,a=b.child,0!==(b.subtreeFlags&1028)&&null!==a)a.return=b,V=a;else for(;null!==V;){b=V;try{var n=b.alternate;if(0!==(b.flags&1024))switch(b.tag){case 0:case 11:case 15:break;\ncase 1:if(null!==n){var t=n.memoizedProps,J=n.memoizedState,x=b.stateNode,w=x.getSnapshotBeforeUpdate(b.elementType===b.type?t:Lg(b.type,t),J);x.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var u=b.stateNode.containerInfo;1===u.nodeType?u.textContent="":9===u.nodeType&&u.documentElement&&u.removeChild(u.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p(163));}}catch(F){W(b,b.return,F)}a=b.sibling;if(null!==a){a.return=b.return;V=a;break}V=b.return}n=Oj;Oj=!1;return n}\nfunction Qj(a,b,c){var d=b.updateQueue;d=null!==d?d.lastEffect:null;if(null!==d){var e=d=d.next;do{if((e.tag&a)===a){var f=e.destroy;e.destroy=void 0;void 0!==f&&Nj(b,c,f)}e=e.next}while(e!==d)}}function Rj(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function Sj(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=c;break;default:a=c}"function"===typeof b?b(a):b.current=a}}\nfunction Tj(a){var b=a.alternate;null!==b&&(a.alternate=null,Tj(b));a.child=null;a.deletions=null;a.sibling=null;5===a.tag&&(b=a.stateNode,null!==b&&(delete b[Of],delete b[Pf],delete b[of],delete b[Qf],delete b[Rf]));a.stateNode=null;a.return=null;a.dependencies=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.stateNode=null;a.updateQueue=null}function Uj(a){return 5===a.tag||3===a.tag||4===a.tag}\nfunction Vj(a){a:for(;;){for(;null===a.sibling;){if(null===a.return||Uj(a.return))return null;a=a.return}a.sibling.return=a.return;for(a=a.sibling;5!==a.tag&&6!==a.tag&&18!==a.tag;){if(a.flags&2)continue a;if(null===a.child||4===a.tag)continue a;else a.child.return=a,a=a.child}if(!(a.flags&2))return a.stateNode}}\nfunction Wj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Bf));else if(4!==d&&(a=a.child,null!==a))for(Wj(a,b,c),a=a.sibling;null!==a;)Wj(a,b,c),a=a.sibling}\nfunction Xj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?c.insertBefore(a,b):c.appendChild(a);else if(4!==d&&(a=a.child,null!==a))for(Xj(a,b,c),a=a.sibling;null!==a;)Xj(a,b,c),a=a.sibling}var X=null,Yj=!1;function Zj(a,b,c){for(c=c.child;null!==c;)ak(a,b,c),c=c.sibling}\nfunction ak(a,b,c){if(lc&&"function"===typeof lc.onCommitFiberUnmount)try{lc.onCommitFiberUnmount(kc,c)}catch(h){}switch(c.tag){case 5:U||Mj(c,b);case 6:var d=X,e=Yj;X=null;Zj(a,b,c);X=d;Yj=e;null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?a.parentNode.removeChild(c):a.removeChild(c)):X.removeChild(c.stateNode));break;case 18:null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?Kf(a.parentNode,c):1===a.nodeType&&Kf(a,c),bd(a)):Kf(X,c.stateNode));break;case 4:d=X;e=Yj;X=c.stateNode.containerInfo;Yj=!0;\nZj(a,b,c);X=d;Yj=e;break;case 0:case 11:case 14:case 15:if(!U&&(d=c.updateQueue,null!==d&&(d=d.lastEffect,null!==d))){e=d=d.next;do{var f=e,g=f.destroy;f=f.tag;void 0!==g&&(0!==(f&2)?Nj(c,b,g):0!==(f&4)&&Nj(c,b,g));e=e.next}while(e!==d)}Zj(a,b,c);break;case 1:if(!U&&(Mj(c,b),d=c.stateNode,"function"===typeof d.componentWillUnmount))try{d.props=c.memoizedProps,d.state=c.memoizedState,d.componentWillUnmount()}catch(h){W(c,b,h)}Zj(a,b,c);break;case 21:Zj(a,b,c);break;case 22:c.mode&1?(U=(d=U)||null!==\nc.memoizedState,Zj(a,b,c),U=d):Zj(a,b,c);break;default:Zj(a,b,c)}}function bk(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=new Lj);b.forEach(function(b){var d=ck.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}}\nfunction dk(a,b){var c=b.deletions;if(null!==c)for(var d=0;d<c.length;d++){var e=c[d];try{var f=a,g=b,h=g;a:for(;null!==h;){switch(h.tag){case 5:X=h.stateNode;Yj=!1;break a;case 3:X=h.stateNode.containerInfo;Yj=!0;break a;case 4:X=h.stateNode.containerInfo;Yj=!0;break a}h=h.return}if(null===X)throw Error(p(160));ak(f,g,e);X=null;Yj=!1;var k=e.alternate;null!==k&&(k.return=null);e.return=null}catch(l){W(e,b,l)}}if(b.subtreeFlags&12854)for(b=b.child;null!==b;)ek(b,a),b=b.sibling}\nfunction ek(a,b){var c=a.alternate,d=a.flags;switch(a.tag){case 0:case 11:case 14:case 15:dk(b,a);fk(a);if(d&4){try{Qj(3,a,a.return),Rj(3,a)}catch(t){W(a,a.return,t)}try{Qj(5,a,a.return)}catch(t){W(a,a.return,t)}}break;case 1:dk(b,a);fk(a);d&512&&null!==c&&Mj(c,c.return);break;case 5:dk(b,a);fk(a);d&512&&null!==c&&Mj(c,c.return);if(a.flags&32){var e=a.stateNode;try{ob(e,"")}catch(t){W(a,a.return,t)}}if(d&4&&(e=a.stateNode,null!=e)){var f=a.memoizedProps,g=null!==c?c.memoizedProps:f,h=a.type,k=a.updateQueue;\na.updateQueue=null;if(null!==k)try{"input"===h&&"radio"===f.type&&null!=f.name&&ab(e,f);vb(h,g);var l=vb(h,f);for(g=0;g<k.length;g+=2){var m=k[g],q=k[g+1];"style"===m?sb(e,q):"dangerouslySetInnerHTML"===m?nb(e,q):"children"===m?ob(e,q):ta(e,m,q,l)}switch(h){case "input":bb(e,f);break;case "textarea":ib(e,f);break;case "select":var r=e._wrapperState.wasMultiple;e._wrapperState.wasMultiple=!!f.multiple;var y=f.value;null!=y?fb(e,!!f.multiple,y,!1):r!==!!f.multiple&&(null!=f.defaultValue?fb(e,!!f.multiple,\nf.defaultValue,!0):fb(e,!!f.multiple,f.multiple?[]:"",!1))}e[Pf]=f}catch(t){W(a,a.return,t)}}break;case 6:dk(b,a);fk(a);if(d&4){if(null===a.stateNode)throw Error(p(162));e=a.stateNode;f=a.memoizedProps;try{e.nodeValue=f}catch(t){W(a,a.return,t)}}break;case 3:dk(b,a);fk(a);if(d&4&&null!==c&&c.memoizedState.isDehydrated)try{bd(b.containerInfo)}catch(t){W(a,a.return,t)}break;case 4:dk(b,a);fk(a);break;case 13:dk(b,a);fk(a);e=a.child;e.flags&8192&&(f=null!==e.memoizedState,e.stateNode.isHidden=f,!f||\nnull!==e.alternate&&null!==e.alternate.memoizedState||(gk=B()));d&4&&bk(a);break;case 22:m=null!==c&&null!==c.memoizedState;a.mode&1?(U=(l=U)||m,dk(b,a),U=l):dk(b,a);fk(a);if(d&8192){l=null!==a.memoizedState;if((a.stateNode.isHidden=l)&&!m&&0!==(a.mode&1))for(V=a,m=a.child;null!==m;){for(q=V=m;null!==V;){r=V;y=r.child;switch(r.tag){case 0:case 11:case 14:case 15:Qj(4,r,r.return);break;case 1:Mj(r,r.return);var n=r.stateNode;if("function"===typeof n.componentWillUnmount){d=r;c=r.return;try{b=d,n.props=\nb.memoizedProps,n.state=b.memoizedState,n.componentWillUnmount()}catch(t){W(d,c,t)}}break;case 5:Mj(r,r.return);break;case 22:if(null!==r.memoizedState){hk(q);continue}}null!==y?(y.return=r,V=y):hk(q)}m=m.sibling}a:for(m=null,q=a;;){if(5===q.tag){if(null===m){m=q;try{e=q.stateNode,l?(f=e.style,"function"===typeof f.setProperty?f.setProperty("display","none","important"):f.display="none"):(h=q.stateNode,k=q.memoizedProps.style,g=void 0!==k&&null!==k&&k.hasOwnProperty("display")?k.display:null,h.style.display=\nrb("display",g))}catch(t){W(a,a.return,t)}}}else if(6===q.tag){if(null===m)try{q.stateNode.nodeValue=l?"":q.memoizedProps}catch(t){W(a,a.return,t)}}else if((22!==q.tag&&23!==q.tag||null===q.memoizedState||q===a)&&null!==q.child){q.child.return=q;q=q.child;continue}if(q===a)break a;for(;null===q.sibling;){if(null===q.return||q.return===a)break a;m===q&&(m=null);q=q.return}m===q&&(m=null);q.sibling.return=q.return;q=q.sibling}}break;case 19:dk(b,a);fk(a);d&4&&bk(a);break;case 21:break;default:dk(b,\na),fk(a)}}function fk(a){var b=a.flags;if(b&2){try{a:{for(var c=a.return;null!==c;){if(Uj(c)){var d=c;break a}c=c.return}throw Error(p(160));}switch(d.tag){case 5:var e=d.stateNode;d.flags&32&&(ob(e,""),d.flags&=-33);var f=Vj(a);Xj(a,f,e);break;case 3:case 4:var g=d.stateNode.containerInfo,h=Vj(a);Wj(a,h,g);break;default:throw Error(p(161));}}catch(k){W(a,a.return,k)}a.flags&=-3}b&4096&&(a.flags&=-4097)}function ik(a,b,c){V=a;jk(a,b,c)}\nfunction jk(a,b,c){for(var d=0!==(a.mode&1);null!==V;){var e=V,f=e.child;if(22===e.tag&&d){var g=null!==e.memoizedState||Kj;if(!g){var h=e.alternate,k=null!==h&&null!==h.memoizedState||U;h=Kj;var l=U;Kj=g;if((U=k)&&!l)for(V=e;null!==V;)g=V,k=g.child,22===g.tag&&null!==g.memoizedState?kk(e):null!==k?(k.return=g,V=k):kk(e);for(;null!==f;)V=f,jk(f,b,c),f=f.sibling;V=e;Kj=h;U=l}lk(a,b,c)}else 0!==(e.subtreeFlags&8772)&&null!==f?(f.return=e,V=f):lk(a,b,c)}}\nfunction lk(a){for(;null!==V;){var b=V;if(0!==(b.flags&8772)){var c=b.alternate;try{if(0!==(b.flags&8772))switch(b.tag){case 0:case 11:case 15:U||Rj(5,b);break;case 1:var d=b.stateNode;if(b.flags&4&&!U)if(null===c)d.componentDidMount();else{var e=b.elementType===b.type?c.memoizedProps:Lg(b.type,c.memoizedProps);d.componentDidUpdate(e,c.memoizedState,d.__reactInternalSnapshotBeforeUpdate)}var f=b.updateQueue;null!==f&&ih(b,f,d);break;case 3:var g=b.updateQueue;if(null!==g){c=null;if(null!==b.child)switch(b.child.tag){case 5:c=\nb.child.stateNode;break;case 1:c=b.child.stateNode}ih(b,g,c)}break;case 5:var h=b.stateNode;if(null===c&&b.flags&4){c=h;var k=b.memoizedProps;switch(b.type){case "button":case "input":case "select":case "textarea":k.autoFocus&&c.focus();break;case "img":k.src&&(c.src=k.src)}}break;case 6:break;case 4:break;case 12:break;case 13:if(null===b.memoizedState){var l=b.alternate;if(null!==l){var m=l.memoizedState;if(null!==m){var q=m.dehydrated;null!==q&&bd(q)}}}break;case 19:case 17:case 21:case 22:case 23:case 25:break;\ndefault:throw Error(p(163));}U||b.flags&512&&Sj(b)}catch(r){W(b,b.return,r)}}if(b===a){V=null;break}c=b.sibling;if(null!==c){c.return=b.return;V=c;break}V=b.return}}function hk(a){for(;null!==V;){var b=V;if(b===a){V=null;break}var c=b.sibling;if(null!==c){c.return=b.return;V=c;break}V=b.return}}\nfunction kk(a){for(;null!==V;){var b=V;try{switch(b.tag){case 0:case 11:case 15:var c=b.return;try{Rj(4,b)}catch(k){W(b,c,k)}break;case 1:var d=b.stateNode;if("function"===typeof d.componentDidMount){var e=b.return;try{d.componentDidMount()}catch(k){W(b,e,k)}}var f=b.return;try{Sj(b)}catch(k){W(b,f,k)}break;case 5:var g=b.return;try{Sj(b)}catch(k){W(b,g,k)}}}catch(k){W(b,b.return,k)}if(b===a){V=null;break}var h=b.sibling;if(null!==h){h.return=b.return;V=h;break}V=b.return}}\nvar mk=Math.ceil,nk=ua.ReactCurrentDispatcher,ok=ua.ReactCurrentOwner,pk=ua.ReactCurrentBatchConfig,K=0,R=null,Y=null,Z=0,gj=0,fj=Uf(0),T=0,qk=null,hh=0,rk=0,sk=0,tk=null,uk=null,gk=0,Hj=Infinity,vk=null,Pi=!1,Qi=null,Si=null,wk=!1,xk=null,yk=0,zk=0,Ak=null,Bk=-1,Ck=0;function L(){return 0!==(K&6)?B():-1!==Bk?Bk:Bk=B()}\nfunction lh(a){if(0===(a.mode&1))return 1;if(0!==(K&2)&&0!==Z)return Z&-Z;if(null!==Kg.transition)return 0===Ck&&(Ck=yc()),Ck;a=C;if(0!==a)return a;a=window.event;a=void 0===a?16:jd(a.type);return a}function mh(a,b,c,d){if(50<zk)throw zk=0,Ak=null,Error(p(185));Ac(a,c,d);if(0===(K&2)||a!==R)a===R&&(0===(K&2)&&(rk|=c),4===T&&Dk(a,Z)),Ek(a,d),1===c&&0===K&&0===(b.mode&1)&&(Hj=B()+500,fg&&jg())}\nfunction Ek(a,b){var c=a.callbackNode;wc(a,b);var d=uc(a,a===R?Z:0);if(0===d)null!==c&&bc(c),a.callbackNode=null,a.callbackPriority=0;else if(b=d&-d,a.callbackPriority!==b){null!=c&&bc(c);if(1===b)0===a.tag?ig(Fk.bind(null,a)):hg(Fk.bind(null,a)),Jf(function(){0===(K&6)&&jg()}),c=null;else{switch(Dc(d)){case 1:c=fc;break;case 4:c=gc;break;case 16:c=hc;break;case 536870912:c=jc;break;default:c=hc}c=Gk(c,Hk.bind(null,a))}a.callbackPriority=b;a.callbackNode=c}}\nfunction Hk(a,b){Bk=-1;Ck=0;if(0!==(K&6))throw Error(p(327));var c=a.callbackNode;if(Ik()&&a.callbackNode!==c)return null;var d=uc(a,a===R?Z:0);if(0===d)return null;if(0!==(d&30)||0!==(d&a.expiredLanes)||b)b=Jk(a,d);else{b=d;var e=K;K|=2;var f=Kk();if(R!==a||Z!==b)vk=null,Hj=B()+500,Lk(a,b);do try{Mk();break}catch(h){Nk(a,h)}while(1);Qg();nk.current=f;K=e;null!==Y?b=0:(R=null,Z=0,b=T)}if(0!==b){2===b&&(e=xc(a),0!==e&&(d=e,b=Ok(a,e)));if(1===b)throw c=qk,Lk(a,0),Dk(a,d),Ek(a,B()),c;if(6===b)Dk(a,d);\nelse{e=a.current.alternate;if(0===(d&30)&&!Pk(e)&&(b=Jk(a,d),2===b&&(f=xc(a),0!==f&&(d=f,b=Ok(a,f))),1===b))throw c=qk,Lk(a,0),Dk(a,d),Ek(a,B()),c;a.finishedWork=e;a.finishedLanes=d;switch(b){case 0:case 1:throw Error(p(345));case 2:Qk(a,uk,vk);break;case 3:Dk(a,d);if((d&130023424)===d&&(b=gk+500-B(),10<b)){if(0!==uc(a,0))break;e=a.suspendedLanes;if((e&d)!==d){L();a.pingedLanes|=a.suspendedLanes&e;break}a.timeoutHandle=Ff(Qk.bind(null,a,uk,vk),b);break}Qk(a,uk,vk);break;case 4:Dk(a,d);if((d&4194240)===\nd)break;b=a.eventTimes;for(e=-1;0<d;){var g=31-oc(d);f=1<<g;g=b[g];g>e&&(e=g);d&=~f}d=e;d=B()-d;d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*mk(d/1960))-d;if(10<d){a.timeoutHandle=Ff(Qk.bind(null,a,uk,vk),d);break}Qk(a,uk,vk);break;case 5:Qk(a,uk,vk);break;default:throw Error(p(329));}}}Ek(a,B());return a.callbackNode===c?Hk.bind(null,a):null}\nfunction Ok(a,b){var c=tk;a.current.memoizedState.isDehydrated&&(Lk(a,b).flags|=256);a=Jk(a,b);2!==a&&(b=uk,uk=c,null!==b&&Gj(b));return a}function Gj(a){null===uk?uk=a:uk.push.apply(uk,a)}\nfunction Pk(a){for(var b=a;;){if(b.flags&16384){var c=b.updateQueue;if(null!==c&&(c=c.stores,null!==c))for(var d=0;d<c.length;d++){var e=c[d],f=e.getSnapshot;e=e.value;try{if(!He(f(),e))return!1}catch(g){return!1}}}c=b.child;if(b.subtreeFlags&16384&&null!==c)c.return=b,b=c;else{if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return!0;b=b.return}b.sibling.return=b.return;b=b.sibling}}return!0}\nfunction Dk(a,b){b&=~sk;b&=~rk;a.suspendedLanes|=b;a.pingedLanes&=~b;for(a=a.expirationTimes;0<b;){var c=31-oc(b),d=1<<c;a[c]=-1;b&=~d}}function Fk(a){if(0!==(K&6))throw Error(p(327));Ik();var b=uc(a,0);if(0===(b&1))return Ek(a,B()),null;var c=Jk(a,b);if(0!==a.tag&&2===c){var d=xc(a);0!==d&&(b=d,c=Ok(a,d))}if(1===c)throw c=qk,Lk(a,0),Dk(a,b),Ek(a,B()),c;if(6===c)throw Error(p(345));a.finishedWork=a.current.alternate;a.finishedLanes=b;Qk(a,uk,vk);Ek(a,B());return null}\nfunction Rk(a,b){var c=K;K|=1;try{return a(b)}finally{K=c,0===K&&(Hj=B()+500,fg&&jg())}}function Sk(a){null!==xk&&0===xk.tag&&0===(K&6)&&Ik();var b=K;K|=1;var c=pk.transition,d=C;try{if(pk.transition=null,C=1,a)return a()}finally{C=d,pk.transition=c,K=b,0===(K&6)&&jg()}}function Ij(){gj=fj.current;E(fj)}\nfunction Lk(a,b){a.finishedWork=null;a.finishedLanes=0;var c=a.timeoutHandle;-1!==c&&(a.timeoutHandle=-1,Gf(c));if(null!==Y)for(c=Y.return;null!==c;){var d=c;wg(d);switch(d.tag){case 1:d=d.type.childContextTypes;null!==d&&void 0!==d&&$f();break;case 3:Jh();E(Wf);E(H);Oh();break;case 5:Lh(d);break;case 4:Jh();break;case 13:E(M);break;case 19:E(M);break;case 10:Rg(d.type._context);break;case 22:case 23:Ij()}c=c.return}R=a;Y=a=wh(a.current,null);Z=gj=b;T=0;qk=null;sk=rk=hh=0;uk=tk=null;if(null!==Wg){for(b=\n0;b<Wg.length;b++)if(c=Wg[b],d=c.interleaved,null!==d){c.interleaved=null;var e=d.next,f=c.pending;if(null!==f){var g=f.next;f.next=e;d.next=g}c.pending=d}Wg=null}return a}\nfunction Nk(a,b){do{var c=Y;try{Qg();Ph.current=ai;if(Sh){for(var d=N.memoizedState;null!==d;){var e=d.queue;null!==e&&(e.pending=null);d=d.next}Sh=!1}Rh=0;P=O=N=null;Th=!1;Uh=0;ok.current=null;if(null===c||null===c.return){T=1;qk=b;Y=null;break}a:{var f=a,g=c.return,h=c,k=b;b=Z;h.flags|=32768;if(null!==k&&"object"===typeof k&&"function"===typeof k.then){var l=k,m=h,q=m.tag;if(0===(m.mode&1)&&(0===q||11===q||15===q)){var r=m.alternate;r?(m.updateQueue=r.updateQueue,m.memoizedState=r.memoizedState,\nm.lanes=r.lanes):(m.updateQueue=null,m.memoizedState=null)}var y=Vi(g);if(null!==y){y.flags&=-257;Wi(y,g,h,f,b);y.mode&1&&Ti(f,l,b);b=y;k=l;var n=b.updateQueue;if(null===n){var t=new Set;t.add(k);b.updateQueue=t}else n.add(k);break a}else{if(0===(b&1)){Ti(f,l,b);uj();break a}k=Error(p(426))}}else if(I&&h.mode&1){var J=Vi(g);if(null!==J){0===(J.flags&65536)&&(J.flags|=256);Wi(J,g,h,f,b);Jg(Ki(k,h));break a}}f=k=Ki(k,h);4!==T&&(T=2);null===tk?tk=[f]:tk.push(f);f=g;do{switch(f.tag){case 3:f.flags|=65536;\nb&=-b;f.lanes|=b;var x=Oi(f,k,b);fh(f,x);break a;case 1:h=k;var w=f.type,u=f.stateNode;if(0===(f.flags&128)&&("function"===typeof w.getDerivedStateFromError||null!==u&&"function"===typeof u.componentDidCatch&&(null===Si||!Si.has(u)))){f.flags|=65536;b&=-b;f.lanes|=b;var F=Ri(f,h,b);fh(f,F);break a}}f=f.return}while(null!==f)}Tk(c)}catch(na){b=na;Y===c&&null!==c&&(Y=c=c.return);continue}break}while(1)}function Kk(){var a=nk.current;nk.current=ai;return null===a?ai:a}\nfunction uj(){if(0===T||3===T||2===T)T=4;null===R||0===(hh&268435455)&&0===(rk&268435455)||Dk(R,Z)}function Jk(a,b){var c=K;K|=2;var d=Kk();if(R!==a||Z!==b)vk=null,Lk(a,b);do try{Uk();break}catch(e){Nk(a,e)}while(1);Qg();K=c;nk.current=d;if(null!==Y)throw Error(p(261));R=null;Z=0;return T}function Uk(){for(;null!==Y;)Vk(Y)}function Mk(){for(;null!==Y&&!cc();)Vk(Y)}function Vk(a){var b=Wk(a.alternate,a,gj);a.memoizedProps=a.pendingProps;null===b?Tk(a):Y=b;ok.current=null}\nfunction Tk(a){var b=a;do{var c=b.alternate;a=b.return;if(0===(b.flags&32768)){if(c=Fj(c,b,gj),null!==c){Y=c;return}}else{c=Jj(c,b);if(null!==c){c.flags&=32767;Y=c;return}if(null!==a)a.flags|=32768,a.subtreeFlags=0,a.deletions=null;else{T=6;Y=null;return}}b=b.sibling;if(null!==b){Y=b;return}Y=b=a}while(null!==b);0===T&&(T=5)}function Qk(a,b,c){var d=C,e=pk.transition;try{pk.transition=null,C=1,Xk(a,b,c,d)}finally{pk.transition=e,C=d}return null}\nfunction Xk(a,b,c,d){do Ik();while(null!==xk);if(0!==(K&6))throw Error(p(327));c=a.finishedWork;var e=a.finishedLanes;if(null===c)return null;a.finishedWork=null;a.finishedLanes=0;if(c===a.current)throw Error(p(177));a.callbackNode=null;a.callbackPriority=0;var f=c.lanes|c.childLanes;Bc(a,f);a===R&&(Y=R=null,Z=0);0===(c.subtreeFlags&2064)&&0===(c.flags&2064)||wk||(wk=!0,Gk(hc,function(){Ik();return null}));f=0!==(c.flags&15990);if(0!==(c.subtreeFlags&15990)||f){f=pk.transition;pk.transition=null;\nvar g=C;C=1;var h=K;K|=4;ok.current=null;Pj(a,c);ek(c,a);Oe(Df);dd=!!Cf;Df=Cf=null;a.current=c;ik(c,a,e);dc();K=h;C=g;pk.transition=f}else a.current=c;wk&&(wk=!1,xk=a,yk=e);f=a.pendingLanes;0===f&&(Si=null);mc(c.stateNode,d);Ek(a,B());if(null!==b)for(d=a.onRecoverableError,c=0;c<b.length;c++)e=b[c],d(e.value,{componentStack:e.stack,digest:e.digest});if(Pi)throw Pi=!1,a=Qi,Qi=null,a;0!==(yk&1)&&0!==a.tag&&Ik();f=a.pendingLanes;0!==(f&1)?a===Ak?zk++:(zk=0,Ak=a):zk=0;jg();return null}\nfunction Ik(){if(null!==xk){var a=Dc(yk),b=pk.transition,c=C;try{pk.transition=null;C=16>a?16:a;if(null===xk)var d=!1;else{a=xk;xk=null;yk=0;if(0!==(K&6))throw Error(p(331));var e=K;K|=4;for(V=a.current;null!==V;){var f=V,g=f.child;if(0!==(V.flags&16)){var h=f.deletions;if(null!==h){for(var k=0;k<h.length;k++){var l=h[k];for(V=l;null!==V;){var m=V;switch(m.tag){case 0:case 11:case 15:Qj(8,m,f)}var q=m.child;if(null!==q)q.return=m,V=q;else for(;null!==V;){m=V;var r=m.sibling,y=m.return;Tj(m);if(m===\nl){V=null;break}if(null!==r){r.return=y;V=r;break}V=y}}}var n=f.alternate;if(null!==n){var t=n.child;if(null!==t){n.child=null;do{var J=t.sibling;t.sibling=null;t=J}while(null!==t)}}V=f}}if(0!==(f.subtreeFlags&2064)&&null!==g)g.return=f,V=g;else b:for(;null!==V;){f=V;if(0!==(f.flags&2048))switch(f.tag){case 0:case 11:case 15:Qj(9,f,f.return)}var x=f.sibling;if(null!==x){x.return=f.return;V=x;break b}V=f.return}}var w=a.current;for(V=w;null!==V;){g=V;var u=g.child;if(0!==(g.subtreeFlags&2064)&&null!==\nu)u.return=g,V=u;else b:for(g=w;null!==V;){h=V;if(0!==(h.flags&2048))try{switch(h.tag){case 0:case 11:case 15:Rj(9,h)}}catch(na){W(h,h.return,na)}if(h===g){V=null;break b}var F=h.sibling;if(null!==F){F.return=h.return;V=F;break b}V=h.return}}K=e;jg();if(lc&&"function"===typeof lc.onPostCommitFiberRoot)try{lc.onPostCommitFiberRoot(kc,a)}catch(na){}d=!0}return d}finally{C=c,pk.transition=b}}return!1}function Yk(a,b,c){b=Ki(c,b);b=Oi(a,b,1);a=dh(a,b,1);b=L();null!==a&&(Ac(a,1,b),Ek(a,b))}\nfunction W(a,b,c){if(3===a.tag)Yk(a,a,c);else for(;null!==b;){if(3===b.tag){Yk(b,a,c);break}else if(1===b.tag){var d=b.stateNode;if("function"===typeof b.type.getDerivedStateFromError||"function"===typeof d.componentDidCatch&&(null===Si||!Si.has(d))){a=Ki(c,a);a=Ri(b,a,1);b=dh(b,a,1);a=L();null!==b&&(Ac(b,1,a),Ek(b,a));break}}b=b.return}}\nfunction Ui(a,b,c){var d=a.pingCache;null!==d&&d.delete(b);b=L();a.pingedLanes|=a.suspendedLanes&c;R===a&&(Z&c)===c&&(4===T||3===T&&(Z&130023424)===Z&&500>B()-gk?Lk(a,0):sk|=c);Ek(a,b)}function Zk(a,b){0===b&&(0===(a.mode&1)?b=1:(b=sc,sc<<=1,0===(sc&130023424)&&(sc=4194304)));var c=L();a=Zg(a,b);null!==a&&(Ac(a,b,c),Ek(a,c))}function vj(a){var b=a.memoizedState,c=0;null!==b&&(c=b.retryLane);Zk(a,c)}\nfunction ck(a,b){var c=0;switch(a.tag){case 13:var d=a.stateNode;var e=a.memoizedState;null!==e&&(c=e.retryLane);break;case 19:d=a.stateNode;break;default:throw Error(p(314));}null!==d&&d.delete(b);Zk(a,c)}var Wk;\nWk=function(a,b,c){if(null!==a)if(a.memoizedProps!==b.pendingProps||Wf.current)Ug=!0;else{if(0===(a.lanes&c)&&0===(b.flags&128))return Ug=!1,zj(a,b,c);Ug=0!==(a.flags&131072)?!0:!1}else Ug=!1,I&&0!==(b.flags&1048576)&&ug(b,ng,b.index);b.lanes=0;switch(b.tag){case 2:var d=b.type;jj(a,b);a=b.pendingProps;var e=Yf(b,H.current);Tg(b,c);e=Xh(null,b,d,a,e,c);var f=bi();b.flags|=1;"object"===typeof e&&null!==e&&"function"===typeof e.render&&void 0===e.$$typeof?(b.tag=1,b.memoizedState=null,b.updateQueue=\nnull,Zf(d)?(f=!0,cg(b)):f=!1,b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null,ah(b),e.updater=nh,b.stateNode=e,e._reactInternals=b,rh(b,d,a,c),b=kj(null,b,d,!0,f,c)):(b.tag=0,I&&f&&vg(b),Yi(null,b,e,c),b=b.child);return b;case 16:d=b.elementType;a:{jj(a,b);a=b.pendingProps;e=d._init;d=e(d._payload);b.type=d;e=b.tag=$k(d);a=Lg(d,a);switch(e){case 0:b=dj(null,b,d,a,c);break a;case 1:b=ij(null,b,d,a,c);break a;case 11:b=Zi(null,b,d,a,c);break a;case 14:b=aj(null,b,d,Lg(d.type,a),c);break a}throw Error(p(306,\nd,""));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),dj(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),ij(a,b,d,e,c);case 3:a:{lj(b);if(null===a)throw Error(p(387));d=b.pendingProps;f=b.memoizedState;e=f.element;bh(a,b);gh(b,d,null,c);var g=b.memoizedState;d=g.element;if(f.isDehydrated)if(f={element:d,isDehydrated:!1,cache:g.cache,pendingSuspenseBoundaries:g.pendingSuspenseBoundaries,transitions:g.transitions},b.updateQueue.baseState=\nf,b.memoizedState=f,b.flags&256){e=Ki(Error(p(423)),b);b=mj(a,b,d,c,e);break a}else if(d!==e){e=Ki(Error(p(424)),b);b=mj(a,b,d,c,e);break a}else for(yg=Lf(b.stateNode.containerInfo.firstChild),xg=b,I=!0,zg=null,c=Ch(b,null,d,c),b.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{Ig();if(d===e){b=$i(a,b,c);break a}Yi(a,b,d,c)}b=b.child}return b;case 5:return Kh(b),null===a&&Eg(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,Ef(d,e)?g=null:null!==f&&Ef(d,f)&&(b.flags|=32),\nhj(a,b),Yi(a,b,g,c),b.child;case 6:return null===a&&Eg(b),null;case 13:return pj(a,b,c);case 4:return Ih(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Bh(b,null,d,c):Yi(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),Zi(a,b,d,e,c);case 7:return Yi(a,b,b.pendingProps,c),b.child;case 8:return Yi(a,b,b.pendingProps.children,c),b.child;case 12:return Yi(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;f=b.memoizedProps;\ng=e.value;G(Mg,d._currentValue);d._currentValue=g;if(null!==f)if(He(f.value,g)){if(f.children===e.children&&!Wf.current){b=$i(a,b,c);break a}}else for(f=b.child,null!==f&&(f.return=b);null!==f;){var h=f.dependencies;if(null!==h){g=f.child;for(var k=h.firstContext;null!==k;){if(k.context===d){if(1===f.tag){k=ch(-1,c&-c);k.tag=2;var l=f.updateQueue;if(null!==l){l=l.shared;var m=l.pending;null===m?k.next=k:(k.next=m.next,m.next=k);l.pending=k}}f.lanes|=c;k=f.alternate;null!==k&&(k.lanes|=c);Sg(f.return,\nc,b);h.lanes|=c;break}k=k.next}}else if(10===f.tag)g=f.type===b.type?null:f.child;else if(18===f.tag){g=f.return;if(null===g)throw Error(p(341));g.lanes|=c;h=g.alternate;null!==h&&(h.lanes|=c);Sg(g,c,b);g=f.sibling}else g=f.child;if(null!==g)g.return=f;else for(g=f;null!==g;){if(g===b){g=null;break}f=g.sibling;if(null!==f){f.return=g.return;g=f;break}g=g.return}f=g}Yi(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,d=b.pendingProps.children,Tg(b,c),e=Vg(e),d=d(e),b.flags|=1,Yi(a,b,d,c),\nb.child;case 14:return d=b.type,e=Lg(d,b.pendingProps),e=Lg(d.type,e),aj(a,b,d,e,c);case 15:return cj(a,b,b.type,b.pendingProps,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),jj(a,b),b.tag=1,Zf(d)?(a=!0,cg(b)):a=!1,Tg(b,c),ph(b,d,e),rh(b,d,e,c),kj(null,b,d,!0,a,c);case 19:return yj(a,b,c);case 22:return ej(a,b,c)}throw Error(p(156,b.tag));};function Gk(a,b){return ac(a,b)}\nfunction al(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.subtreeFlags=this.flags=0;this.deletions=null;this.childLanes=this.lanes=0;this.alternate=null}function Bg(a,b,c,d){return new al(a,b,c,d)}function bj(a){a=a.prototype;return!(!a||!a.isReactComponent)}\nfunction $k(a){if("function"===typeof a)return bj(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Da)return 11;if(a===Ga)return 14}return 2}\nfunction wh(a,b){var c=a.alternate;null===c?(c=Bg(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.subtreeFlags=0,c.deletions=null);c.flags=a.flags&14680064;c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext};\nc.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c}\nfunction yh(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)bj(a)&&(g=1);else if("string"===typeof a)g=5;else a:switch(a){case ya:return Ah(c.children,e,f,b);case za:g=8;e|=8;break;case Aa:return a=Bg(12,c,b,e|2),a.elementType=Aa,a.lanes=f,a;case Ea:return a=Bg(13,c,b,e),a.elementType=Ea,a.lanes=f,a;case Fa:return a=Bg(19,c,b,e),a.elementType=Fa,a.lanes=f,a;case Ia:return qj(c,e,f,b);default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case Ba:g=10;break a;case Ca:g=9;break a;case Da:g=11;\nbreak a;case Ga:g=14;break a;case Ha:g=16;d=null;break a}throw Error(p(130,null==a?a:typeof a,""));}b=Bg(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function Ah(a,b,c,d){a=Bg(7,a,d,b);a.lanes=c;return a}function qj(a,b,c,d){a=Bg(22,a,d,b);a.elementType=Ia;a.lanes=c;a.stateNode={isHidden:!1};return a}function xh(a,b,c){a=Bg(6,a,null,b);a.lanes=c;return a}\nfunction zh(a,b,c){b=Bg(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b}\nfunction bl(a,b,c,d,e){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.callbackNode=this.pendingContext=this.context=null;this.callbackPriority=0;this.eventTimes=zc(0);this.expirationTimes=zc(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=zc(0);this.identifierPrefix=d;this.onRecoverableError=e;this.mutableSourceEagerHydrationData=\nnull}function cl(a,b,c,d,e,f,g,h,k){a=new bl(a,b,c,h,k);1===b?(b=1,!0===f&&(b|=8)):b=0;f=Bg(3,null,null,b);a.current=f;f.stateNode=a;f.memoizedState={element:d,isDehydrated:c,cache:null,transitions:null,pendingSuspenseBoundaries:null};ah(f);return a}function dl(a,b,c){var d=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:wa,key:null==d?null:""+d,children:a,containerInfo:b,implementation:c}}\nfunction el(a){if(!a)return Vf;a=a._reactInternals;a:{if(Vb(a)!==a||1!==a.tag)throw Error(p(170));var b=a;do{switch(b.tag){case 3:b=b.stateNode.context;break a;case 1:if(Zf(b.type)){b=b.stateNode.__reactInternalMemoizedMergedChildContext;break a}}b=b.return}while(null!==b);throw Error(p(171));}if(1===a.tag){var c=a.type;if(Zf(c))return bg(a,c,b)}return b}\nfunction fl(a,b,c,d,e,f,g,h,k){a=cl(c,d,!0,a,e,f,g,h,k);a.context=el(null);c=a.current;d=L();e=lh(c);f=ch(d,e);f.callback=void 0!==b&&null!==b?b:null;dh(c,f,e);a.current.lanes=e;Ac(a,e,d);Ek(a,d);return a}function gl(a,b,c,d){var e=b.current,f=L(),g=lh(e);c=el(c);null===b.context?b.context=c:b.pendingContext=c;b=ch(f,g);b.payload={element:a};d=void 0===d?null:d;null!==d&&(b.callback=d);a=dh(e,b,g);null!==a&&(mh(a,e,g,f),eh(a,e,g));return g}\nfunction hl(a){a=a.current;if(!a.child)return null;switch(a.child.tag){case 5:return a.child.stateNode;default:return a.child.stateNode}}function il(a,b){a=a.memoizedState;if(null!==a&&null!==a.dehydrated){var c=a.retryLane;a.retryLane=0!==c&&c<b?c:b}}function jl(a,b){il(a,b);(a=a.alternate)&&il(a,b)}function kl(){return null}var ll="function"===typeof reportError?reportError:function(a){console.error(a)};function ml(a){this._internalRoot=a}\nnl.prototype.render=ml.prototype.render=function(a){var b=this._internalRoot;if(null===b)throw Error(p(409));gl(a,b,null,null)};nl.prototype.unmount=ml.prototype.unmount=function(){var a=this._internalRoot;if(null!==a){this._internalRoot=null;var b=a.containerInfo;Sk(function(){gl(null,a,null,null)});b[uf]=null}};function nl(a){this._internalRoot=a}\nnl.prototype.unstable_scheduleHydration=function(a){if(a){var b=Hc();a={blockedOn:null,target:a,priority:b};for(var c=0;c<Qc.length&&0!==b&&b<Qc[c].priority;c++);Qc.splice(c,0,a);0===c&&Vc(a)}};function ol(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType)}function pl(a){return!(!a||1!==a.nodeType&&9!==a.nodeType&&11!==a.nodeType&&(8!==a.nodeType||" react-mount-point-unstable "!==a.nodeValue))}function ql(){}\nfunction rl(a,b,c,d,e){if(e){if("function"===typeof d){var f=d;d=function(){var a=hl(g);f.call(a)}}var g=fl(b,d,a,0,null,!1,!1,"",ql);a._reactRootContainer=g;a[uf]=g.current;sf(8===a.nodeType?a.parentNode:a);Sk();return g}for(;e=a.lastChild;)a.removeChild(e);if("function"===typeof d){var h=d;d=function(){var a=hl(k);h.call(a)}}var k=cl(a,0,!1,null,null,!1,!1,"",ql);a._reactRootContainer=k;a[uf]=k.current;sf(8===a.nodeType?a.parentNode:a);Sk(function(){gl(b,k,c,d)});return k}\nfunction sl(a,b,c,d,e){var f=c._reactRootContainer;if(f){var g=f;if("function"===typeof e){var h=e;e=function(){var a=hl(g);h.call(a)}}gl(b,g,a,e)}else g=rl(c,b,a,e,d);return hl(g)}Ec=function(a){switch(a.tag){case 3:var b=a.stateNode;if(b.current.memoizedState.isDehydrated){var c=tc(b.pendingLanes);0!==c&&(Cc(b,c|1),Ek(b,B()),0===(K&6)&&(Hj=B()+500,jg()))}break;case 13:Sk(function(){var b=Zg(a,1);if(null!==b){var c=L();mh(b,a,1,c)}}),jl(a,1)}};\nFc=function(a){if(13===a.tag){var b=Zg(a,134217728);if(null!==b){var c=L();mh(b,a,134217728,c)}jl(a,134217728)}};Gc=function(a){if(13===a.tag){var b=lh(a),c=Zg(a,b);if(null!==c){var d=L();mh(c,a,b,d)}jl(a,b)}};Hc=function(){return C};Ic=function(a,b){var c=C;try{return C=a,b()}finally{C=c}};\nyb=function(a,b,c){switch(b){case "input":bb(a,c);b=c.name;if("radio"===c.type&&null!=b){for(c=a;c.parentNode;)c=c.parentNode;c=c.querySelectorAll("input[name="+JSON.stringify(""+b)+\'][type="radio"]\');for(b=0;b<c.length;b++){var d=c[b];if(d!==a&&d.form===a.form){var e=Db(d);if(!e)throw Error(p(90));Wa(d);bb(d,e)}}}break;case "textarea":ib(a,c);break;case "select":b=c.value,null!=b&&fb(a,!!c.multiple,b,!1)}};Gb=Rk;Hb=Sk;\nvar tl={usingClientEntryPoint:!1,Events:[Cb,ue,Db,Eb,Fb,Rk]},ul={findFiberByHostInstance:Wc,bundleType:0,version:"18.2.0",rendererPackageName:"react-dom"};\nvar vl={bundleType:ul.bundleType,version:ul.version,rendererPackageName:ul.rendererPackageName,rendererConfig:ul.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:ua.ReactCurrentDispatcher,findHostInstanceByFiber:function(a){a=Zb(a);return null===a?null:a.stateNode},findFiberByHostInstance:ul.findFiberByHostInstance||\nkl,findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0-next-9e3b772b8-20220608"};if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var wl=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!wl.isDisabled&&wl.supportsFiber)try{kc=wl.inject(vl),lc=wl}catch(a){}}exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=tl;\nexports.createPortal=function(a,b){var c=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!ol(b))throw Error(p(200));return dl(a,b,null,c)};exports.createRoot=function(a,b){if(!ol(a))throw Error(p(299));var c=!1,d="",e=ll;null!==b&&void 0!==b&&(!0===b.unstable_strictMode&&(c=!0),void 0!==b.identifierPrefix&&(d=b.identifierPrefix),void 0!==b.onRecoverableError&&(e=b.onRecoverableError));b=cl(a,1,!1,null,null,c,!1,d,e);a[uf]=b.current;sf(8===a.nodeType?a.parentNode:a);return new ml(b)};\nexports.findDOMNode=function(a){if(null==a)return null;if(1===a.nodeType)return a;var b=a._reactInternals;if(void 0===b){if("function"===typeof a.render)throw Error(p(188));a=Object.keys(a).join(",");throw Error(p(268,a));}a=Zb(b);a=null===a?null:a.stateNode;return a};exports.flushSync=function(a){return Sk(a)};exports.hydrate=function(a,b,c){if(!pl(b))throw Error(p(200));return sl(null,a,b,!0,c)};\nexports.hydrateRoot=function(a,b,c){if(!ol(a))throw Error(p(405));var d=null!=c&&c.hydratedSources||null,e=!1,f="",g=ll;null!==c&&void 0!==c&&(!0===c.unstable_strictMode&&(e=!0),void 0!==c.identifierPrefix&&(f=c.identifierPrefix),void 0!==c.onRecoverableError&&(g=c.onRecoverableError));b=fl(b,null,a,1,null!=c?c:null,e,!1,f,g);a[uf]=b.current;sf(a);if(d)for(a=0;a<d.length;a++)c=d[a],e=c._getVersion,e=e(c._source),null==b.mutableSourceEagerHydrationData?b.mutableSourceEagerHydrationData=[c,e]:b.mutableSourceEagerHydrationData.push(c,\ne);return new nl(b)};exports.render=function(a,b,c){if(!pl(b))throw Error(p(200));return sl(null,a,b,!1,c)};exports.unmountComponentAtNode=function(a){if(!pl(a))throw Error(p(40));return a._reactRootContainer?(Sk(function(){sl(null,null,a,!1,function(){a._reactRootContainer=null;a[uf]=null})}),!0):!1};exports.unstable_batchedUpdates=Rk;\nexports.unstable_renderSubtreeIntoContainer=function(a,b,c,d){if(!pl(c))throw Error(p(200));if(null==a||void 0===a._reactInternals)throw Error(p(38));return sl(a,b,c,!1,d)};exports.version="18.2.0-next-9e3b772b8-20220608";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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QXNELHVLQUF1Syx5Q0FBeUMsZ0JBQWdCLE1BQU0sYUFBYSxXQUFXO0FBQ3RYLEdBQUcsa0JBQWtCLGNBQWMsaUJBQWlCLDhCQUE4QiwwQkFBMEIsOEJBQThCLGFBQWEsNkJBQTZCLDRDQUE0Qyw2QkFBNkIsMkJBQTJCLFdBQVcsRUFBRSxVQUFVLCtCQUErQjtBQUM5VSwyQ0FBMkMsbUJBQW1CLDhCQUE4QiwwREFBMEQsdUJBQXVCLGVBQWUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVhY3QtZG9tL2Nqcy9yZWFjdC1kb20ucHJvZHVjdGlvbi5taW4uanM/Y2E1ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC1kb20ucHJvZHVjdGlvbi5taW4uanNcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIEZhY2Vib29rLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuLypcbiBNb2Rlcm5penIgMy4wLjBwcmUgKEN1c3RvbSBCdWlsZCkgfCBNSVRcbiovXG4ndXNlIHN0cmljdCc7dmFyIGFhPXJlcXVpcmUoXCJyZWFjdFwiKSxjYT1yZXF1aXJlKFwic2NoZWR1bGVyXCIpO2Z1bmN0aW9uIHAoYSl7Zm9yKHZhciBiPVwiaHR0cHM6Ly9yZWFjdGpzLm9yZy9kb2NzL2Vycm9yLWRlY29kZXIuaHRtbD9pbnZhcmlhbnQ9XCIrYSxjPTE7Yzxhcmd1bWVudHMubGVuZ3RoO2MrKyliKz1cIiZhcmdzW109XCIrZW5jb2RlVVJJQ29tcG9uZW50KGFyZ3VtZW50c1tjXSk7cmV0dXJuXCJNaW5pZmllZCBSZWFjdCBlcnJvciAjXCIrYStcIjsgdmlzaXQgXCIrYitcIiBmb3IgdGhlIGZ1bGwgbWVzc2FnZSBvciB1c2UgdGhlIG5vbi1taW5pZmllZCBkZXYgZW52aXJvbm1lbnQgZm9yIGZ1bGwgZXJyb3JzIGFuZCBhZGRpdGlvbmFsIGhlbHBmdWwgd2FybmluZ3MuXCJ9dmFyIGRhPW5ldyBTZXQsZWE9e307ZnVuY3Rpb24gZmEoYSxiKXtoYShhLGIpO2hhKGErXCJDYXB0dXJlXCIsYil9XG5mdW5jdGlvbiBoYShhLGIpe2VhW2FdPWI7Zm9yKGE9MDthPGIubGVuZ3RoO2ErKylkYS5hZGQoYlthXSl9XG52YXIgaWE9IShcInVuZGVmaW5lZFwiPT09dHlwZW9mIHdpbmRvd3x8XCJ1bmRlZmluZWRcIj09PXR5cGVvZiB3aW5kb3cuZG9jdW1lbnR8fFwidW5kZWZpbmVkXCI9PT10eXBlb2Ygd2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQpLGphPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksa2E9L15bOkEtWl9hLXpcXHUwMEMwLVxcdTAwRDZcXHUwMEQ4LVxcdTAwRjZcXHUwMEY4LVxcdTAyRkZcXHUwMzcwLVxcdTAzN0RcXHUwMzdGLVxcdTFGRkZcXHUyMDBDLVxcdTIwMERcXHUyMDcwLVxcdTIxOEZcXHUyQzAwLVxcdTJGRUZcXHUzMDAxLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRkRdWzpBLVpfYS16XFx1MDBDMC1cXHUwMEQ2XFx1MDBEOC1cXHUwMEY2XFx1MDBGOC1cXHUwMkZGXFx1MDM3MC1cXHUwMzdEXFx1MDM3Ri1cXHUxRkZGXFx1MjAwQy1cXHUyMDBEXFx1MjA3MC1cXHUyMThGXFx1MkMwMC1cXHUyRkVGXFx1MzAwMS1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkZEXFwtLjAtOVxcdTAwQjdcXHUwMzAwLVxcdTAzNkZcXHUyMDNGLVxcdTIwNDBdKiQvLGxhPVxue30sbWE9e307ZnVuY3Rpb24gb2EoYSl7aWYoamEuY2FsbChtYSxhKSlyZXR1cm4hMDtpZihqYS5jYWxsKGxhLGEpKXJldHVybiExO2lmKGthLnRlc3QoYSkpcmV0dXJuIG1hW2FdPSEwO2xhW2FdPSEwO3JldHVybiExfWZ1bmN0aW9uIHBhKGEsYixjLGQpe2lmKG51bGwhPT1jJiYwPT09Yy50eXBlKXJldHVybiExO3N3aXRjaCh0eXBlb2YgYil7Y2FzZSBcImZ1bmN0aW9uXCI6Y2FzZSBcInN5bWJvbFwiOnJldHVybiEwO2Nhc2UgXCJib29sZWFuXCI6aWYoZClyZXR1cm4hMTtpZihudWxsIT09YylyZXR1cm4hYy5hY2NlcHRzQm9vbGVhbnM7YT1hLnRvTG93ZXJDYXNlKCkuc2xpY2UoMCw1KTtyZXR1cm5cImRhdGEtXCIhPT1hJiZcImFyaWEtXCIhPT1hO2RlZmF1bHQ6cmV0dXJuITF9fVxuZnVuY3Rpb24gcWEoYSxiLGMsZCl7aWYobnVsbD09PWJ8fFwidW5kZWZpbmVkXCI9PT10eXBlb2YgYnx8cGEoYSxiLGMsZCkpcmV0dXJuITA7aWYoZClyZXR1cm4hMTtpZihudWxsIT09Yylzd2l0Y2goYy50eXBlKXtjYXNlIDM6cmV0dXJuIWI7Y2FzZSA0OnJldHVybiExPT09YjtjYXNlIDU6cmV0dXJuIGlzTmFOKGIpO2Nhc2UgNjpyZXR1cm4gaXNOYU4oYil8fDE+Yn1yZXR1cm4hMX1mdW5jdGlvbiB2KGEsYixjLGQsZSxmLGcpe3RoaXMuYWNjZXB0c0Jvb2xlYW5zPTI9PT1ifHwzPT09Ynx8ND09PWI7dGhpcy5hdHRyaWJ1dGVOYW1lPWQ7dGhpcy5hdHRyaWJ1dGVOYW1lc3BhY2U9ZTt0aGlzLm11c3RVc2VQcm9wZXJ0eT1jO3RoaXMucHJvcGVydHlOYW1lPWE7dGhpcy50eXBlPWI7dGhpcy5zYW5pdGl6ZVVSTD1mO3RoaXMucmVtb3ZlRW1wdHlTdHJpbmc9Z312YXIgej17fTtcblwiY2hpbGRyZW4gZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwgZGVmYXVsdFZhbHVlIGRlZmF1bHRDaGVja2VkIGlubmVySFRNTCBzdXBwcmVzc0NvbnRlbnRFZGl0YWJsZVdhcm5pbmcgc3VwcHJlc3NIeWRyYXRpb25XYXJuaW5nIHN0eWxlXCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDAsITEsYSxudWxsLCExLCExKX0pO1tbXCJhY2NlcHRDaGFyc2V0XCIsXCJhY2NlcHQtY2hhcnNldFwiXSxbXCJjbGFzc05hbWVcIixcImNsYXNzXCJdLFtcImh0bWxGb3JcIixcImZvclwiXSxbXCJodHRwRXF1aXZcIixcImh0dHAtZXF1aXZcIl1dLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YVswXTt6W2JdPW5ldyB2KGIsMSwhMSxhWzFdLG51bGwsITEsITEpfSk7W1wiY29udGVudEVkaXRhYmxlXCIsXCJkcmFnZ2FibGVcIixcInNwZWxsQ2hlY2tcIixcInZhbHVlXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDIsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7XG5bXCJhdXRvUmV2ZXJzZVwiLFwiZXh0ZXJuYWxSZXNvdXJjZXNSZXF1aXJlZFwiLFwiZm9jdXNhYmxlXCIsXCJwcmVzZXJ2ZUFscGhhXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDIsITEsYSxudWxsLCExLCExKX0pO1wiYWxsb3dGdWxsU2NyZWVuIGFzeW5jIGF1dG9Gb2N1cyBhdXRvUGxheSBjb250cm9scyBkZWZhdWx0IGRlZmVyIGRpc2FibGVkIGRpc2FibGVQaWN0dXJlSW5QaWN0dXJlIGRpc2FibGVSZW1vdGVQbGF5YmFjayBmb3JtTm9WYWxpZGF0ZSBoaWRkZW4gbG9vcCBub01vZHVsZSBub1ZhbGlkYXRlIG9wZW4gcGxheXNJbmxpbmUgcmVhZE9ubHkgcmVxdWlyZWQgcmV2ZXJzZWQgc2NvcGVkIHNlYW1sZXNzIGl0ZW1TY29wZVwiLnNwbGl0KFwiIFwiKS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3pbYV09bmV3IHYoYSwzLCExLGEudG9Mb3dlckNhc2UoKSxudWxsLCExLCExKX0pO1xuW1wiY2hlY2tlZFwiLFwibXVsdGlwbGVcIixcIm11dGVkXCIsXCJzZWxlY3RlZFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3pbYV09bmV3IHYoYSwzLCEwLGEsbnVsbCwhMSwhMSl9KTtbXCJjYXB0dXJlXCIsXCJkb3dubG9hZFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3pbYV09bmV3IHYoYSw0LCExLGEsbnVsbCwhMSwhMSl9KTtbXCJjb2xzXCIsXCJyb3dzXCIsXCJzaXplXCIsXCJzcGFuXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDYsITEsYSxudWxsLCExLCExKX0pO1tcInJvd1NwYW5cIixcInN0YXJ0XCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDUsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7dmFyIHJhPS9bXFwtOl0oW2Etel0pL2c7ZnVuY3Rpb24gc2EoYSl7cmV0dXJuIGFbMV0udG9VcHBlckNhc2UoKX1cblwiYWNjZW50LWhlaWdodCBhbGlnbm1lbnQtYmFzZWxpbmUgYXJhYmljLWZvcm0gYmFzZWxpbmUtc2hpZnQgY2FwLWhlaWdodCBjbGlwLXBhdGggY2xpcC1ydWxlIGNvbG9yLWludGVycG9sYXRpb24gY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzIGNvbG9yLXByb2ZpbGUgY29sb3ItcmVuZGVyaW5nIGRvbWluYW50LWJhc2VsaW5lIGVuYWJsZS1iYWNrZ3JvdW5kIGZpbGwtb3BhY2l0eSBmaWxsLXJ1bGUgZmxvb2QtY29sb3IgZmxvb2Qtb3BhY2l0eSBmb250LWZhbWlseSBmb250LXNpemUgZm9udC1zaXplLWFkanVzdCBmb250LXN0cmV0Y2ggZm9udC1zdHlsZSBmb250LXZhcmlhbnQgZm9udC13ZWlnaHQgZ2x5cGgtbmFtZSBnbHlwaC1vcmllbnRhdGlvbi1ob3Jpem9udGFsIGdseXBoLW9yaWVudGF0aW9uLXZlcnRpY2FsIGhvcml6LWFkdi14IGhvcml6LW9yaWdpbi14IGltYWdlLXJlbmRlcmluZyBsZXR0ZXItc3BhY2luZyBsaWdodGluZy1jb2xvciBtYXJrZXItZW5kIG1hcmtlci1taWQgbWFya2VyLXN0YXJ0IG92ZXJsaW5lLXBvc2l0aW9uIG92ZXJsaW5lLXRoaWNrbmVzcyBwYWludC1vcmRlciBwYW5vc2UtMSBwb2ludGVyLWV2ZW50cyByZW5kZXJpbmctaW50ZW50IHNoYXBlLXJlbmRlcmluZyBzdG9wLWNvbG9yIHN0b3Atb3BhY2l0eSBzdHJpa2V0aHJvdWdoLXBvc2l0aW9uIHN0cmlrZXRocm91Z2gtdGhpY2tuZXNzIHN0cm9rZS1kYXNoYXJyYXkgc3Ryb2tlLWRhc2hvZmZzZXQgc3Ryb2tlLWxpbmVjYXAgc3Ryb2tlLWxpbmVqb2luIHN0cm9rZS1taXRlcmxpbWl0IHN0cm9rZS1vcGFjaXR5IHN0cm9rZS13aWR0aCB0ZXh0LWFuY2hvciB0ZXh0LWRlY29yYXRpb24gdGV4dC1yZW5kZXJpbmcgdW5kZXJsaW5lLXBvc2l0aW9uIHVuZGVybGluZS10aGlja25lc3MgdW5pY29kZS1iaWRpIHVuaWNvZGUtcmFuZ2UgdW5pdHMtcGVyLWVtIHYtYWxwaGFiZXRpYyB2LWhhbmdpbmcgdi1pZGVvZ3JhcGhpYyB2LW1hdGhlbWF0aWNhbCB2ZWN0b3ItZWZmZWN0IHZlcnQtYWR2LXkgdmVydC1vcmlnaW4teCB2ZXJ0LW9yaWdpbi15IHdvcmQtc3BhY2luZyB3cml0aW5nLW1vZGUgeG1sbnM6eGxpbmsgeC1oZWlnaHRcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UocmEsXG5zYSk7eltiXT1uZXcgdihiLDEsITEsYSxudWxsLCExLCExKX0pO1wieGxpbms6YWN0dWF0ZSB4bGluazphcmNyb2xlIHhsaW5rOnJvbGUgeGxpbms6c2hvdyB4bGluazp0aXRsZSB4bGluazp0eXBlXCIuc3BsaXQoXCIgXCIpLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YS5yZXBsYWNlKHJhLHNhKTt6W2JdPW5ldyB2KGIsMSwhMSxhLFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiLCExLCExKX0pO1tcInhtbDpiYXNlXCIsXCJ4bWw6bGFuZ1wiLFwieG1sOnNwYWNlXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YS5yZXBsYWNlKHJhLHNhKTt6W2JdPW5ldyB2KGIsMSwhMSxhLFwiaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlXCIsITEsITEpfSk7W1widGFiSW5kZXhcIixcImNyb3NzT3JpZ2luXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDEsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITEsITEpfSk7XG56LnhsaW5rSHJlZj1uZXcgdihcInhsaW5rSHJlZlwiLDEsITEsXCJ4bGluazpocmVmXCIsXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIsITAsITEpO1tcInNyY1wiLFwiaHJlZlwiLFwiYWN0aW9uXCIsXCJmb3JtQWN0aW9uXCJdLmZvckVhY2goZnVuY3Rpb24oYSl7elthXT1uZXcgdihhLDEsITEsYS50b0xvd2VyQ2FzZSgpLG51bGwsITAsITApfSk7XG5mdW5jdGlvbiB0YShhLGIsYyxkKXt2YXIgZT16Lmhhc093blByb3BlcnR5KGIpP3pbYl06bnVsbDtpZihudWxsIT09ZT8wIT09ZS50eXBlOmR8fCEoMjxiLmxlbmd0aCl8fFwib1wiIT09YlswXSYmXCJPXCIhPT1iWzBdfHxcIm5cIiE9PWJbMV0mJlwiTlwiIT09YlsxXSlxYShiLGMsZSxkKSYmKGM9bnVsbCksZHx8bnVsbD09PWU/b2EoYikmJihudWxsPT09Yz9hLnJlbW92ZUF0dHJpYnV0ZShiKTphLnNldEF0dHJpYnV0ZShiLFwiXCIrYykpOmUubXVzdFVzZVByb3BlcnR5P2FbZS5wcm9wZXJ0eU5hbWVdPW51bGw9PT1jPzM9PT1lLnR5cGU/ITE6XCJcIjpjOihiPWUuYXR0cmlidXRlTmFtZSxkPWUuYXR0cmlidXRlTmFtZXNwYWNlLG51bGw9PT1jP2EucmVtb3ZlQXR0cmlidXRlKGIpOihlPWUudHlwZSxjPTM9PT1lfHw0PT09ZSYmITA9PT1jP1wiXCI6XCJcIitjLGQ/YS5zZXRBdHRyaWJ1dGVOUyhkLGIsYyk6YS5zZXRBdHRyaWJ1dGUoYixjKSkpfVxudmFyIHVhPWFhLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVELHZhPVN5bWJvbC5mb3IoXCJyZWFjdC5lbGVtZW50XCIpLHdhPVN5bWJvbC5mb3IoXCJyZWFjdC5wb3J0YWxcIikseWE9U3ltYm9sLmZvcihcInJlYWN0LmZyYWdtZW50XCIpLHphPVN5bWJvbC5mb3IoXCJyZWFjdC5zdHJpY3RfbW9kZVwiKSxBYT1TeW1ib2wuZm9yKFwicmVhY3QucHJvZmlsZXJcIiksQmE9U3ltYm9sLmZvcihcInJlYWN0LnByb3ZpZGVyXCIpLENhPVN5bWJvbC5mb3IoXCJyZWFjdC5jb250ZXh0XCIpLERhPVN5bWJvbC5mb3IoXCJyZWFjdC5mb3J3YXJkX3JlZlwiKSxFYT1TeW1ib2wuZm9yKFwicmVhY3Quc3VzcGVuc2VcIiksRmE9U3ltYm9sLmZvcihcInJlYWN0LnN1c3BlbnNlX2xpc3RcIiksR2E9U3ltYm9sLmZvcihcInJlYWN0Lm1lbW9cIiksSGE9U3ltYm9sLmZvcihcInJlYWN0LmxhenlcIik7U3ltYm9sLmZvcihcInJlYWN0LnNjb3BlXCIpO1N5bWJvbC5mb3IoXCJyZWFjdC5kZWJ1Z190cmFjZV9tb2RlXCIpO1xudmFyIElhPVN5bWJvbC5mb3IoXCJyZWFjdC5vZmZzY3JlZW5cIik7U3ltYm9sLmZvcihcInJlYWN0LmxlZ2FjeV9oaWRkZW5cIik7U3ltYm9sLmZvcihcInJlYWN0LmNhY2hlXCIpO1N5bWJvbC5mb3IoXCJyZWFjdC50cmFjaW5nX21hcmtlclwiKTt2YXIgSmE9U3ltYm9sLml0ZXJhdG9yO2Z1bmN0aW9uIEthKGEpe2lmKG51bGw9PT1hfHxcIm9iamVjdFwiIT09dHlwZW9mIGEpcmV0dXJuIG51bGw7YT1KYSYmYVtKYV18fGFbXCJAQGl0ZXJhdG9yXCJdO3JldHVyblwiZnVuY3Rpb25cIj09PXR5cGVvZiBhP2E6bnVsbH12YXIgQT1PYmplY3QuYXNzaWduLExhO2Z1bmN0aW9uIE1hKGEpe2lmKHZvaWQgMD09PUxhKXRyeXt0aHJvdyBFcnJvcigpO31jYXRjaChjKXt2YXIgYj1jLnN0YWNrLnRyaW0oKS5tYXRjaCgvXFxuKCAqKGF0ICk/KS8pO0xhPWImJmJbMV18fFwiXCJ9cmV0dXJuXCJcXG5cIitMYSthfXZhciBOYT0hMTtcbmZ1bmN0aW9uIE9hKGEsYil7aWYoIWF8fE5hKXJldHVyblwiXCI7TmE9ITA7dmFyIGM9RXJyb3IucHJlcGFyZVN0YWNrVHJhY2U7RXJyb3IucHJlcGFyZVN0YWNrVHJhY2U9dm9pZCAwO3RyeXtpZihiKWlmKGI9ZnVuY3Rpb24oKXt0aHJvdyBFcnJvcigpO30sT2JqZWN0LmRlZmluZVByb3BlcnR5KGIucHJvdG90eXBlLFwicHJvcHNcIix7c2V0OmZ1bmN0aW9uKCl7dGhyb3cgRXJyb3IoKTt9fSksXCJvYmplY3RcIj09PXR5cGVvZiBSZWZsZWN0JiZSZWZsZWN0LmNvbnN0cnVjdCl7dHJ5e1JlZmxlY3QuY29uc3RydWN0KGIsW10pfWNhdGNoKGwpe3ZhciBkPWx9UmVmbGVjdC5jb25zdHJ1Y3QoYSxbXSxiKX1lbHNle3RyeXtiLmNhbGwoKX1jYXRjaChsKXtkPWx9YS5jYWxsKGIucHJvdG90eXBlKX1lbHNle3RyeXt0aHJvdyBFcnJvcigpO31jYXRjaChsKXtkPWx9YSgpfX1jYXRjaChsKXtpZihsJiZkJiZcInN0cmluZ1wiPT09dHlwZW9mIGwuc3RhY2spe2Zvcih2YXIgZT1sLnN0YWNrLnNwbGl0KFwiXFxuXCIpLFxuZj1kLnN0YWNrLnNwbGl0KFwiXFxuXCIpLGc9ZS5sZW5ndGgtMSxoPWYubGVuZ3RoLTE7MTw9ZyYmMDw9aCYmZVtnXSE9PWZbaF07KWgtLTtmb3IoOzE8PWcmJjA8PWg7Zy0tLGgtLSlpZihlW2ddIT09ZltoXSl7aWYoMSE9PWd8fDEhPT1oKXtkbyBpZihnLS0saC0tLDA+aHx8ZVtnXSE9PWZbaF0pe3ZhciBrPVwiXFxuXCIrZVtnXS5yZXBsYWNlKFwiIGF0IG5ldyBcIixcIiBhdCBcIik7YS5kaXNwbGF5TmFtZSYmay5pbmNsdWRlcyhcIjxhbm9ueW1vdXM+XCIpJiYoaz1rLnJlcGxhY2UoXCI8YW5vbnltb3VzPlwiLGEuZGlzcGxheU5hbWUpKTtyZXR1cm4ga313aGlsZSgxPD1nJiYwPD1oKX1icmVha319fWZpbmFsbHl7TmE9ITEsRXJyb3IucHJlcGFyZVN0YWNrVHJhY2U9Y31yZXR1cm4oYT1hP2EuZGlzcGxheU5hbWV8fGEubmFtZTpcIlwiKT9NYShhKTpcIlwifVxuZnVuY3Rpb24gUGEoYSl7c3dpdGNoKGEudGFnKXtjYXNlIDU6cmV0dXJuIE1hKGEudHlwZSk7Y2FzZSAxNjpyZXR1cm4gTWEoXCJMYXp5XCIpO2Nhc2UgMTM6cmV0dXJuIE1hKFwiU3VzcGVuc2VcIik7Y2FzZSAxOTpyZXR1cm4gTWEoXCJTdXNwZW5zZUxpc3RcIik7Y2FzZSAwOmNhc2UgMjpjYXNlIDE1OnJldHVybiBhPU9hKGEudHlwZSwhMSksYTtjYXNlIDExOnJldHVybiBhPU9hKGEudHlwZS5yZW5kZXIsITEpLGE7Y2FzZSAxOnJldHVybiBhPU9hKGEudHlwZSwhMCksYTtkZWZhdWx0OnJldHVyblwiXCJ9fVxuZnVuY3Rpb24gUWEoYSl7aWYobnVsbD09YSlyZXR1cm4gbnVsbDtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYSlyZXR1cm4gYS5kaXNwbGF5TmFtZXx8YS5uYW1lfHxudWxsO2lmKFwic3RyaW5nXCI9PT10eXBlb2YgYSlyZXR1cm4gYTtzd2l0Y2goYSl7Y2FzZSB5YTpyZXR1cm5cIkZyYWdtZW50XCI7Y2FzZSB3YTpyZXR1cm5cIlBvcnRhbFwiO2Nhc2UgQWE6cmV0dXJuXCJQcm9maWxlclwiO2Nhc2UgemE6cmV0dXJuXCJTdHJpY3RNb2RlXCI7Y2FzZSBFYTpyZXR1cm5cIlN1c3BlbnNlXCI7Y2FzZSBGYTpyZXR1cm5cIlN1c3BlbnNlTGlzdFwifWlmKFwib2JqZWN0XCI9PT10eXBlb2YgYSlzd2l0Y2goYS4kJHR5cGVvZil7Y2FzZSBDYTpyZXR1cm4oYS5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLkNvbnN1bWVyXCI7Y2FzZSBCYTpyZXR1cm4oYS5fY29udGV4dC5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLlByb3ZpZGVyXCI7Y2FzZSBEYTp2YXIgYj1hLnJlbmRlcjthPWEuZGlzcGxheU5hbWU7YXx8KGE9Yi5kaXNwbGF5TmFtZXx8XG5iLm5hbWV8fFwiXCIsYT1cIlwiIT09YT9cIkZvcndhcmRSZWYoXCIrYStcIilcIjpcIkZvcndhcmRSZWZcIik7cmV0dXJuIGE7Y2FzZSBHYTpyZXR1cm4gYj1hLmRpc3BsYXlOYW1lfHxudWxsLG51bGwhPT1iP2I6UWEoYS50eXBlKXx8XCJNZW1vXCI7Y2FzZSBIYTpiPWEuX3BheWxvYWQ7YT1hLl9pbml0O3RyeXtyZXR1cm4gUWEoYShiKSl9Y2F0Y2goYyl7fX1yZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFJhKGEpe3ZhciBiPWEudHlwZTtzd2l0Y2goYS50YWcpe2Nhc2UgMjQ6cmV0dXJuXCJDYWNoZVwiO2Nhc2UgOTpyZXR1cm4oYi5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLkNvbnN1bWVyXCI7Y2FzZSAxMDpyZXR1cm4oYi5fY29udGV4dC5kaXNwbGF5TmFtZXx8XCJDb250ZXh0XCIpK1wiLlByb3ZpZGVyXCI7Y2FzZSAxODpyZXR1cm5cIkRlaHlkcmF0ZWRGcmFnbWVudFwiO2Nhc2UgMTE6cmV0dXJuIGE9Yi5yZW5kZXIsYT1hLmRpc3BsYXlOYW1lfHxhLm5hbWV8fFwiXCIsYi5kaXNwbGF5TmFtZXx8KFwiXCIhPT1hP1wiRm9yd2FyZFJlZihcIithK1wiKVwiOlwiRm9yd2FyZFJlZlwiKTtjYXNlIDc6cmV0dXJuXCJGcmFnbWVudFwiO2Nhc2UgNTpyZXR1cm4gYjtjYXNlIDQ6cmV0dXJuXCJQb3J0YWxcIjtjYXNlIDM6cmV0dXJuXCJSb290XCI7Y2FzZSA2OnJldHVyblwiVGV4dFwiO2Nhc2UgMTY6cmV0dXJuIFFhKGIpO2Nhc2UgODpyZXR1cm4gYj09PXphP1wiU3RyaWN0TW9kZVwiOlwiTW9kZVwiO2Nhc2UgMjI6cmV0dXJuXCJPZmZzY3JlZW5cIjtcbmNhc2UgMTI6cmV0dXJuXCJQcm9maWxlclwiO2Nhc2UgMjE6cmV0dXJuXCJTY29wZVwiO2Nhc2UgMTM6cmV0dXJuXCJTdXNwZW5zZVwiO2Nhc2UgMTk6cmV0dXJuXCJTdXNwZW5zZUxpc3RcIjtjYXNlIDI1OnJldHVyblwiVHJhY2luZ01hcmtlclwiO2Nhc2UgMTpjYXNlIDA6Y2FzZSAxNzpjYXNlIDI6Y2FzZSAxNDpjYXNlIDE1OmlmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBiKXJldHVybiBiLmRpc3BsYXlOYW1lfHxiLm5hbWV8fG51bGw7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBiKXJldHVybiBifXJldHVybiBudWxsfWZ1bmN0aW9uIFNhKGEpe3N3aXRjaCh0eXBlb2YgYSl7Y2FzZSBcImJvb2xlYW5cIjpjYXNlIFwibnVtYmVyXCI6Y2FzZSBcInN0cmluZ1wiOmNhc2UgXCJ1bmRlZmluZWRcIjpyZXR1cm4gYTtjYXNlIFwib2JqZWN0XCI6cmV0dXJuIGE7ZGVmYXVsdDpyZXR1cm5cIlwifX1cbmZ1bmN0aW9uIFRhKGEpe3ZhciBiPWEudHlwZTtyZXR1cm4oYT1hLm5vZGVOYW1lKSYmXCJpbnB1dFwiPT09YS50b0xvd2VyQ2FzZSgpJiYoXCJjaGVja2JveFwiPT09Ynx8XCJyYWRpb1wiPT09Yil9XG5mdW5jdGlvbiBVYShhKXt2YXIgYj1UYShhKT9cImNoZWNrZWRcIjpcInZhbHVlXCIsYz1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGEuY29uc3RydWN0b3IucHJvdG90eXBlLGIpLGQ9XCJcIithW2JdO2lmKCFhLmhhc093blByb3BlcnR5KGIpJiZcInVuZGVmaW5lZFwiIT09dHlwZW9mIGMmJlwiZnVuY3Rpb25cIj09PXR5cGVvZiBjLmdldCYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGMuc2V0KXt2YXIgZT1jLmdldCxmPWMuc2V0O09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLGIse2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gZS5jYWxsKHRoaXMpfSxzZXQ6ZnVuY3Rpb24oYSl7ZD1cIlwiK2E7Zi5jYWxsKHRoaXMsYSl9fSk7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsYix7ZW51bWVyYWJsZTpjLmVudW1lcmFibGV9KTtyZXR1cm57Z2V0VmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm4gZH0sc2V0VmFsdWU6ZnVuY3Rpb24oYSl7ZD1cIlwiK2F9LHN0b3BUcmFja2luZzpmdW5jdGlvbigpe2EuX3ZhbHVlVHJhY2tlcj1cbm51bGw7ZGVsZXRlIGFbYl19fX19ZnVuY3Rpb24gVmEoYSl7YS5fdmFsdWVUcmFja2VyfHwoYS5fdmFsdWVUcmFja2VyPVVhKGEpKX1mdW5jdGlvbiBXYShhKXtpZighYSlyZXR1cm4hMTt2YXIgYj1hLl92YWx1ZVRyYWNrZXI7aWYoIWIpcmV0dXJuITA7dmFyIGM9Yi5nZXRWYWx1ZSgpO3ZhciBkPVwiXCI7YSYmKGQ9VGEoYSk/YS5jaGVja2VkP1widHJ1ZVwiOlwiZmFsc2VcIjphLnZhbHVlKTthPWQ7cmV0dXJuIGEhPT1jPyhiLnNldFZhbHVlKGEpLCEwKTohMX1mdW5jdGlvbiBYYShhKXthPWF8fChcInVuZGVmaW5lZFwiIT09dHlwZW9mIGRvY3VtZW50P2RvY3VtZW50OnZvaWQgMCk7aWYoXCJ1bmRlZmluZWRcIj09PXR5cGVvZiBhKXJldHVybiBudWxsO3RyeXtyZXR1cm4gYS5hY3RpdmVFbGVtZW50fHxhLmJvZHl9Y2F0Y2goYil7cmV0dXJuIGEuYm9keX19XG5mdW5jdGlvbiBZYShhLGIpe3ZhciBjPWIuY2hlY2tlZDtyZXR1cm4gQSh7fSxiLHtkZWZhdWx0Q2hlY2tlZDp2b2lkIDAsZGVmYXVsdFZhbHVlOnZvaWQgMCx2YWx1ZTp2b2lkIDAsY2hlY2tlZDpudWxsIT1jP2M6YS5fd3JhcHBlclN0YXRlLmluaXRpYWxDaGVja2VkfSl9ZnVuY3Rpb24gWmEoYSxiKXt2YXIgYz1udWxsPT1iLmRlZmF1bHRWYWx1ZT9cIlwiOmIuZGVmYXVsdFZhbHVlLGQ9bnVsbCE9Yi5jaGVja2VkP2IuY2hlY2tlZDpiLmRlZmF1bHRDaGVja2VkO2M9U2EobnVsbCE9Yi52YWx1ZT9iLnZhbHVlOmMpO2EuX3dyYXBwZXJTdGF0ZT17aW5pdGlhbENoZWNrZWQ6ZCxpbml0aWFsVmFsdWU6Yyxjb250cm9sbGVkOlwiY2hlY2tib3hcIj09PWIudHlwZXx8XCJyYWRpb1wiPT09Yi50eXBlP251bGwhPWIuY2hlY2tlZDpudWxsIT1iLnZhbHVlfX1mdW5jdGlvbiBhYihhLGIpe2I9Yi5jaGVja2VkO251bGwhPWImJnRhKGEsXCJjaGVja2VkXCIsYiwhMSl9XG5mdW5jdGlvbiBiYihhLGIpe2FiKGEsYik7dmFyIGM9U2EoYi52YWx1ZSksZD1iLnR5cGU7aWYobnVsbCE9YylpZihcIm51bWJlclwiPT09ZCl7aWYoMD09PWMmJlwiXCI9PT1hLnZhbHVlfHxhLnZhbHVlIT1jKWEudmFsdWU9XCJcIitjfWVsc2UgYS52YWx1ZSE9PVwiXCIrYyYmKGEudmFsdWU9XCJcIitjKTtlbHNlIGlmKFwic3VibWl0XCI9PT1kfHxcInJlc2V0XCI9PT1kKXthLnJlbW92ZUF0dHJpYnV0ZShcInZhbHVlXCIpO3JldHVybn1iLmhhc093blByb3BlcnR5KFwidmFsdWVcIik/Y2IoYSxiLnR5cGUsYyk6Yi5oYXNPd25Qcm9wZXJ0eShcImRlZmF1bHRWYWx1ZVwiKSYmY2IoYSxiLnR5cGUsU2EoYi5kZWZhdWx0VmFsdWUpKTtudWxsPT1iLmNoZWNrZWQmJm51bGwhPWIuZGVmYXVsdENoZWNrZWQmJihhLmRlZmF1bHRDaGVja2VkPSEhYi5kZWZhdWx0Q2hlY2tlZCl9XG5mdW5jdGlvbiBkYihhLGIsYyl7aWYoYi5oYXNPd25Qcm9wZXJ0eShcInZhbHVlXCIpfHxiLmhhc093blByb3BlcnR5KFwiZGVmYXVsdFZhbHVlXCIpKXt2YXIgZD1iLnR5cGU7aWYoIShcInN1Ym1pdFwiIT09ZCYmXCJyZXNldFwiIT09ZHx8dm9pZCAwIT09Yi52YWx1ZSYmbnVsbCE9PWIudmFsdWUpKXJldHVybjtiPVwiXCIrYS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZTtjfHxiPT09YS52YWx1ZXx8KGEudmFsdWU9Yik7YS5kZWZhdWx0VmFsdWU9Yn1jPWEubmFtZTtcIlwiIT09YyYmKGEubmFtZT1cIlwiKTthLmRlZmF1bHRDaGVja2VkPSEhYS5fd3JhcHBlclN0YXRlLmluaXRpYWxDaGVja2VkO1wiXCIhPT1jJiYoYS5uYW1lPWMpfVxuZnVuY3Rpb24gY2IoYSxiLGMpe2lmKFwibnVtYmVyXCIhPT1ifHxYYShhLm93bmVyRG9jdW1lbnQpIT09YSludWxsPT1jP2EuZGVmYXVsdFZhbHVlPVwiXCIrYS5fd3JhcHBlclN0YXRlLmluaXRpYWxWYWx1ZTphLmRlZmF1bHRWYWx1ZSE9PVwiXCIrYyYmKGEuZGVmYXVsdFZhbHVlPVwiXCIrYyl9dmFyIGViPUFycmF5LmlzQXJyYXk7XG5mdW5jdGlvbiBmYihhLGIsYyxkKXthPWEub3B0aW9ucztpZihiKXtiPXt9O2Zvcih2YXIgZT0wO2U8Yy5sZW5ndGg7ZSsrKWJbXCIkXCIrY1tlXV09ITA7Zm9yKGM9MDtjPGEubGVuZ3RoO2MrKyllPWIuaGFzT3duUHJvcGVydHkoXCIkXCIrYVtjXS52YWx1ZSksYVtjXS5zZWxlY3RlZCE9PWUmJihhW2NdLnNlbGVjdGVkPWUpLGUmJmQmJihhW2NdLmRlZmF1bHRTZWxlY3RlZD0hMCl9ZWxzZXtjPVwiXCIrU2EoYyk7Yj1udWxsO2ZvcihlPTA7ZTxhLmxlbmd0aDtlKyspe2lmKGFbZV0udmFsdWU9PT1jKXthW2VdLnNlbGVjdGVkPSEwO2QmJihhW2VdLmRlZmF1bHRTZWxlY3RlZD0hMCk7cmV0dXJufW51bGwhPT1ifHxhW2VdLmRpc2FibGVkfHwoYj1hW2VdKX1udWxsIT09YiYmKGIuc2VsZWN0ZWQ9ITApfX1cbmZ1bmN0aW9uIGdiKGEsYil7aWYobnVsbCE9Yi5kYW5nZXJvdXNseVNldElubmVySFRNTCl0aHJvdyBFcnJvcihwKDkxKSk7cmV0dXJuIEEoe30sYix7dmFsdWU6dm9pZCAwLGRlZmF1bHRWYWx1ZTp2b2lkIDAsY2hpbGRyZW46XCJcIithLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlfSl9ZnVuY3Rpb24gaGIoYSxiKXt2YXIgYz1iLnZhbHVlO2lmKG51bGw9PWMpe2M9Yi5jaGlsZHJlbjtiPWIuZGVmYXVsdFZhbHVlO2lmKG51bGwhPWMpe2lmKG51bGwhPWIpdGhyb3cgRXJyb3IocCg5MikpO2lmKGViKGMpKXtpZigxPGMubGVuZ3RoKXRocm93IEVycm9yKHAoOTMpKTtjPWNbMF19Yj1jfW51bGw9PWImJihiPVwiXCIpO2M9Yn1hLl93cmFwcGVyU3RhdGU9e2luaXRpYWxWYWx1ZTpTYShjKX19XG5mdW5jdGlvbiBpYihhLGIpe3ZhciBjPVNhKGIudmFsdWUpLGQ9U2EoYi5kZWZhdWx0VmFsdWUpO251bGwhPWMmJihjPVwiXCIrYyxjIT09YS52YWx1ZSYmKGEudmFsdWU9YyksbnVsbD09Yi5kZWZhdWx0VmFsdWUmJmEuZGVmYXVsdFZhbHVlIT09YyYmKGEuZGVmYXVsdFZhbHVlPWMpKTtudWxsIT1kJiYoYS5kZWZhdWx0VmFsdWU9XCJcIitkKX1mdW5jdGlvbiBqYihhKXt2YXIgYj1hLnRleHRDb250ZW50O2I9PT1hLl93cmFwcGVyU3RhdGUuaW5pdGlhbFZhbHVlJiZcIlwiIT09YiYmbnVsbCE9PWImJihhLnZhbHVlPWIpfWZ1bmN0aW9uIGtiKGEpe3N3aXRjaChhKXtjYXNlIFwic3ZnXCI6cmV0dXJuXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiO2Nhc2UgXCJtYXRoXCI6cmV0dXJuXCJodHRwOi8vd3d3LnczLm9yZy8xOTk4L01hdGgvTWF0aE1MXCI7ZGVmYXVsdDpyZXR1cm5cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIn19XG5mdW5jdGlvbiBsYihhLGIpe3JldHVybiBudWxsPT1hfHxcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIj09PWE/a2IoYik6XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPT09YSYmXCJmb3JlaWduT2JqZWN0XCI9PT1iP1wiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiOmF9XG52YXIgbWIsbmI9ZnVuY3Rpb24oYSl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBNU0FwcCYmTVNBcHAuZXhlY1Vuc2FmZUxvY2FsRnVuY3Rpb24/ZnVuY3Rpb24oYixjLGQsZSl7TVNBcHAuZXhlY1Vuc2FmZUxvY2FsRnVuY3Rpb24oZnVuY3Rpb24oKXtyZXR1cm4gYShiLGMsZCxlKX0pfTphfShmdW5jdGlvbihhLGIpe2lmKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiE9PWEubmFtZXNwYWNlVVJJfHxcImlubmVySFRNTFwiaW4gYSlhLmlubmVySFRNTD1iO2Vsc2V7bWI9bWJ8fGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7bWIuaW5uZXJIVE1MPVwiPHN2Zz5cIitiLnZhbHVlT2YoKS50b1N0cmluZygpK1wiPC9zdmc+XCI7Zm9yKGI9bWIuZmlyc3RDaGlsZDthLmZpcnN0Q2hpbGQ7KWEucmVtb3ZlQ2hpbGQoYS5maXJzdENoaWxkKTtmb3IoO2IuZmlyc3RDaGlsZDspYS5hcHBlbmRDaGlsZChiLmZpcnN0Q2hpbGQpfX0pO1xuZnVuY3Rpb24gb2IoYSxiKXtpZihiKXt2YXIgYz1hLmZpcnN0Q2hpbGQ7aWYoYyYmYz09PWEubGFzdENoaWxkJiYzPT09Yy5ub2RlVHlwZSl7Yy5ub2RlVmFsdWU9YjtyZXR1cm59fWEudGV4dENvbnRlbnQ9Yn1cbnZhciBwYj17YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsYXNwZWN0UmF0aW86ITAsYm9yZGVySW1hZ2VPdXRzZXQ6ITAsYm9yZGVySW1hZ2VTbGljZTohMCxib3JkZXJJbWFnZVdpZHRoOiEwLGJveEZsZXg6ITAsYm94RmxleEdyb3VwOiEwLGJveE9yZGluYWxHcm91cDohMCxjb2x1bW5Db3VudDohMCxjb2x1bW5zOiEwLGZsZXg6ITAsZmxleEdyb3c6ITAsZmxleFBvc2l0aXZlOiEwLGZsZXhTaHJpbms6ITAsZmxleE5lZ2F0aXZlOiEwLGZsZXhPcmRlcjohMCxncmlkQXJlYTohMCxncmlkUm93OiEwLGdyaWRSb3dFbmQ6ITAsZ3JpZFJvd1NwYW46ITAsZ3JpZFJvd1N0YXJ0OiEwLGdyaWRDb2x1bW46ITAsZ3JpZENvbHVtbkVuZDohMCxncmlkQ29sdW1uU3BhbjohMCxncmlkQ29sdW1uU3RhcnQ6ITAsZm9udFdlaWdodDohMCxsaW5lQ2xhbXA6ITAsbGluZUhlaWdodDohMCxvcGFjaXR5OiEwLG9yZGVyOiEwLG9ycGhhbnM6ITAsdGFiU2l6ZTohMCx3aWRvd3M6ITAsekluZGV4OiEwLFxuem9vbTohMCxmaWxsT3BhY2l0eTohMCxmbG9vZE9wYWNpdHk6ITAsc3RvcE9wYWNpdHk6ITAsc3Ryb2tlRGFzaGFycmF5OiEwLHN0cm9rZURhc2hvZmZzZXQ6ITAsc3Ryb2tlTWl0ZXJsaW1pdDohMCxzdHJva2VPcGFjaXR5OiEwLHN0cm9rZVdpZHRoOiEwfSxxYj1bXCJXZWJraXRcIixcIm1zXCIsXCJNb3pcIixcIk9cIl07T2JqZWN0LmtleXMocGIpLmZvckVhY2goZnVuY3Rpb24oYSl7cWIuZm9yRWFjaChmdW5jdGlvbihiKXtiPWIrYS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSthLnN1YnN0cmluZygxKTtwYltiXT1wYlthXX0pfSk7ZnVuY3Rpb24gcmIoYSxiLGMpe3JldHVybiBudWxsPT1ifHxcImJvb2xlYW5cIj09PXR5cGVvZiBifHxcIlwiPT09Yj9cIlwiOmN8fFwibnVtYmVyXCIhPT10eXBlb2YgYnx8MD09PWJ8fHBiLmhhc093blByb3BlcnR5KGEpJiZwYlthXT8oXCJcIitiKS50cmltKCk6YitcInB4XCJ9XG5mdW5jdGlvbiBzYihhLGIpe2E9YS5zdHlsZTtmb3IodmFyIGMgaW4gYilpZihiLmhhc093blByb3BlcnR5KGMpKXt2YXIgZD0wPT09Yy5pbmRleE9mKFwiLS1cIiksZT1yYihjLGJbY10sZCk7XCJmbG9hdFwiPT09YyYmKGM9XCJjc3NGbG9hdFwiKTtkP2Euc2V0UHJvcGVydHkoYyxlKTphW2NdPWV9fXZhciB0Yj1BKHttZW51aXRlbTohMH0se2FyZWE6ITAsYmFzZTohMCxicjohMCxjb2w6ITAsZW1iZWQ6ITAsaHI6ITAsaW1nOiEwLGlucHV0OiEwLGtleWdlbjohMCxsaW5rOiEwLG1ldGE6ITAscGFyYW06ITAsc291cmNlOiEwLHRyYWNrOiEwLHdicjohMH0pO1xuZnVuY3Rpb24gdWIoYSxiKXtpZihiKXtpZih0YlthXSYmKG51bGwhPWIuY2hpbGRyZW58fG51bGwhPWIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwpKXRocm93IEVycm9yKHAoMTM3LGEpKTtpZihudWxsIT1iLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MKXtpZihudWxsIT1iLmNoaWxkcmVuKXRocm93IEVycm9yKHAoNjApKTtpZihcIm9iamVjdFwiIT09dHlwZW9mIGIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUx8fCEoXCJfX2h0bWxcImluIGIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwpKXRocm93IEVycm9yKHAoNjEpKTt9aWYobnVsbCE9Yi5zdHlsZSYmXCJvYmplY3RcIiE9PXR5cGVvZiBiLnN0eWxlKXRocm93IEVycm9yKHAoNjIpKTt9fVxuZnVuY3Rpb24gdmIoYSxiKXtpZigtMT09PWEuaW5kZXhPZihcIi1cIikpcmV0dXJuXCJzdHJpbmdcIj09PXR5cGVvZiBiLmlzO3N3aXRjaChhKXtjYXNlIFwiYW5ub3RhdGlvbi14bWxcIjpjYXNlIFwiY29sb3ItcHJvZmlsZVwiOmNhc2UgXCJmb250LWZhY2VcIjpjYXNlIFwiZm9udC1mYWNlLXNyY1wiOmNhc2UgXCJmb250LWZhY2UtdXJpXCI6Y2FzZSBcImZvbnQtZmFjZS1mb3JtYXRcIjpjYXNlIFwiZm9udC1mYWNlLW5hbWVcIjpjYXNlIFwibWlzc2luZy1nbHlwaFwiOnJldHVybiExO2RlZmF1bHQ6cmV0dXJuITB9fXZhciB3Yj1udWxsO2Z1bmN0aW9uIHhiKGEpe2E9YS50YXJnZXR8fGEuc3JjRWxlbWVudHx8d2luZG93O2EuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQmJihhPWEuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQpO3JldHVybiAzPT09YS5ub2RlVHlwZT9hLnBhcmVudE5vZGU6YX12YXIgeWI9bnVsbCx6Yj1udWxsLEFiPW51bGw7XG5mdW5jdGlvbiBCYihhKXtpZihhPUNiKGEpKXtpZihcImZ1bmN0aW9uXCIhPT10eXBlb2YgeWIpdGhyb3cgRXJyb3IocCgyODApKTt2YXIgYj1hLnN0YXRlTm9kZTtiJiYoYj1EYihiKSx5YihhLnN0YXRlTm9kZSxhLnR5cGUsYikpfX1mdW5jdGlvbiBFYihhKXt6Yj9BYj9BYi5wdXNoKGEpOkFiPVthXTp6Yj1hfWZ1bmN0aW9uIEZiKCl7aWYoemIpe3ZhciBhPXpiLGI9QWI7QWI9emI9bnVsbDtCYihhKTtpZihiKWZvcihhPTA7YTxiLmxlbmd0aDthKyspQmIoYlthXSl9fWZ1bmN0aW9uIEdiKGEsYil7cmV0dXJuIGEoYil9ZnVuY3Rpb24gSGIoKXt9dmFyIEliPSExO2Z1bmN0aW9uIEpiKGEsYixjKXtpZihJYilyZXR1cm4gYShiLGMpO0liPSEwO3RyeXtyZXR1cm4gR2IoYSxiLGMpfWZpbmFsbHl7aWYoSWI9ITEsbnVsbCE9PXpifHxudWxsIT09QWIpSGIoKSxGYigpfX1cbmZ1bmN0aW9uIEtiKGEsYil7dmFyIGM9YS5zdGF0ZU5vZGU7aWYobnVsbD09PWMpcmV0dXJuIG51bGw7dmFyIGQ9RGIoYyk7aWYobnVsbD09PWQpcmV0dXJuIG51bGw7Yz1kW2JdO2E6c3dpdGNoKGIpe2Nhc2UgXCJvbkNsaWNrXCI6Y2FzZSBcIm9uQ2xpY2tDYXB0dXJlXCI6Y2FzZSBcIm9uRG91YmxlQ2xpY2tcIjpjYXNlIFwib25Eb3VibGVDbGlja0NhcHR1cmVcIjpjYXNlIFwib25Nb3VzZURvd25cIjpjYXNlIFwib25Nb3VzZURvd25DYXB0dXJlXCI6Y2FzZSBcIm9uTW91c2VNb3ZlXCI6Y2FzZSBcIm9uTW91c2VNb3ZlQ2FwdHVyZVwiOmNhc2UgXCJvbk1vdXNlVXBcIjpjYXNlIFwib25Nb3VzZVVwQ2FwdHVyZVwiOmNhc2UgXCJvbk1vdXNlRW50ZXJcIjooZD0hZC5kaXNhYmxlZCl8fChhPWEudHlwZSxkPSEoXCJidXR0b25cIj09PWF8fFwiaW5wdXRcIj09PWF8fFwic2VsZWN0XCI9PT1hfHxcInRleHRhcmVhXCI9PT1hKSk7YT0hZDticmVhayBhO2RlZmF1bHQ6YT0hMX1pZihhKXJldHVybiBudWxsO2lmKGMmJlwiZnVuY3Rpb25cIiE9PVxudHlwZW9mIGMpdGhyb3cgRXJyb3IocCgyMzEsYix0eXBlb2YgYykpO3JldHVybiBjfXZhciBMYj0hMTtpZihpYSl0cnl7dmFyIE1iPXt9O09iamVjdC5kZWZpbmVQcm9wZXJ0eShNYixcInBhc3NpdmVcIix7Z2V0OmZ1bmN0aW9uKCl7TGI9ITB9fSk7d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJ0ZXN0XCIsTWIsTWIpO3dpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwidGVzdFwiLE1iLE1iKX1jYXRjaChhKXtMYj0hMX1mdW5jdGlvbiBOYihhLGIsYyxkLGUsZixnLGgsayl7dmFyIGw9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDMpO3RyeXtiLmFwcGx5KGMsbCl9Y2F0Y2gobSl7dGhpcy5vbkVycm9yKG0pfX12YXIgT2I9ITEsUGI9bnVsbCxRYj0hMSxSYj1udWxsLFNiPXtvbkVycm9yOmZ1bmN0aW9uKGEpe09iPSEwO1BiPWF9fTtmdW5jdGlvbiBUYihhLGIsYyxkLGUsZixnLGgsayl7T2I9ITE7UGI9bnVsbDtOYi5hcHBseShTYixhcmd1bWVudHMpfVxuZnVuY3Rpb24gVWIoYSxiLGMsZCxlLGYsZyxoLGspe1RiLmFwcGx5KHRoaXMsYXJndW1lbnRzKTtpZihPYil7aWYoT2Ipe3ZhciBsPVBiO09iPSExO1BiPW51bGx9ZWxzZSB0aHJvdyBFcnJvcihwKDE5OCkpO1FifHwoUWI9ITAsUmI9bCl9fWZ1bmN0aW9uIFZiKGEpe3ZhciBiPWEsYz1hO2lmKGEuYWx0ZXJuYXRlKWZvcig7Yi5yZXR1cm47KWI9Yi5yZXR1cm47ZWxzZXthPWI7ZG8gYj1hLDAhPT0oYi5mbGFncyY0MDk4KSYmKGM9Yi5yZXR1cm4pLGE9Yi5yZXR1cm47d2hpbGUoYSl9cmV0dXJuIDM9PT1iLnRhZz9jOm51bGx9ZnVuY3Rpb24gV2IoYSl7aWYoMTM9PT1hLnRhZyl7dmFyIGI9YS5tZW1vaXplZFN0YXRlO251bGw9PT1iJiYoYT1hLmFsdGVybmF0ZSxudWxsIT09YSYmKGI9YS5tZW1vaXplZFN0YXRlKSk7aWYobnVsbCE9PWIpcmV0dXJuIGIuZGVoeWRyYXRlZH1yZXR1cm4gbnVsbH1mdW5jdGlvbiBYYihhKXtpZihWYihhKSE9PWEpdGhyb3cgRXJyb3IocCgxODgpKTt9XG5mdW5jdGlvbiBZYihhKXt2YXIgYj1hLmFsdGVybmF0ZTtpZighYil7Yj1WYihhKTtpZihudWxsPT09Yil0aHJvdyBFcnJvcihwKDE4OCkpO3JldHVybiBiIT09YT9udWxsOmF9Zm9yKHZhciBjPWEsZD1iOzspe3ZhciBlPWMucmV0dXJuO2lmKG51bGw9PT1lKWJyZWFrO3ZhciBmPWUuYWx0ZXJuYXRlO2lmKG51bGw9PT1mKXtkPWUucmV0dXJuO2lmKG51bGwhPT1kKXtjPWQ7Y29udGludWV9YnJlYWt9aWYoZS5jaGlsZD09PWYuY2hpbGQpe2ZvcihmPWUuY2hpbGQ7Zjspe2lmKGY9PT1jKXJldHVybiBYYihlKSxhO2lmKGY9PT1kKXJldHVybiBYYihlKSxiO2Y9Zi5zaWJsaW5nfXRocm93IEVycm9yKHAoMTg4KSk7fWlmKGMucmV0dXJuIT09ZC5yZXR1cm4pYz1lLGQ9ZjtlbHNle2Zvcih2YXIgZz0hMSxoPWUuY2hpbGQ7aDspe2lmKGg9PT1jKXtnPSEwO2M9ZTtkPWY7YnJlYWt9aWYoaD09PWQpe2c9ITA7ZD1lO2M9ZjticmVha31oPWguc2libGluZ31pZighZyl7Zm9yKGg9Zi5jaGlsZDtoOyl7aWYoaD09PVxuYyl7Zz0hMDtjPWY7ZD1lO2JyZWFrfWlmKGg9PT1kKXtnPSEwO2Q9ZjtjPWU7YnJlYWt9aD1oLnNpYmxpbmd9aWYoIWcpdGhyb3cgRXJyb3IocCgxODkpKTt9fWlmKGMuYWx0ZXJuYXRlIT09ZCl0aHJvdyBFcnJvcihwKDE5MCkpO31pZigzIT09Yy50YWcpdGhyb3cgRXJyb3IocCgxODgpKTtyZXR1cm4gYy5zdGF0ZU5vZGUuY3VycmVudD09PWM/YTpifWZ1bmN0aW9uIFpiKGEpe2E9WWIoYSk7cmV0dXJuIG51bGwhPT1hPyRiKGEpOm51bGx9ZnVuY3Rpb24gJGIoYSl7aWYoNT09PWEudGFnfHw2PT09YS50YWcpcmV0dXJuIGE7Zm9yKGE9YS5jaGlsZDtudWxsIT09YTspe3ZhciBiPSRiKGEpO2lmKG51bGwhPT1iKXJldHVybiBiO2E9YS5zaWJsaW5nfXJldHVybiBudWxsfVxudmFyIGFjPWNhLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2ssYmM9Y2EudW5zdGFibGVfY2FuY2VsQ2FsbGJhY2ssY2M9Y2EudW5zdGFibGVfc2hvdWxkWWllbGQsZGM9Y2EudW5zdGFibGVfcmVxdWVzdFBhaW50LEI9Y2EudW5zdGFibGVfbm93LGVjPWNhLnVuc3RhYmxlX2dldEN1cnJlbnRQcmlvcml0eUxldmVsLGZjPWNhLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5LGdjPWNhLnVuc3RhYmxlX1VzZXJCbG9ja2luZ1ByaW9yaXR5LGhjPWNhLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5LGljPWNhLnVuc3RhYmxlX0xvd1ByaW9yaXR5LGpjPWNhLnVuc3RhYmxlX0lkbGVQcmlvcml0eSxrYz1udWxsLGxjPW51bGw7ZnVuY3Rpb24gbWMoYSl7aWYobGMmJlwiZnVuY3Rpb25cIj09PXR5cGVvZiBsYy5vbkNvbW1pdEZpYmVyUm9vdCl0cnl7bGMub25Db21taXRGaWJlclJvb3Qoa2MsYSx2b2lkIDAsMTI4PT09KGEuY3VycmVudC5mbGFncyYxMjgpKX1jYXRjaChiKXt9fVxudmFyIG9jPU1hdGguY2x6MzI/TWF0aC5jbHozMjpuYyxwYz1NYXRoLmxvZyxxYz1NYXRoLkxOMjtmdW5jdGlvbiBuYyhhKXthPj4+PTA7cmV0dXJuIDA9PT1hPzMyOjMxLShwYyhhKS9xY3wwKXwwfXZhciByYz02NCxzYz00MTk0MzA0O1xuZnVuY3Rpb24gdGMoYSl7c3dpdGNoKGEmLWEpe2Nhc2UgMTpyZXR1cm4gMTtjYXNlIDI6cmV0dXJuIDI7Y2FzZSA0OnJldHVybiA0O2Nhc2UgODpyZXR1cm4gODtjYXNlIDE2OnJldHVybiAxNjtjYXNlIDMyOnJldHVybiAzMjtjYXNlIDY0OmNhc2UgMTI4OmNhc2UgMjU2OmNhc2UgNTEyOmNhc2UgMTAyNDpjYXNlIDIwNDg6Y2FzZSA0MDk2OmNhc2UgODE5MjpjYXNlIDE2Mzg0OmNhc2UgMzI3Njg6Y2FzZSA2NTUzNjpjYXNlIDEzMTA3MjpjYXNlIDI2MjE0NDpjYXNlIDUyNDI4ODpjYXNlIDEwNDg1NzY6Y2FzZSAyMDk3MTUyOnJldHVybiBhJjQxOTQyNDA7Y2FzZSA0MTk0MzA0OmNhc2UgODM4ODYwODpjYXNlIDE2Nzc3MjE2OmNhc2UgMzM1NTQ0MzI6Y2FzZSA2NzEwODg2NDpyZXR1cm4gYSYxMzAwMjM0MjQ7Y2FzZSAxMzQyMTc3Mjg6cmV0dXJuIDEzNDIxNzcyODtjYXNlIDI2ODQzNTQ1NjpyZXR1cm4gMjY4NDM1NDU2O2Nhc2UgNTM2ODcwOTEyOnJldHVybiA1MzY4NzA5MTI7Y2FzZSAxMDczNzQxODI0OnJldHVybiAxMDczNzQxODI0O1xuZGVmYXVsdDpyZXR1cm4gYX19ZnVuY3Rpb24gdWMoYSxiKXt2YXIgYz1hLnBlbmRpbmdMYW5lcztpZigwPT09YylyZXR1cm4gMDt2YXIgZD0wLGU9YS5zdXNwZW5kZWRMYW5lcyxmPWEucGluZ2VkTGFuZXMsZz1jJjI2ODQzNTQ1NTtpZigwIT09Zyl7dmFyIGg9ZyZ+ZTswIT09aD9kPXRjKGgpOihmJj1nLDAhPT1mJiYoZD10YyhmKSkpfWVsc2UgZz1jJn5lLDAhPT1nP2Q9dGMoZyk6MCE9PWYmJihkPXRjKGYpKTtpZigwPT09ZClyZXR1cm4gMDtpZigwIT09YiYmYiE9PWQmJjA9PT0oYiZlKSYmKGU9ZCYtZCxmPWImLWIsZT49Znx8MTY9PT1lJiYwIT09KGYmNDE5NDI0MCkpKXJldHVybiBiOzAhPT0oZCY0KSYmKGR8PWMmMTYpO2I9YS5lbnRhbmdsZWRMYW5lcztpZigwIT09Yilmb3IoYT1hLmVudGFuZ2xlbWVudHMsYiY9ZDswPGI7KWM9MzEtb2MoYiksZT0xPDxjLGR8PWFbY10sYiY9fmU7cmV0dXJuIGR9XG5mdW5jdGlvbiB2YyhhLGIpe3N3aXRjaChhKXtjYXNlIDE6Y2FzZSAyOmNhc2UgNDpyZXR1cm4gYisyNTA7Y2FzZSA4OmNhc2UgMTY6Y2FzZSAzMjpjYXNlIDY0OmNhc2UgMTI4OmNhc2UgMjU2OmNhc2UgNTEyOmNhc2UgMTAyNDpjYXNlIDIwNDg6Y2FzZSA0MDk2OmNhc2UgODE5MjpjYXNlIDE2Mzg0OmNhc2UgMzI3Njg6Y2FzZSA2NTUzNjpjYXNlIDEzMTA3MjpjYXNlIDI2MjE0NDpjYXNlIDUyNDI4ODpjYXNlIDEwNDg1NzY6Y2FzZSAyMDk3MTUyOnJldHVybiBiKzVFMztjYXNlIDQxOTQzMDQ6Y2FzZSA4Mzg4NjA4OmNhc2UgMTY3NzcyMTY6Y2FzZSAzMzU1NDQzMjpjYXNlIDY3MTA4ODY0OnJldHVybi0xO2Nhc2UgMTM0MjE3NzI4OmNhc2UgMjY4NDM1NDU2OmNhc2UgNTM2ODcwOTEyOmNhc2UgMTA3Mzc0MTgyNDpyZXR1cm4tMTtkZWZhdWx0OnJldHVybi0xfX1cbmZ1bmN0aW9uIHdjKGEsYil7Zm9yKHZhciBjPWEuc3VzcGVuZGVkTGFuZXMsZD1hLnBpbmdlZExhbmVzLGU9YS5leHBpcmF0aW9uVGltZXMsZj1hLnBlbmRpbmdMYW5lczswPGY7KXt2YXIgZz0zMS1vYyhmKSxoPTE8PGcsaz1lW2ddO2lmKC0xPT09ayl7aWYoMD09PShoJmMpfHwwIT09KGgmZCkpZVtnXT12YyhoLGIpfWVsc2Ugazw9YiYmKGEuZXhwaXJlZExhbmVzfD1oKTtmJj1+aH19ZnVuY3Rpb24geGMoYSl7YT1hLnBlbmRpbmdMYW5lcyYtMTA3Mzc0MTgyNTtyZXR1cm4gMCE9PWE/YTphJjEwNzM3NDE4MjQ/MTA3Mzc0MTgyNDowfWZ1bmN0aW9uIHljKCl7dmFyIGE9cmM7cmM8PD0xOzA9PT0ocmMmNDE5NDI0MCkmJihyYz02NCk7cmV0dXJuIGF9ZnVuY3Rpb24gemMoYSl7Zm9yKHZhciBiPVtdLGM9MDszMT5jO2MrKyliLnB1c2goYSk7cmV0dXJuIGJ9XG5mdW5jdGlvbiBBYyhhLGIsYyl7YS5wZW5kaW5nTGFuZXN8PWI7NTM2ODcwOTEyIT09YiYmKGEuc3VzcGVuZGVkTGFuZXM9MCxhLnBpbmdlZExhbmVzPTApO2E9YS5ldmVudFRpbWVzO2I9MzEtb2MoYik7YVtiXT1jfWZ1bmN0aW9uIEJjKGEsYil7dmFyIGM9YS5wZW5kaW5nTGFuZXMmfmI7YS5wZW5kaW5nTGFuZXM9YjthLnN1c3BlbmRlZExhbmVzPTA7YS5waW5nZWRMYW5lcz0wO2EuZXhwaXJlZExhbmVzJj1iO2EubXV0YWJsZVJlYWRMYW5lcyY9YjthLmVudGFuZ2xlZExhbmVzJj1iO2I9YS5lbnRhbmdsZW1lbnRzO3ZhciBkPWEuZXZlbnRUaW1lcztmb3IoYT1hLmV4cGlyYXRpb25UaW1lczswPGM7KXt2YXIgZT0zMS1vYyhjKSxmPTE8PGU7YltlXT0wO2RbZV09LTE7YVtlXT0tMTtjJj1+Zn19XG5mdW5jdGlvbiBDYyhhLGIpe3ZhciBjPWEuZW50YW5nbGVkTGFuZXN8PWI7Zm9yKGE9YS5lbnRhbmdsZW1lbnRzO2M7KXt2YXIgZD0zMS1vYyhjKSxlPTE8PGQ7ZSZifGFbZF0mYiYmKGFbZF18PWIpO2MmPX5lfX12YXIgQz0wO2Z1bmN0aW9uIERjKGEpe2EmPS1hO3JldHVybiAxPGE/NDxhPzAhPT0oYSYyNjg0MzU0NTUpPzE2OjUzNjg3MDkxMjo0OjF9dmFyIEVjLEZjLEdjLEhjLEljLEpjPSExLEtjPVtdLExjPW51bGwsTWM9bnVsbCxOYz1udWxsLE9jPW5ldyBNYXAsUGM9bmV3IE1hcCxRYz1bXSxSYz1cIm1vdXNlZG93biBtb3VzZXVwIHRvdWNoY2FuY2VsIHRvdWNoZW5kIHRvdWNoc3RhcnQgYXV4Y2xpY2sgZGJsY2xpY2sgcG9pbnRlcmNhbmNlbCBwb2ludGVyZG93biBwb2ludGVydXAgZHJhZ2VuZCBkcmFnc3RhcnQgZHJvcCBjb21wb3NpdGlvbmVuZCBjb21wb3NpdGlvbnN0YXJ0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgaW5wdXQgdGV4dElucHV0IGNvcHkgY3V0IHBhc3RlIGNsaWNrIGNoYW5nZSBjb250ZXh0bWVudSByZXNldCBzdWJtaXRcIi5zcGxpdChcIiBcIik7XG5mdW5jdGlvbiBTYyhhLGIpe3N3aXRjaChhKXtjYXNlIFwiZm9jdXNpblwiOmNhc2UgXCJmb2N1c291dFwiOkxjPW51bGw7YnJlYWs7Y2FzZSBcImRyYWdlbnRlclwiOmNhc2UgXCJkcmFnbGVhdmVcIjpNYz1udWxsO2JyZWFrO2Nhc2UgXCJtb3VzZW92ZXJcIjpjYXNlIFwibW91c2VvdXRcIjpOYz1udWxsO2JyZWFrO2Nhc2UgXCJwb2ludGVyb3ZlclwiOmNhc2UgXCJwb2ludGVyb3V0XCI6T2MuZGVsZXRlKGIucG9pbnRlcklkKTticmVhaztjYXNlIFwiZ290cG9pbnRlcmNhcHR1cmVcIjpjYXNlIFwibG9zdHBvaW50ZXJjYXB0dXJlXCI6UGMuZGVsZXRlKGIucG9pbnRlcklkKX19XG5mdW5jdGlvbiBUYyhhLGIsYyxkLGUsZil7aWYobnVsbD09PWF8fGEubmF0aXZlRXZlbnQhPT1mKXJldHVybiBhPXtibG9ja2VkT246Yixkb21FdmVudE5hbWU6YyxldmVudFN5c3RlbUZsYWdzOmQsbmF0aXZlRXZlbnQ6Zix0YXJnZXRDb250YWluZXJzOltlXX0sbnVsbCE9PWImJihiPUNiKGIpLG51bGwhPT1iJiZGYyhiKSksYTthLmV2ZW50U3lzdGVtRmxhZ3N8PWQ7Yj1hLnRhcmdldENvbnRhaW5lcnM7bnVsbCE9PWUmJi0xPT09Yi5pbmRleE9mKGUpJiZiLnB1c2goZSk7cmV0dXJuIGF9XG5mdW5jdGlvbiBVYyhhLGIsYyxkLGUpe3N3aXRjaChiKXtjYXNlIFwiZm9jdXNpblwiOnJldHVybiBMYz1UYyhMYyxhLGIsYyxkLGUpLCEwO2Nhc2UgXCJkcmFnZW50ZXJcIjpyZXR1cm4gTWM9VGMoTWMsYSxiLGMsZCxlKSwhMDtjYXNlIFwibW91c2VvdmVyXCI6cmV0dXJuIE5jPVRjKE5jLGEsYixjLGQsZSksITA7Y2FzZSBcInBvaW50ZXJvdmVyXCI6dmFyIGY9ZS5wb2ludGVySWQ7T2Muc2V0KGYsVGMoT2MuZ2V0KGYpfHxudWxsLGEsYixjLGQsZSkpO3JldHVybiEwO2Nhc2UgXCJnb3Rwb2ludGVyY2FwdHVyZVwiOnJldHVybiBmPWUucG9pbnRlcklkLFBjLnNldChmLFRjKFBjLmdldChmKXx8bnVsbCxhLGIsYyxkLGUpKSwhMH1yZXR1cm4hMX1cbmZ1bmN0aW9uIFZjKGEpe3ZhciBiPVdjKGEudGFyZ2V0KTtpZihudWxsIT09Yil7dmFyIGM9VmIoYik7aWYobnVsbCE9PWMpaWYoYj1jLnRhZywxMz09PWIpe2lmKGI9V2IoYyksbnVsbCE9PWIpe2EuYmxvY2tlZE9uPWI7SWMoYS5wcmlvcml0eSxmdW5jdGlvbigpe0djKGMpfSk7cmV0dXJufX1lbHNlIGlmKDM9PT1iJiZjLnN0YXRlTm9kZS5jdXJyZW50Lm1lbW9pemVkU3RhdGUuaXNEZWh5ZHJhdGVkKXthLmJsb2NrZWRPbj0zPT09Yy50YWc/Yy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbzpudWxsO3JldHVybn19YS5ibG9ja2VkT249bnVsbH1cbmZ1bmN0aW9uIFhjKGEpe2lmKG51bGwhPT1hLmJsb2NrZWRPbilyZXR1cm4hMTtmb3IodmFyIGI9YS50YXJnZXRDb250YWluZXJzOzA8Yi5sZW5ndGg7KXt2YXIgYz1ZYyhhLmRvbUV2ZW50TmFtZSxhLmV2ZW50U3lzdGVtRmxhZ3MsYlswXSxhLm5hdGl2ZUV2ZW50KTtpZihudWxsPT09Yyl7Yz1hLm5hdGl2ZUV2ZW50O3ZhciBkPW5ldyBjLmNvbnN0cnVjdG9yKGMudHlwZSxjKTt3Yj1kO2MudGFyZ2V0LmRpc3BhdGNoRXZlbnQoZCk7d2I9bnVsbH1lbHNlIHJldHVybiBiPUNiKGMpLG51bGwhPT1iJiZGYyhiKSxhLmJsb2NrZWRPbj1jLCExO2Iuc2hpZnQoKX1yZXR1cm4hMH1mdW5jdGlvbiBaYyhhLGIsYyl7WGMoYSkmJmMuZGVsZXRlKGIpfWZ1bmN0aW9uICRjKCl7SmM9ITE7bnVsbCE9PUxjJiZYYyhMYykmJihMYz1udWxsKTtudWxsIT09TWMmJlhjKE1jKSYmKE1jPW51bGwpO251bGwhPT1OYyYmWGMoTmMpJiYoTmM9bnVsbCk7T2MuZm9yRWFjaChaYyk7UGMuZm9yRWFjaChaYyl9XG5mdW5jdGlvbiBhZChhLGIpe2EuYmxvY2tlZE9uPT09YiYmKGEuYmxvY2tlZE9uPW51bGwsSmN8fChKYz0hMCxjYS51bnN0YWJsZV9zY2hlZHVsZUNhbGxiYWNrKGNhLnVuc3RhYmxlX05vcm1hbFByaW9yaXR5LCRjKSkpfVxuZnVuY3Rpb24gYmQoYSl7ZnVuY3Rpb24gYihiKXtyZXR1cm4gYWQoYixhKX1pZigwPEtjLmxlbmd0aCl7YWQoS2NbMF0sYSk7Zm9yKHZhciBjPTE7YzxLYy5sZW5ndGg7YysrKXt2YXIgZD1LY1tjXTtkLmJsb2NrZWRPbj09PWEmJihkLmJsb2NrZWRPbj1udWxsKX19bnVsbCE9PUxjJiZhZChMYyxhKTtudWxsIT09TWMmJmFkKE1jLGEpO251bGwhPT1OYyYmYWQoTmMsYSk7T2MuZm9yRWFjaChiKTtQYy5mb3JFYWNoKGIpO2ZvcihjPTA7YzxRYy5sZW5ndGg7YysrKWQ9UWNbY10sZC5ibG9ja2VkT249PT1hJiYoZC5ibG9ja2VkT249bnVsbCk7Zm9yKDswPFFjLmxlbmd0aCYmKGM9UWNbMF0sbnVsbD09PWMuYmxvY2tlZE9uKTspVmMoYyksbnVsbD09PWMuYmxvY2tlZE9uJiZRYy5zaGlmdCgpfXZhciBjZD11YS5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZyxkZD0hMDtcbmZ1bmN0aW9uIGVkKGEsYixjLGQpe3ZhciBlPUMsZj1jZC50cmFuc2l0aW9uO2NkLnRyYW5zaXRpb249bnVsbDt0cnl7Qz0xLGZkKGEsYixjLGQpfWZpbmFsbHl7Qz1lLGNkLnRyYW5zaXRpb249Zn19ZnVuY3Rpb24gZ2QoYSxiLGMsZCl7dmFyIGU9QyxmPWNkLnRyYW5zaXRpb247Y2QudHJhbnNpdGlvbj1udWxsO3RyeXtDPTQsZmQoYSxiLGMsZCl9ZmluYWxseXtDPWUsY2QudHJhbnNpdGlvbj1mfX1cbmZ1bmN0aW9uIGZkKGEsYixjLGQpe2lmKGRkKXt2YXIgZT1ZYyhhLGIsYyxkKTtpZihudWxsPT09ZSloZChhLGIsZCxpZCxjKSxTYyhhLGQpO2Vsc2UgaWYoVWMoZSxhLGIsYyxkKSlkLnN0b3BQcm9wYWdhdGlvbigpO2Vsc2UgaWYoU2MoYSxkKSxiJjQmJi0xPFJjLmluZGV4T2YoYSkpe2Zvcig7bnVsbCE9PWU7KXt2YXIgZj1DYihlKTtudWxsIT09ZiYmRWMoZik7Zj1ZYyhhLGIsYyxkKTtudWxsPT09ZiYmaGQoYSxiLGQsaWQsYyk7aWYoZj09PWUpYnJlYWs7ZT1mfW51bGwhPT1lJiZkLnN0b3BQcm9wYWdhdGlvbigpfWVsc2UgaGQoYSxiLGQsbnVsbCxjKX19dmFyIGlkPW51bGw7XG5mdW5jdGlvbiBZYyhhLGIsYyxkKXtpZD1udWxsO2E9eGIoZCk7YT1XYyhhKTtpZihudWxsIT09YSlpZihiPVZiKGEpLG51bGw9PT1iKWE9bnVsbDtlbHNlIGlmKGM9Yi50YWcsMTM9PT1jKXthPVdiKGIpO2lmKG51bGwhPT1hKXJldHVybiBhO2E9bnVsbH1lbHNlIGlmKDM9PT1jKXtpZihiLnN0YXRlTm9kZS5jdXJyZW50Lm1lbW9pemVkU3RhdGUuaXNEZWh5ZHJhdGVkKXJldHVybiAzPT09Yi50YWc/Yi5zdGF0ZU5vZGUuY29udGFpbmVySW5mbzpudWxsO2E9bnVsbH1lbHNlIGIhPT1hJiYoYT1udWxsKTtpZD1hO3JldHVybiBudWxsfVxuZnVuY3Rpb24gamQoYSl7c3dpdGNoKGEpe2Nhc2UgXCJjYW5jZWxcIjpjYXNlIFwiY2xpY2tcIjpjYXNlIFwiY2xvc2VcIjpjYXNlIFwiY29udGV4dG1lbnVcIjpjYXNlIFwiY29weVwiOmNhc2UgXCJjdXRcIjpjYXNlIFwiYXV4Y2xpY2tcIjpjYXNlIFwiZGJsY2xpY2tcIjpjYXNlIFwiZHJhZ2VuZFwiOmNhc2UgXCJkcmFnc3RhcnRcIjpjYXNlIFwiZHJvcFwiOmNhc2UgXCJmb2N1c2luXCI6Y2FzZSBcImZvY3Vzb3V0XCI6Y2FzZSBcImlucHV0XCI6Y2FzZSBcImludmFsaWRcIjpjYXNlIFwia2V5ZG93blwiOmNhc2UgXCJrZXlwcmVzc1wiOmNhc2UgXCJrZXl1cFwiOmNhc2UgXCJtb3VzZWRvd25cIjpjYXNlIFwibW91c2V1cFwiOmNhc2UgXCJwYXN0ZVwiOmNhc2UgXCJwYXVzZVwiOmNhc2UgXCJwbGF5XCI6Y2FzZSBcInBvaW50ZXJjYW5jZWxcIjpjYXNlIFwicG9pbnRlcmRvd25cIjpjYXNlIFwicG9pbnRlcnVwXCI6Y2FzZSBcInJhdGVjaGFuZ2VcIjpjYXNlIFwicmVzZXRcIjpjYXNlIFwicmVzaXplXCI6Y2FzZSBcInNlZWtlZFwiOmNhc2UgXCJzdWJtaXRcIjpjYXNlIFwidG91Y2hjYW5jZWxcIjpjYXNlIFwidG91Y2hlbmRcIjpjYXNlIFwidG91Y2hzdGFydFwiOmNhc2UgXCJ2b2x1bWVjaGFuZ2VcIjpjYXNlIFwiY2hhbmdlXCI6Y2FzZSBcInNlbGVjdGlvbmNoYW5nZVwiOmNhc2UgXCJ0ZXh0SW5wdXRcIjpjYXNlIFwiY29tcG9zaXRpb25zdGFydFwiOmNhc2UgXCJjb21wb3NpdGlvbmVuZFwiOmNhc2UgXCJjb21wb3NpdGlvbnVwZGF0ZVwiOmNhc2UgXCJiZWZvcmVibHVyXCI6Y2FzZSBcImFmdGVyYmx1clwiOmNhc2UgXCJiZWZvcmVpbnB1dFwiOmNhc2UgXCJibHVyXCI6Y2FzZSBcImZ1bGxzY3JlZW5jaGFuZ2VcIjpjYXNlIFwiZm9jdXNcIjpjYXNlIFwiaGFzaGNoYW5nZVwiOmNhc2UgXCJwb3BzdGF0ZVwiOmNhc2UgXCJzZWxlY3RcIjpjYXNlIFwic2VsZWN0c3RhcnRcIjpyZXR1cm4gMTtjYXNlIFwiZHJhZ1wiOmNhc2UgXCJkcmFnZW50ZXJcIjpjYXNlIFwiZHJhZ2V4aXRcIjpjYXNlIFwiZHJhZ2xlYXZlXCI6Y2FzZSBcImRyYWdvdmVyXCI6Y2FzZSBcIm1vdXNlbW92ZVwiOmNhc2UgXCJtb3VzZW91dFwiOmNhc2UgXCJtb3VzZW92ZXJcIjpjYXNlIFwicG9pbnRlcm1vdmVcIjpjYXNlIFwicG9pbnRlcm91dFwiOmNhc2UgXCJwb2ludGVyb3ZlclwiOmNhc2UgXCJzY3JvbGxcIjpjYXNlIFwidG9nZ2xlXCI6Y2FzZSBcInRvdWNobW92ZVwiOmNhc2UgXCJ3aGVlbFwiOmNhc2UgXCJtb3VzZWVudGVyXCI6Y2FzZSBcIm1vdXNlbGVhdmVcIjpjYXNlIFwicG9pbnRlcmVudGVyXCI6Y2FzZSBcInBvaW50ZXJsZWF2ZVwiOnJldHVybiA0O1xuY2FzZSBcIm1lc3NhZ2VcIjpzd2l0Y2goZWMoKSl7Y2FzZSBmYzpyZXR1cm4gMTtjYXNlIGdjOnJldHVybiA0O2Nhc2UgaGM6Y2FzZSBpYzpyZXR1cm4gMTY7Y2FzZSBqYzpyZXR1cm4gNTM2ODcwOTEyO2RlZmF1bHQ6cmV0dXJuIDE2fWRlZmF1bHQ6cmV0dXJuIDE2fX12YXIga2Q9bnVsbCxsZD1udWxsLG1kPW51bGw7ZnVuY3Rpb24gbmQoKXtpZihtZClyZXR1cm4gbWQ7dmFyIGEsYj1sZCxjPWIubGVuZ3RoLGQsZT1cInZhbHVlXCJpbiBrZD9rZC52YWx1ZTprZC50ZXh0Q29udGVudCxmPWUubGVuZ3RoO2ZvcihhPTA7YTxjJiZiW2FdPT09ZVthXTthKyspO3ZhciBnPWMtYTtmb3IoZD0xO2Q8PWcmJmJbYy1kXT09PWVbZi1kXTtkKyspO3JldHVybiBtZD1lLnNsaWNlKGEsMTxkPzEtZDp2b2lkIDApfVxuZnVuY3Rpb24gb2QoYSl7dmFyIGI9YS5rZXlDb2RlO1wiY2hhckNvZGVcImluIGE/KGE9YS5jaGFyQ29kZSwwPT09YSYmMTM9PT1iJiYoYT0xMykpOmE9YjsxMD09PWEmJihhPTEzKTtyZXR1cm4gMzI8PWF8fDEzPT09YT9hOjB9ZnVuY3Rpb24gcGQoKXtyZXR1cm4hMH1mdW5jdGlvbiBxZCgpe3JldHVybiExfVxuZnVuY3Rpb24gcmQoYSl7ZnVuY3Rpb24gYihiLGQsZSxmLGcpe3RoaXMuX3JlYWN0TmFtZT1iO3RoaXMuX3RhcmdldEluc3Q9ZTt0aGlzLnR5cGU9ZDt0aGlzLm5hdGl2ZUV2ZW50PWY7dGhpcy50YXJnZXQ9Zzt0aGlzLmN1cnJlbnRUYXJnZXQ9bnVsbDtmb3IodmFyIGMgaW4gYSlhLmhhc093blByb3BlcnR5KGMpJiYoYj1hW2NdLHRoaXNbY109Yj9iKGYpOmZbY10pO3RoaXMuaXNEZWZhdWx0UHJldmVudGVkPShudWxsIT1mLmRlZmF1bHRQcmV2ZW50ZWQ/Zi5kZWZhdWx0UHJldmVudGVkOiExPT09Zi5yZXR1cm5WYWx1ZSk/cGQ6cWQ7dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1xZDtyZXR1cm4gdGhpc31BKGIucHJvdG90eXBlLHtwcmV2ZW50RGVmYXVsdDpmdW5jdGlvbigpe3RoaXMuZGVmYXVsdFByZXZlbnRlZD0hMDt2YXIgYT10aGlzLm5hdGl2ZUV2ZW50O2EmJihhLnByZXZlbnREZWZhdWx0P2EucHJldmVudERlZmF1bHQoKTpcInVua25vd25cIiE9PXR5cGVvZiBhLnJldHVyblZhbHVlJiZcbihhLnJldHVyblZhbHVlPSExKSx0aGlzLmlzRGVmYXVsdFByZXZlbnRlZD1wZCl9LHN0b3BQcm9wYWdhdGlvbjpmdW5jdGlvbigpe3ZhciBhPXRoaXMubmF0aXZlRXZlbnQ7YSYmKGEuc3RvcFByb3BhZ2F0aW9uP2Euc3RvcFByb3BhZ2F0aW9uKCk6XCJ1bmtub3duXCIhPT10eXBlb2YgYS5jYW5jZWxCdWJibGUmJihhLmNhbmNlbEJ1YmJsZT0hMCksdGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZD1wZCl9LHBlcnNpc3Q6ZnVuY3Rpb24oKXt9LGlzUGVyc2lzdGVudDpwZH0pO3JldHVybiBifVxudmFyIHNkPXtldmVudFBoYXNlOjAsYnViYmxlczowLGNhbmNlbGFibGU6MCx0aW1lU3RhbXA6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudGltZVN0YW1wfHxEYXRlLm5vdygpfSxkZWZhdWx0UHJldmVudGVkOjAsaXNUcnVzdGVkOjB9LHRkPXJkKHNkKSx1ZD1BKHt9LHNkLHt2aWV3OjAsZGV0YWlsOjB9KSx2ZD1yZCh1ZCksd2QseGQseWQsQWQ9QSh7fSx1ZCx7c2NyZWVuWDowLHNjcmVlblk6MCxjbGllbnRYOjAsY2xpZW50WTowLHBhZ2VYOjAscGFnZVk6MCxjdHJsS2V5OjAsc2hpZnRLZXk6MCxhbHRLZXk6MCxtZXRhS2V5OjAsZ2V0TW9kaWZpZXJTdGF0ZTp6ZCxidXR0b246MCxidXR0b25zOjAscmVsYXRlZFRhcmdldDpmdW5jdGlvbihhKXtyZXR1cm4gdm9pZCAwPT09YS5yZWxhdGVkVGFyZ2V0P2EuZnJvbUVsZW1lbnQ9PT1hLnNyY0VsZW1lbnQ/YS50b0VsZW1lbnQ6YS5mcm9tRWxlbWVudDphLnJlbGF0ZWRUYXJnZXR9LG1vdmVtZW50WDpmdW5jdGlvbihhKXtpZihcIm1vdmVtZW50WFwiaW5cbmEpcmV0dXJuIGEubW92ZW1lbnRYO2EhPT15ZCYmKHlkJiZcIm1vdXNlbW92ZVwiPT09YS50eXBlPyh3ZD1hLnNjcmVlblgteWQuc2NyZWVuWCx4ZD1hLnNjcmVlblkteWQuc2NyZWVuWSk6eGQ9d2Q9MCx5ZD1hKTtyZXR1cm4gd2R9LG1vdmVtZW50WTpmdW5jdGlvbihhKXtyZXR1cm5cIm1vdmVtZW50WVwiaW4gYT9hLm1vdmVtZW50WTp4ZH19KSxCZD1yZChBZCksQ2Q9QSh7fSxBZCx7ZGF0YVRyYW5zZmVyOjB9KSxEZD1yZChDZCksRWQ9QSh7fSx1ZCx7cmVsYXRlZFRhcmdldDowfSksRmQ9cmQoRWQpLEdkPUEoe30sc2Qse2FuaW1hdGlvbk5hbWU6MCxlbGFwc2VkVGltZTowLHBzZXVkb0VsZW1lbnQ6MH0pLEhkPXJkKEdkKSxJZD1BKHt9LHNkLHtjbGlwYm9hcmREYXRhOmZ1bmN0aW9uKGEpe3JldHVyblwiY2xpcGJvYXJkRGF0YVwiaW4gYT9hLmNsaXBib2FyZERhdGE6d2luZG93LmNsaXBib2FyZERhdGF9fSksSmQ9cmQoSWQpLEtkPUEoe30sc2Qse2RhdGE6MH0pLExkPXJkKEtkKSxNZD17RXNjOlwiRXNjYXBlXCIsXG5TcGFjZWJhcjpcIiBcIixMZWZ0OlwiQXJyb3dMZWZ0XCIsVXA6XCJBcnJvd1VwXCIsUmlnaHQ6XCJBcnJvd1JpZ2h0XCIsRG93bjpcIkFycm93RG93blwiLERlbDpcIkRlbGV0ZVwiLFdpbjpcIk9TXCIsTWVudTpcIkNvbnRleHRNZW51XCIsQXBwczpcIkNvbnRleHRNZW51XCIsU2Nyb2xsOlwiU2Nyb2xsTG9ja1wiLE1velByaW50YWJsZUtleTpcIlVuaWRlbnRpZmllZFwifSxOZD17ODpcIkJhY2tzcGFjZVwiLDk6XCJUYWJcIiwxMjpcIkNsZWFyXCIsMTM6XCJFbnRlclwiLDE2OlwiU2hpZnRcIiwxNzpcIkNvbnRyb2xcIiwxODpcIkFsdFwiLDE5OlwiUGF1c2VcIiwyMDpcIkNhcHNMb2NrXCIsMjc6XCJFc2NhcGVcIiwzMjpcIiBcIiwzMzpcIlBhZ2VVcFwiLDM0OlwiUGFnZURvd25cIiwzNTpcIkVuZFwiLDM2OlwiSG9tZVwiLDM3OlwiQXJyb3dMZWZ0XCIsMzg6XCJBcnJvd1VwXCIsMzk6XCJBcnJvd1JpZ2h0XCIsNDA6XCJBcnJvd0Rvd25cIiw0NTpcIkluc2VydFwiLDQ2OlwiRGVsZXRlXCIsMTEyOlwiRjFcIiwxMTM6XCJGMlwiLDExNDpcIkYzXCIsMTE1OlwiRjRcIiwxMTY6XCJGNVwiLDExNzpcIkY2XCIsMTE4OlwiRjdcIixcbjExOTpcIkY4XCIsMTIwOlwiRjlcIiwxMjE6XCJGMTBcIiwxMjI6XCJGMTFcIiwxMjM6XCJGMTJcIiwxNDQ6XCJOdW1Mb2NrXCIsMTQ1OlwiU2Nyb2xsTG9ja1wiLDIyNDpcIk1ldGFcIn0sT2Q9e0FsdDpcImFsdEtleVwiLENvbnRyb2w6XCJjdHJsS2V5XCIsTWV0YTpcIm1ldGFLZXlcIixTaGlmdDpcInNoaWZ0S2V5XCJ9O2Z1bmN0aW9uIFBkKGEpe3ZhciBiPXRoaXMubmF0aXZlRXZlbnQ7cmV0dXJuIGIuZ2V0TW9kaWZpZXJTdGF0ZT9iLmdldE1vZGlmaWVyU3RhdGUoYSk6KGE9T2RbYV0pPyEhYlthXTohMX1mdW5jdGlvbiB6ZCgpe3JldHVybiBQZH1cbnZhciBRZD1BKHt9LHVkLHtrZXk6ZnVuY3Rpb24oYSl7aWYoYS5rZXkpe3ZhciBiPU1kW2Eua2V5XXx8YS5rZXk7aWYoXCJVbmlkZW50aWZpZWRcIiE9PWIpcmV0dXJuIGJ9cmV0dXJuXCJrZXlwcmVzc1wiPT09YS50eXBlPyhhPW9kKGEpLDEzPT09YT9cIkVudGVyXCI6U3RyaW5nLmZyb21DaGFyQ29kZShhKSk6XCJrZXlkb3duXCI9PT1hLnR5cGV8fFwia2V5dXBcIj09PWEudHlwZT9OZFthLmtleUNvZGVdfHxcIlVuaWRlbnRpZmllZFwiOlwiXCJ9LGNvZGU6MCxsb2NhdGlvbjowLGN0cmxLZXk6MCxzaGlmdEtleTowLGFsdEtleTowLG1ldGFLZXk6MCxyZXBlYXQ6MCxsb2NhbGU6MCxnZXRNb2RpZmllclN0YXRlOnpkLGNoYXJDb2RlOmZ1bmN0aW9uKGEpe3JldHVyblwia2V5cHJlc3NcIj09PWEudHlwZT9vZChhKTowfSxrZXlDb2RlOmZ1bmN0aW9uKGEpe3JldHVyblwia2V5ZG93blwiPT09YS50eXBlfHxcImtleXVwXCI9PT1hLnR5cGU/YS5rZXlDb2RlOjB9LHdoaWNoOmZ1bmN0aW9uKGEpe3JldHVyblwia2V5cHJlc3NcIj09PVxuYS50eXBlP29kKGEpOlwia2V5ZG93blwiPT09YS50eXBlfHxcImtleXVwXCI9PT1hLnR5cGU/YS5rZXlDb2RlOjB9fSksUmQ9cmQoUWQpLFNkPUEoe30sQWQse3BvaW50ZXJJZDowLHdpZHRoOjAsaGVpZ2h0OjAscHJlc3N1cmU6MCx0YW5nZW50aWFsUHJlc3N1cmU6MCx0aWx0WDowLHRpbHRZOjAsdHdpc3Q6MCxwb2ludGVyVHlwZTowLGlzUHJpbWFyeTowfSksVGQ9cmQoU2QpLFVkPUEoe30sdWQse3RvdWNoZXM6MCx0YXJnZXRUb3VjaGVzOjAsY2hhbmdlZFRvdWNoZXM6MCxhbHRLZXk6MCxtZXRhS2V5OjAsY3RybEtleTowLHNoaWZ0S2V5OjAsZ2V0TW9kaWZpZXJTdGF0ZTp6ZH0pLFZkPXJkKFVkKSxXZD1BKHt9LHNkLHtwcm9wZXJ0eU5hbWU6MCxlbGFwc2VkVGltZTowLHBzZXVkb0VsZW1lbnQ6MH0pLFhkPXJkKFdkKSxZZD1BKHt9LEFkLHtkZWx0YVg6ZnVuY3Rpb24oYSl7cmV0dXJuXCJkZWx0YVhcImluIGE/YS5kZWx0YVg6XCJ3aGVlbERlbHRhWFwiaW4gYT8tYS53aGVlbERlbHRhWDowfSxcbmRlbHRhWTpmdW5jdGlvbihhKXtyZXR1cm5cImRlbHRhWVwiaW4gYT9hLmRlbHRhWTpcIndoZWVsRGVsdGFZXCJpbiBhPy1hLndoZWVsRGVsdGFZOlwid2hlZWxEZWx0YVwiaW4gYT8tYS53aGVlbERlbHRhOjB9LGRlbHRhWjowLGRlbHRhTW9kZTowfSksWmQ9cmQoWWQpLCRkPVs5LDEzLDI3LDMyXSxhZT1pYSYmXCJDb21wb3NpdGlvbkV2ZW50XCJpbiB3aW5kb3csYmU9bnVsbDtpYSYmXCJkb2N1bWVudE1vZGVcImluIGRvY3VtZW50JiYoYmU9ZG9jdW1lbnQuZG9jdW1lbnRNb2RlKTt2YXIgY2U9aWEmJlwiVGV4dEV2ZW50XCJpbiB3aW5kb3cmJiFiZSxkZT1pYSYmKCFhZXx8YmUmJjg8YmUmJjExPj1iZSksZWU9U3RyaW5nLmZyb21DaGFyQ29kZSgzMiksZmU9ITE7XG5mdW5jdGlvbiBnZShhLGIpe3N3aXRjaChhKXtjYXNlIFwia2V5dXBcIjpyZXR1cm4tMSE9PSRkLmluZGV4T2YoYi5rZXlDb2RlKTtjYXNlIFwia2V5ZG93blwiOnJldHVybiAyMjkhPT1iLmtleUNvZGU7Y2FzZSBcImtleXByZXNzXCI6Y2FzZSBcIm1vdXNlZG93blwiOmNhc2UgXCJmb2N1c291dFwiOnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuITF9fWZ1bmN0aW9uIGhlKGEpe2E9YS5kZXRhaWw7cmV0dXJuXCJvYmplY3RcIj09PXR5cGVvZiBhJiZcImRhdGFcImluIGE/YS5kYXRhOm51bGx9dmFyIGllPSExO2Z1bmN0aW9uIGplKGEsYil7c3dpdGNoKGEpe2Nhc2UgXCJjb21wb3NpdGlvbmVuZFwiOnJldHVybiBoZShiKTtjYXNlIFwia2V5cHJlc3NcIjppZigzMiE9PWIud2hpY2gpcmV0dXJuIG51bGw7ZmU9ITA7cmV0dXJuIGVlO2Nhc2UgXCJ0ZXh0SW5wdXRcIjpyZXR1cm4gYT1iLmRhdGEsYT09PWVlJiZmZT9udWxsOmE7ZGVmYXVsdDpyZXR1cm4gbnVsbH19XG5mdW5jdGlvbiBrZShhLGIpe2lmKGllKXJldHVyblwiY29tcG9zaXRpb25lbmRcIj09PWF8fCFhZSYmZ2UoYSxiKT8oYT1uZCgpLG1kPWxkPWtkPW51bGwsaWU9ITEsYSk6bnVsbDtzd2l0Y2goYSl7Y2FzZSBcInBhc3RlXCI6cmV0dXJuIG51bGw7Y2FzZSBcImtleXByZXNzXCI6aWYoIShiLmN0cmxLZXl8fGIuYWx0S2V5fHxiLm1ldGFLZXkpfHxiLmN0cmxLZXkmJmIuYWx0S2V5KXtpZihiLmNoYXImJjE8Yi5jaGFyLmxlbmd0aClyZXR1cm4gYi5jaGFyO2lmKGIud2hpY2gpcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoYi53aGljaCl9cmV0dXJuIG51bGw7Y2FzZSBcImNvbXBvc2l0aW9uZW5kXCI6cmV0dXJuIGRlJiZcImtvXCIhPT1iLmxvY2FsZT9udWxsOmIuZGF0YTtkZWZhdWx0OnJldHVybiBudWxsfX1cbnZhciBsZT17Y29sb3I6ITAsZGF0ZTohMCxkYXRldGltZTohMCxcImRhdGV0aW1lLWxvY2FsXCI6ITAsZW1haWw6ITAsbW9udGg6ITAsbnVtYmVyOiEwLHBhc3N3b3JkOiEwLHJhbmdlOiEwLHNlYXJjaDohMCx0ZWw6ITAsdGV4dDohMCx0aW1lOiEwLHVybDohMCx3ZWVrOiEwfTtmdW5jdGlvbiBtZShhKXt2YXIgYj1hJiZhLm5vZGVOYW1lJiZhLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuXCJpbnB1dFwiPT09Yj8hIWxlW2EudHlwZV06XCJ0ZXh0YXJlYVwiPT09Yj8hMDohMX1mdW5jdGlvbiBuZShhLGIsYyxkKXtFYihkKTtiPW9lKGIsXCJvbkNoYW5nZVwiKTswPGIubGVuZ3RoJiYoYz1uZXcgdGQoXCJvbkNoYW5nZVwiLFwiY2hhbmdlXCIsbnVsbCxjLGQpLGEucHVzaCh7ZXZlbnQ6YyxsaXN0ZW5lcnM6Yn0pKX12YXIgcGU9bnVsbCxxZT1udWxsO2Z1bmN0aW9uIHJlKGEpe3NlKGEsMCl9ZnVuY3Rpb24gdGUoYSl7dmFyIGI9dWUoYSk7aWYoV2EoYikpcmV0dXJuIGF9XG5mdW5jdGlvbiB2ZShhLGIpe2lmKFwiY2hhbmdlXCI9PT1hKXJldHVybiBifXZhciB3ZT0hMTtpZihpYSl7dmFyIHhlO2lmKGlhKXt2YXIgeWU9XCJvbmlucHV0XCJpbiBkb2N1bWVudDtpZigheWUpe3ZhciB6ZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO3plLnNldEF0dHJpYnV0ZShcIm9uaW5wdXRcIixcInJldHVybjtcIik7eWU9XCJmdW5jdGlvblwiPT09dHlwZW9mIHplLm9uaW5wdXR9eGU9eWV9ZWxzZSB4ZT0hMTt3ZT14ZSYmKCFkb2N1bWVudC5kb2N1bWVudE1vZGV8fDk8ZG9jdW1lbnQuZG9jdW1lbnRNb2RlKX1mdW5jdGlvbiBBZSgpe3BlJiYocGUuZGV0YWNoRXZlbnQoXCJvbnByb3BlcnR5Y2hhbmdlXCIsQmUpLHFlPXBlPW51bGwpfWZ1bmN0aW9uIEJlKGEpe2lmKFwidmFsdWVcIj09PWEucHJvcGVydHlOYW1lJiZ0ZShxZSkpe3ZhciBiPVtdO25lKGIscWUsYSx4YihhKSk7SmIocmUsYil9fVxuZnVuY3Rpb24gQ2UoYSxiLGMpe1wiZm9jdXNpblwiPT09YT8oQWUoKSxwZT1iLHFlPWMscGUuYXR0YWNoRXZlbnQoXCJvbnByb3BlcnR5Y2hhbmdlXCIsQmUpKTpcImZvY3Vzb3V0XCI9PT1hJiZBZSgpfWZ1bmN0aW9uIERlKGEpe2lmKFwic2VsZWN0aW9uY2hhbmdlXCI9PT1hfHxcImtleXVwXCI9PT1hfHxcImtleWRvd25cIj09PWEpcmV0dXJuIHRlKHFlKX1mdW5jdGlvbiBFZShhLGIpe2lmKFwiY2xpY2tcIj09PWEpcmV0dXJuIHRlKGIpfWZ1bmN0aW9uIEZlKGEsYil7aWYoXCJpbnB1dFwiPT09YXx8XCJjaGFuZ2VcIj09PWEpcmV0dXJuIHRlKGIpfWZ1bmN0aW9uIEdlKGEsYil7cmV0dXJuIGE9PT1iJiYoMCE9PWF8fDEvYT09PTEvYil8fGEhPT1hJiZiIT09Yn12YXIgSGU9XCJmdW5jdGlvblwiPT09dHlwZW9mIE9iamVjdC5pcz9PYmplY3QuaXM6R2U7XG5mdW5jdGlvbiBJZShhLGIpe2lmKEhlKGEsYikpcmV0dXJuITA7aWYoXCJvYmplY3RcIiE9PXR5cGVvZiBhfHxudWxsPT09YXx8XCJvYmplY3RcIiE9PXR5cGVvZiBifHxudWxsPT09YilyZXR1cm4hMTt2YXIgYz1PYmplY3Qua2V5cyhhKSxkPU9iamVjdC5rZXlzKGIpO2lmKGMubGVuZ3RoIT09ZC5sZW5ndGgpcmV0dXJuITE7Zm9yKGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGU9Y1tkXTtpZighamEuY2FsbChiLGUpfHwhSGUoYVtlXSxiW2VdKSlyZXR1cm4hMX1yZXR1cm4hMH1mdW5jdGlvbiBKZShhKXtmb3IoO2EmJmEuZmlyc3RDaGlsZDspYT1hLmZpcnN0Q2hpbGQ7cmV0dXJuIGF9XG5mdW5jdGlvbiBLZShhLGIpe3ZhciBjPUplKGEpO2E9MDtmb3IodmFyIGQ7Yzspe2lmKDM9PT1jLm5vZGVUeXBlKXtkPWErYy50ZXh0Q29udGVudC5sZW5ndGg7aWYoYTw9YiYmZD49YilyZXR1cm57bm9kZTpjLG9mZnNldDpiLWF9O2E9ZH1hOntmb3IoO2M7KXtpZihjLm5leHRTaWJsaW5nKXtjPWMubmV4dFNpYmxpbmc7YnJlYWsgYX1jPWMucGFyZW50Tm9kZX1jPXZvaWQgMH1jPUplKGMpfX1mdW5jdGlvbiBMZShhLGIpe3JldHVybiBhJiZiP2E9PT1iPyEwOmEmJjM9PT1hLm5vZGVUeXBlPyExOmImJjM9PT1iLm5vZGVUeXBlP0xlKGEsYi5wYXJlbnROb2RlKTpcImNvbnRhaW5zXCJpbiBhP2EuY29udGFpbnMoYik6YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbj8hIShhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIpJjE2KTohMTohMX1cbmZ1bmN0aW9uIE1lKCl7Zm9yKHZhciBhPXdpbmRvdyxiPVhhKCk7YiBpbnN0YW5jZW9mIGEuSFRNTElGcmFtZUVsZW1lbnQ7KXt0cnl7dmFyIGM9XCJzdHJpbmdcIj09PXR5cGVvZiBiLmNvbnRlbnRXaW5kb3cubG9jYXRpb24uaHJlZn1jYXRjaChkKXtjPSExfWlmKGMpYT1iLmNvbnRlbnRXaW5kb3c7ZWxzZSBicmVhaztiPVhhKGEuZG9jdW1lbnQpfXJldHVybiBifWZ1bmN0aW9uIE5lKGEpe3ZhciBiPWEmJmEubm9kZU5hbWUmJmEubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtyZXR1cm4gYiYmKFwiaW5wdXRcIj09PWImJihcInRleHRcIj09PWEudHlwZXx8XCJzZWFyY2hcIj09PWEudHlwZXx8XCJ0ZWxcIj09PWEudHlwZXx8XCJ1cmxcIj09PWEudHlwZXx8XCJwYXNzd29yZFwiPT09YS50eXBlKXx8XCJ0ZXh0YXJlYVwiPT09Ynx8XCJ0cnVlXCI9PT1hLmNvbnRlbnRFZGl0YWJsZSl9XG5mdW5jdGlvbiBPZShhKXt2YXIgYj1NZSgpLGM9YS5mb2N1c2VkRWxlbSxkPWEuc2VsZWN0aW9uUmFuZ2U7aWYoYiE9PWMmJmMmJmMub3duZXJEb2N1bWVudCYmTGUoYy5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxjKSl7aWYobnVsbCE9PWQmJk5lKGMpKWlmKGI9ZC5zdGFydCxhPWQuZW5kLHZvaWQgMD09PWEmJihhPWIpLFwic2VsZWN0aW9uU3RhcnRcImluIGMpYy5zZWxlY3Rpb25TdGFydD1iLGMuc2VsZWN0aW9uRW5kPU1hdGgubWluKGEsYy52YWx1ZS5sZW5ndGgpO2Vsc2UgaWYoYT0oYj1jLm93bmVyRG9jdW1lbnR8fGRvY3VtZW50KSYmYi5kZWZhdWx0Vmlld3x8d2luZG93LGEuZ2V0U2VsZWN0aW9uKXthPWEuZ2V0U2VsZWN0aW9uKCk7dmFyIGU9Yy50ZXh0Q29udGVudC5sZW5ndGgsZj1NYXRoLm1pbihkLnN0YXJ0LGUpO2Q9dm9pZCAwPT09ZC5lbmQ/ZjpNYXRoLm1pbihkLmVuZCxlKTshYS5leHRlbmQmJmY+ZCYmKGU9ZCxkPWYsZj1lKTtlPUtlKGMsZik7dmFyIGc9S2UoYyxcbmQpO2UmJmcmJigxIT09YS5yYW5nZUNvdW50fHxhLmFuY2hvck5vZGUhPT1lLm5vZGV8fGEuYW5jaG9yT2Zmc2V0IT09ZS5vZmZzZXR8fGEuZm9jdXNOb2RlIT09Zy5ub2RlfHxhLmZvY3VzT2Zmc2V0IT09Zy5vZmZzZXQpJiYoYj1iLmNyZWF0ZVJhbmdlKCksYi5zZXRTdGFydChlLm5vZGUsZS5vZmZzZXQpLGEucmVtb3ZlQWxsUmFuZ2VzKCksZj5kPyhhLmFkZFJhbmdlKGIpLGEuZXh0ZW5kKGcubm9kZSxnLm9mZnNldCkpOihiLnNldEVuZChnLm5vZGUsZy5vZmZzZXQpLGEuYWRkUmFuZ2UoYikpKX1iPVtdO2ZvcihhPWM7YT1hLnBhcmVudE5vZGU7KTE9PT1hLm5vZGVUeXBlJiZiLnB1c2goe2VsZW1lbnQ6YSxsZWZ0OmEuc2Nyb2xsTGVmdCx0b3A6YS5zY3JvbGxUb3B9KTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYy5mb2N1cyYmYy5mb2N1cygpO2ZvcihjPTA7YzxiLmxlbmd0aDtjKyspYT1iW2NdLGEuZWxlbWVudC5zY3JvbGxMZWZ0PWEubGVmdCxhLmVsZW1lbnQuc2Nyb2xsVG9wPWEudG9wfX1cbnZhciBQZT1pYSYmXCJkb2N1bWVudE1vZGVcImluIGRvY3VtZW50JiYxMT49ZG9jdW1lbnQuZG9jdW1lbnRNb2RlLFFlPW51bGwsUmU9bnVsbCxTZT1udWxsLFRlPSExO1xuZnVuY3Rpb24gVWUoYSxiLGMpe3ZhciBkPWMud2luZG93PT09Yz9jLmRvY3VtZW50Ojk9PT1jLm5vZGVUeXBlP2M6Yy5vd25lckRvY3VtZW50O1RlfHxudWxsPT1RZXx8UWUhPT1YYShkKXx8KGQ9UWUsXCJzZWxlY3Rpb25TdGFydFwiaW4gZCYmTmUoZCk/ZD17c3RhcnQ6ZC5zZWxlY3Rpb25TdGFydCxlbmQ6ZC5zZWxlY3Rpb25FbmR9OihkPShkLm93bmVyRG9jdW1lbnQmJmQub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlld3x8d2luZG93KS5nZXRTZWxlY3Rpb24oKSxkPXthbmNob3JOb2RlOmQuYW5jaG9yTm9kZSxhbmNob3JPZmZzZXQ6ZC5hbmNob3JPZmZzZXQsZm9jdXNOb2RlOmQuZm9jdXNOb2RlLGZvY3VzT2Zmc2V0OmQuZm9jdXNPZmZzZXR9KSxTZSYmSWUoU2UsZCl8fChTZT1kLGQ9b2UoUmUsXCJvblNlbGVjdFwiKSwwPGQubGVuZ3RoJiYoYj1uZXcgdGQoXCJvblNlbGVjdFwiLFwic2VsZWN0XCIsbnVsbCxiLGMpLGEucHVzaCh7ZXZlbnQ6YixsaXN0ZW5lcnM6ZH0pLGIudGFyZ2V0PVFlKSkpfVxuZnVuY3Rpb24gVmUoYSxiKXt2YXIgYz17fTtjW2EudG9Mb3dlckNhc2UoKV09Yi50b0xvd2VyQ2FzZSgpO2NbXCJXZWJraXRcIithXT1cIndlYmtpdFwiK2I7Y1tcIk1velwiK2FdPVwibW96XCIrYjtyZXR1cm4gY312YXIgV2U9e2FuaW1hdGlvbmVuZDpWZShcIkFuaW1hdGlvblwiLFwiQW5pbWF0aW9uRW5kXCIpLGFuaW1hdGlvbml0ZXJhdGlvbjpWZShcIkFuaW1hdGlvblwiLFwiQW5pbWF0aW9uSXRlcmF0aW9uXCIpLGFuaW1hdGlvbnN0YXJ0OlZlKFwiQW5pbWF0aW9uXCIsXCJBbmltYXRpb25TdGFydFwiKSx0cmFuc2l0aW9uZW5kOlZlKFwiVHJhbnNpdGlvblwiLFwiVHJhbnNpdGlvbkVuZFwiKX0sWGU9e30sWWU9e307XG5pYSYmKFllPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikuc3R5bGUsXCJBbmltYXRpb25FdmVudFwiaW4gd2luZG93fHwoZGVsZXRlIFdlLmFuaW1hdGlvbmVuZC5hbmltYXRpb24sZGVsZXRlIFdlLmFuaW1hdGlvbml0ZXJhdGlvbi5hbmltYXRpb24sZGVsZXRlIFdlLmFuaW1hdGlvbnN0YXJ0LmFuaW1hdGlvbiksXCJUcmFuc2l0aW9uRXZlbnRcImluIHdpbmRvd3x8ZGVsZXRlIFdlLnRyYW5zaXRpb25lbmQudHJhbnNpdGlvbik7ZnVuY3Rpb24gWmUoYSl7aWYoWGVbYV0pcmV0dXJuIFhlW2FdO2lmKCFXZVthXSlyZXR1cm4gYTt2YXIgYj1XZVthXSxjO2ZvcihjIGluIGIpaWYoYi5oYXNPd25Qcm9wZXJ0eShjKSYmYyBpbiBZZSlyZXR1cm4gWGVbYV09YltjXTtyZXR1cm4gYX12YXIgJGU9WmUoXCJhbmltYXRpb25lbmRcIiksYWY9WmUoXCJhbmltYXRpb25pdGVyYXRpb25cIiksYmY9WmUoXCJhbmltYXRpb25zdGFydFwiKSxjZj1aZShcInRyYW5zaXRpb25lbmRcIiksZGY9bmV3IE1hcCxlZj1cImFib3J0IGF1eENsaWNrIGNhbmNlbCBjYW5QbGF5IGNhblBsYXlUaHJvdWdoIGNsaWNrIGNsb3NlIGNvbnRleHRNZW51IGNvcHkgY3V0IGRyYWcgZHJhZ0VuZCBkcmFnRW50ZXIgZHJhZ0V4aXQgZHJhZ0xlYXZlIGRyYWdPdmVyIGRyYWdTdGFydCBkcm9wIGR1cmF0aW9uQ2hhbmdlIGVtcHRpZWQgZW5jcnlwdGVkIGVuZGVkIGVycm9yIGdvdFBvaW50ZXJDYXB0dXJlIGlucHV0IGludmFsaWQga2V5RG93biBrZXlQcmVzcyBrZXlVcCBsb2FkIGxvYWRlZERhdGEgbG9hZGVkTWV0YWRhdGEgbG9hZFN0YXJ0IGxvc3RQb2ludGVyQ2FwdHVyZSBtb3VzZURvd24gbW91c2VNb3ZlIG1vdXNlT3V0IG1vdXNlT3ZlciBtb3VzZVVwIHBhc3RlIHBhdXNlIHBsYXkgcGxheWluZyBwb2ludGVyQ2FuY2VsIHBvaW50ZXJEb3duIHBvaW50ZXJNb3ZlIHBvaW50ZXJPdXQgcG9pbnRlck92ZXIgcG9pbnRlclVwIHByb2dyZXNzIHJhdGVDaGFuZ2UgcmVzZXQgcmVzaXplIHNlZWtlZCBzZWVraW5nIHN0YWxsZWQgc3VibWl0IHN1c3BlbmQgdGltZVVwZGF0ZSB0b3VjaENhbmNlbCB0b3VjaEVuZCB0b3VjaFN0YXJ0IHZvbHVtZUNoYW5nZSBzY3JvbGwgdG9nZ2xlIHRvdWNoTW92ZSB3YWl0aW5nIHdoZWVsXCIuc3BsaXQoXCIgXCIpO1xuZnVuY3Rpb24gZmYoYSxiKXtkZi5zZXQoYSxiKTtmYShiLFthXSl9Zm9yKHZhciBnZj0wO2dmPGVmLmxlbmd0aDtnZisrKXt2YXIgaGY9ZWZbZ2ZdLGpmPWhmLnRvTG93ZXJDYXNlKCksa2Y9aGZbMF0udG9VcHBlckNhc2UoKStoZi5zbGljZSgxKTtmZihqZixcIm9uXCIra2YpfWZmKCRlLFwib25BbmltYXRpb25FbmRcIik7ZmYoYWYsXCJvbkFuaW1hdGlvbkl0ZXJhdGlvblwiKTtmZihiZixcIm9uQW5pbWF0aW9uU3RhcnRcIik7ZmYoXCJkYmxjbGlja1wiLFwib25Eb3VibGVDbGlja1wiKTtmZihcImZvY3VzaW5cIixcIm9uRm9jdXNcIik7ZmYoXCJmb2N1c291dFwiLFwib25CbHVyXCIpO2ZmKGNmLFwib25UcmFuc2l0aW9uRW5kXCIpO2hhKFwib25Nb3VzZUVudGVyXCIsW1wibW91c2VvdXRcIixcIm1vdXNlb3ZlclwiXSk7aGEoXCJvbk1vdXNlTGVhdmVcIixbXCJtb3VzZW91dFwiLFwibW91c2VvdmVyXCJdKTtoYShcIm9uUG9pbnRlckVudGVyXCIsW1wicG9pbnRlcm91dFwiLFwicG9pbnRlcm92ZXJcIl0pO1xuaGEoXCJvblBvaW50ZXJMZWF2ZVwiLFtcInBvaW50ZXJvdXRcIixcInBvaW50ZXJvdmVyXCJdKTtmYShcIm9uQ2hhbmdlXCIsXCJjaGFuZ2UgY2xpY2sgZm9jdXNpbiBmb2N1c291dCBpbnB1dCBrZXlkb3duIGtleXVwIHNlbGVjdGlvbmNoYW5nZVwiLnNwbGl0KFwiIFwiKSk7ZmEoXCJvblNlbGVjdFwiLFwiZm9jdXNvdXQgY29udGV4dG1lbnUgZHJhZ2VuZCBmb2N1c2luIGtleWRvd24ga2V5dXAgbW91c2Vkb3duIG1vdXNldXAgc2VsZWN0aW9uY2hhbmdlXCIuc3BsaXQoXCIgXCIpKTtmYShcIm9uQmVmb3JlSW5wdXRcIixbXCJjb21wb3NpdGlvbmVuZFwiLFwia2V5cHJlc3NcIixcInRleHRJbnB1dFwiLFwicGFzdGVcIl0pO2ZhKFwib25Db21wb3NpdGlvbkVuZFwiLFwiY29tcG9zaXRpb25lbmQgZm9jdXNvdXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBtb3VzZWRvd25cIi5zcGxpdChcIiBcIikpO2ZhKFwib25Db21wb3NpdGlvblN0YXJ0XCIsXCJjb21wb3NpdGlvbnN0YXJ0IGZvY3Vzb3V0IGtleWRvd24ga2V5cHJlc3Mga2V5dXAgbW91c2Vkb3duXCIuc3BsaXQoXCIgXCIpKTtcbmZhKFwib25Db21wb3NpdGlvblVwZGF0ZVwiLFwiY29tcG9zaXRpb251cGRhdGUgZm9jdXNvdXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBtb3VzZWRvd25cIi5zcGxpdChcIiBcIikpO3ZhciBsZj1cImFib3J0IGNhbnBsYXkgY2FucGxheXRocm91Z2ggZHVyYXRpb25jaGFuZ2UgZW1wdGllZCBlbmNyeXB0ZWQgZW5kZWQgZXJyb3IgbG9hZGVkZGF0YSBsb2FkZWRtZXRhZGF0YSBsb2Fkc3RhcnQgcGF1c2UgcGxheSBwbGF5aW5nIHByb2dyZXNzIHJhdGVjaGFuZ2UgcmVzaXplIHNlZWtlZCBzZWVraW5nIHN0YWxsZWQgc3VzcGVuZCB0aW1ldXBkYXRlIHZvbHVtZWNoYW5nZSB3YWl0aW5nXCIuc3BsaXQoXCIgXCIpLG1mPW5ldyBTZXQoXCJjYW5jZWwgY2xvc2UgaW52YWxpZCBsb2FkIHNjcm9sbCB0b2dnbGVcIi5zcGxpdChcIiBcIikuY29uY2F0KGxmKSk7XG5mdW5jdGlvbiBuZihhLGIsYyl7dmFyIGQ9YS50eXBlfHxcInVua25vd24tZXZlbnRcIjthLmN1cnJlbnRUYXJnZXQ9YztVYihkLGIsdm9pZCAwLGEpO2EuY3VycmVudFRhcmdldD1udWxsfVxuZnVuY3Rpb24gc2UoYSxiKXtiPTAhPT0oYiY0KTtmb3IodmFyIGM9MDtjPGEubGVuZ3RoO2MrKyl7dmFyIGQ9YVtjXSxlPWQuZXZlbnQ7ZD1kLmxpc3RlbmVyczthOnt2YXIgZj12b2lkIDA7aWYoYilmb3IodmFyIGc9ZC5sZW5ndGgtMTswPD1nO2ctLSl7dmFyIGg9ZFtnXSxrPWguaW5zdGFuY2UsbD1oLmN1cnJlbnRUYXJnZXQ7aD1oLmxpc3RlbmVyO2lmKGshPT1mJiZlLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpYnJlYWsgYTtuZihlLGgsbCk7Zj1rfWVsc2UgZm9yKGc9MDtnPGQubGVuZ3RoO2crKyl7aD1kW2ddO2s9aC5pbnN0YW5jZTtsPWguY3VycmVudFRhcmdldDtoPWgubGlzdGVuZXI7aWYoayE9PWYmJmUuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSlicmVhayBhO25mKGUsaCxsKTtmPWt9fX1pZihRYil0aHJvdyBhPVJiLFFiPSExLFJiPW51bGwsYTt9XG5mdW5jdGlvbiBEKGEsYil7dmFyIGM9YltvZl07dm9pZCAwPT09YyYmKGM9YltvZl09bmV3IFNldCk7dmFyIGQ9YStcIl9fYnViYmxlXCI7Yy5oYXMoZCl8fChwZihiLGEsMiwhMSksYy5hZGQoZCkpfWZ1bmN0aW9uIHFmKGEsYixjKXt2YXIgZD0wO2ImJihkfD00KTtwZihjLGEsZCxiKX12YXIgcmY9XCJfcmVhY3RMaXN0ZW5pbmdcIitNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyKTtmdW5jdGlvbiBzZihhKXtpZighYVtyZl0pe2FbcmZdPSEwO2RhLmZvckVhY2goZnVuY3Rpb24oYil7XCJzZWxlY3Rpb25jaGFuZ2VcIiE9PWImJihtZi5oYXMoYil8fHFmKGIsITEsYSkscWYoYiwhMCxhKSl9KTt2YXIgYj05PT09YS5ub2RlVHlwZT9hOmEub3duZXJEb2N1bWVudDtudWxsPT09Ynx8YltyZl18fChiW3JmXT0hMCxxZihcInNlbGVjdGlvbmNoYW5nZVwiLCExLGIpKX19XG5mdW5jdGlvbiBwZihhLGIsYyxkKXtzd2l0Y2goamQoYikpe2Nhc2UgMTp2YXIgZT1lZDticmVhaztjYXNlIDQ6ZT1nZDticmVhaztkZWZhdWx0OmU9ZmR9Yz1lLmJpbmQobnVsbCxiLGMsYSk7ZT12b2lkIDA7IUxifHxcInRvdWNoc3RhcnRcIiE9PWImJlwidG91Y2htb3ZlXCIhPT1iJiZcIndoZWVsXCIhPT1ifHwoZT0hMCk7ZD92b2lkIDAhPT1lP2EuYWRkRXZlbnRMaXN0ZW5lcihiLGMse2NhcHR1cmU6ITAscGFzc2l2ZTplfSk6YS5hZGRFdmVudExpc3RlbmVyKGIsYywhMCk6dm9pZCAwIT09ZT9hLmFkZEV2ZW50TGlzdGVuZXIoYixjLHtwYXNzaXZlOmV9KTphLmFkZEV2ZW50TGlzdGVuZXIoYixjLCExKX1cbmZ1bmN0aW9uIGhkKGEsYixjLGQsZSl7dmFyIGY9ZDtpZigwPT09KGImMSkmJjA9PT0oYiYyKSYmbnVsbCE9PWQpYTpmb3IoOzspe2lmKG51bGw9PT1kKXJldHVybjt2YXIgZz1kLnRhZztpZigzPT09Z3x8ND09PWcpe3ZhciBoPWQuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87aWYoaD09PWV8fDg9PT1oLm5vZGVUeXBlJiZoLnBhcmVudE5vZGU9PT1lKWJyZWFrO2lmKDQ9PT1nKWZvcihnPWQucmV0dXJuO251bGwhPT1nOyl7dmFyIGs9Zy50YWc7aWYoMz09PWt8fDQ9PT1rKWlmKGs9Zy5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyxrPT09ZXx8OD09PWsubm9kZVR5cGUmJmsucGFyZW50Tm9kZT09PWUpcmV0dXJuO2c9Zy5yZXR1cm59Zm9yKDtudWxsIT09aDspe2c9V2MoaCk7aWYobnVsbD09PWcpcmV0dXJuO2s9Zy50YWc7aWYoNT09PWt8fDY9PT1rKXtkPWY9Zztjb250aW51ZSBhfWg9aC5wYXJlbnROb2RlfX1kPWQucmV0dXJufUpiKGZ1bmN0aW9uKCl7dmFyIGQ9ZixlPXhiKGMpLGc9W107XG5hOnt2YXIgaD1kZi5nZXQoYSk7aWYodm9pZCAwIT09aCl7dmFyIGs9dGQsbj1hO3N3aXRjaChhKXtjYXNlIFwia2V5cHJlc3NcIjppZigwPT09b2QoYykpYnJlYWsgYTtjYXNlIFwia2V5ZG93blwiOmNhc2UgXCJrZXl1cFwiOms9UmQ7YnJlYWs7Y2FzZSBcImZvY3VzaW5cIjpuPVwiZm9jdXNcIjtrPUZkO2JyZWFrO2Nhc2UgXCJmb2N1c291dFwiOm49XCJibHVyXCI7az1GZDticmVhaztjYXNlIFwiYmVmb3JlYmx1clwiOmNhc2UgXCJhZnRlcmJsdXJcIjprPUZkO2JyZWFrO2Nhc2UgXCJjbGlja1wiOmlmKDI9PT1jLmJ1dHRvbilicmVhayBhO2Nhc2UgXCJhdXhjbGlja1wiOmNhc2UgXCJkYmxjbGlja1wiOmNhc2UgXCJtb3VzZWRvd25cIjpjYXNlIFwibW91c2Vtb3ZlXCI6Y2FzZSBcIm1vdXNldXBcIjpjYXNlIFwibW91c2VvdXRcIjpjYXNlIFwibW91c2VvdmVyXCI6Y2FzZSBcImNvbnRleHRtZW51XCI6az1CZDticmVhaztjYXNlIFwiZHJhZ1wiOmNhc2UgXCJkcmFnZW5kXCI6Y2FzZSBcImRyYWdlbnRlclwiOmNhc2UgXCJkcmFnZXhpdFwiOmNhc2UgXCJkcmFnbGVhdmVcIjpjYXNlIFwiZHJhZ292ZXJcIjpjYXNlIFwiZHJhZ3N0YXJ0XCI6Y2FzZSBcImRyb3BcIjprPVxuRGQ7YnJlYWs7Y2FzZSBcInRvdWNoY2FuY2VsXCI6Y2FzZSBcInRvdWNoZW5kXCI6Y2FzZSBcInRvdWNobW92ZVwiOmNhc2UgXCJ0b3VjaHN0YXJ0XCI6az1WZDticmVhaztjYXNlICRlOmNhc2UgYWY6Y2FzZSBiZjprPUhkO2JyZWFrO2Nhc2UgY2Y6az1YZDticmVhaztjYXNlIFwic2Nyb2xsXCI6az12ZDticmVhaztjYXNlIFwid2hlZWxcIjprPVpkO2JyZWFrO2Nhc2UgXCJjb3B5XCI6Y2FzZSBcImN1dFwiOmNhc2UgXCJwYXN0ZVwiOms9SmQ7YnJlYWs7Y2FzZSBcImdvdHBvaW50ZXJjYXB0dXJlXCI6Y2FzZSBcImxvc3Rwb2ludGVyY2FwdHVyZVwiOmNhc2UgXCJwb2ludGVyY2FuY2VsXCI6Y2FzZSBcInBvaW50ZXJkb3duXCI6Y2FzZSBcInBvaW50ZXJtb3ZlXCI6Y2FzZSBcInBvaW50ZXJvdXRcIjpjYXNlIFwicG9pbnRlcm92ZXJcIjpjYXNlIFwicG9pbnRlcnVwXCI6az1UZH12YXIgdD0wIT09KGImNCksSj0hdCYmXCJzY3JvbGxcIj09PWEseD10P251bGwhPT1oP2grXCJDYXB0dXJlXCI6bnVsbDpoO3Q9W107Zm9yKHZhciB3PWQsdTtudWxsIT09XG53Oyl7dT13O3ZhciBGPXUuc3RhdGVOb2RlOzU9PT11LnRhZyYmbnVsbCE9PUYmJih1PUYsbnVsbCE9PXgmJihGPUtiKHcseCksbnVsbCE9RiYmdC5wdXNoKHRmKHcsRix1KSkpKTtpZihKKWJyZWFrO3c9dy5yZXR1cm59MDx0Lmxlbmd0aCYmKGg9bmV3IGsoaCxuLG51bGwsYyxlKSxnLnB1c2goe2V2ZW50OmgsbGlzdGVuZXJzOnR9KSl9fWlmKDA9PT0oYiY3KSl7YTp7aD1cIm1vdXNlb3ZlclwiPT09YXx8XCJwb2ludGVyb3ZlclwiPT09YTtrPVwibW91c2VvdXRcIj09PWF8fFwicG9pbnRlcm91dFwiPT09YTtpZihoJiZjIT09d2ImJihuPWMucmVsYXRlZFRhcmdldHx8Yy5mcm9tRWxlbWVudCkmJihXYyhuKXx8blt1Zl0pKWJyZWFrIGE7aWYoa3x8aCl7aD1lLndpbmRvdz09PWU/ZTooaD1lLm93bmVyRG9jdW1lbnQpP2guZGVmYXVsdFZpZXd8fGgucGFyZW50V2luZG93OndpbmRvdztpZihrKXtpZihuPWMucmVsYXRlZFRhcmdldHx8Yy50b0VsZW1lbnQsaz1kLG49bj9XYyhuKTpudWxsLG51bGwhPT1cbm4mJihKPVZiKG4pLG4hPT1KfHw1IT09bi50YWcmJjYhPT1uLnRhZykpbj1udWxsfWVsc2Ugaz1udWxsLG49ZDtpZihrIT09bil7dD1CZDtGPVwib25Nb3VzZUxlYXZlXCI7eD1cIm9uTW91c2VFbnRlclwiO3c9XCJtb3VzZVwiO2lmKFwicG9pbnRlcm91dFwiPT09YXx8XCJwb2ludGVyb3ZlclwiPT09YSl0PVRkLEY9XCJvblBvaW50ZXJMZWF2ZVwiLHg9XCJvblBvaW50ZXJFbnRlclwiLHc9XCJwb2ludGVyXCI7Sj1udWxsPT1rP2g6dWUoayk7dT1udWxsPT1uP2g6dWUobik7aD1uZXcgdChGLHcrXCJsZWF2ZVwiLGssYyxlKTtoLnRhcmdldD1KO2gucmVsYXRlZFRhcmdldD11O0Y9bnVsbDtXYyhlKT09PWQmJih0PW5ldyB0KHgsdytcImVudGVyXCIsbixjLGUpLHQudGFyZ2V0PXUsdC5yZWxhdGVkVGFyZ2V0PUosRj10KTtKPUY7aWYoayYmbiliOnt0PWs7eD1uO3c9MDtmb3IodT10O3U7dT12Zih1KSl3Kys7dT0wO2ZvcihGPXg7RjtGPXZmKEYpKXUrKztmb3IoOzA8dy11Oyl0PXZmKHQpLHctLTtmb3IoOzA8dS13Oyl4PVxudmYoeCksdS0tO2Zvcig7dy0tOyl7aWYodD09PXh8fG51bGwhPT14JiZ0PT09eC5hbHRlcm5hdGUpYnJlYWsgYjt0PXZmKHQpO3g9dmYoeCl9dD1udWxsfWVsc2UgdD1udWxsO251bGwhPT1rJiZ3ZihnLGgsayx0LCExKTtudWxsIT09biYmbnVsbCE9PUomJndmKGcsSixuLHQsITApfX19YTp7aD1kP3VlKGQpOndpbmRvdztrPWgubm9kZU5hbWUmJmgubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtpZihcInNlbGVjdFwiPT09a3x8XCJpbnB1dFwiPT09ayYmXCJmaWxlXCI9PT1oLnR5cGUpdmFyIG5hPXZlO2Vsc2UgaWYobWUoaCkpaWYod2UpbmE9RmU7ZWxzZXtuYT1EZTt2YXIgeGE9Q2V9ZWxzZShrPWgubm9kZU5hbWUpJiZcImlucHV0XCI9PT1rLnRvTG93ZXJDYXNlKCkmJihcImNoZWNrYm94XCI9PT1oLnR5cGV8fFwicmFkaW9cIj09PWgudHlwZSkmJihuYT1FZSk7aWYobmEmJihuYT1uYShhLGQpKSl7bmUoZyxuYSxjLGUpO2JyZWFrIGF9eGEmJnhhKGEsaCxkKTtcImZvY3Vzb3V0XCI9PT1hJiYoeGE9aC5fd3JhcHBlclN0YXRlKSYmXG54YS5jb250cm9sbGVkJiZcIm51bWJlclwiPT09aC50eXBlJiZjYihoLFwibnVtYmVyXCIsaC52YWx1ZSl9eGE9ZD91ZShkKTp3aW5kb3c7c3dpdGNoKGEpe2Nhc2UgXCJmb2N1c2luXCI6aWYobWUoeGEpfHxcInRydWVcIj09PXhhLmNvbnRlbnRFZGl0YWJsZSlRZT14YSxSZT1kLFNlPW51bGw7YnJlYWs7Y2FzZSBcImZvY3Vzb3V0XCI6U2U9UmU9UWU9bnVsbDticmVhaztjYXNlIFwibW91c2Vkb3duXCI6VGU9ITA7YnJlYWs7Y2FzZSBcImNvbnRleHRtZW51XCI6Y2FzZSBcIm1vdXNldXBcIjpjYXNlIFwiZHJhZ2VuZFwiOlRlPSExO1VlKGcsYyxlKTticmVhaztjYXNlIFwic2VsZWN0aW9uY2hhbmdlXCI6aWYoUGUpYnJlYWs7Y2FzZSBcImtleWRvd25cIjpjYXNlIFwia2V5dXBcIjpVZShnLGMsZSl9dmFyICRhO2lmKGFlKWI6e3N3aXRjaChhKXtjYXNlIFwiY29tcG9zaXRpb25zdGFydFwiOnZhciBiYT1cIm9uQ29tcG9zaXRpb25TdGFydFwiO2JyZWFrIGI7Y2FzZSBcImNvbXBvc2l0aW9uZW5kXCI6YmE9XCJvbkNvbXBvc2l0aW9uRW5kXCI7XG5icmVhayBiO2Nhc2UgXCJjb21wb3NpdGlvbnVwZGF0ZVwiOmJhPVwib25Db21wb3NpdGlvblVwZGF0ZVwiO2JyZWFrIGJ9YmE9dm9pZCAwfWVsc2UgaWU/Z2UoYSxjKSYmKGJhPVwib25Db21wb3NpdGlvbkVuZFwiKTpcImtleWRvd25cIj09PWEmJjIyOT09PWMua2V5Q29kZSYmKGJhPVwib25Db21wb3NpdGlvblN0YXJ0XCIpO2JhJiYoZGUmJlwia29cIiE9PWMubG9jYWxlJiYoaWV8fFwib25Db21wb3NpdGlvblN0YXJ0XCIhPT1iYT9cIm9uQ29tcG9zaXRpb25FbmRcIj09PWJhJiZpZSYmKCRhPW5kKCkpOihrZD1lLGxkPVwidmFsdWVcImluIGtkP2tkLnZhbHVlOmtkLnRleHRDb250ZW50LGllPSEwKSkseGE9b2UoZCxiYSksMDx4YS5sZW5ndGgmJihiYT1uZXcgTGQoYmEsYSxudWxsLGMsZSksZy5wdXNoKHtldmVudDpiYSxsaXN0ZW5lcnM6eGF9KSwkYT9iYS5kYXRhPSRhOigkYT1oZShjKSxudWxsIT09JGEmJihiYS5kYXRhPSRhKSkpKTtpZigkYT1jZT9qZShhLGMpOmtlKGEsYykpZD1vZShkLFwib25CZWZvcmVJbnB1dFwiKSxcbjA8ZC5sZW5ndGgmJihlPW5ldyBMZChcIm9uQmVmb3JlSW5wdXRcIixcImJlZm9yZWlucHV0XCIsbnVsbCxjLGUpLGcucHVzaCh7ZXZlbnQ6ZSxsaXN0ZW5lcnM6ZH0pLGUuZGF0YT0kYSl9c2UoZyxiKX0pfWZ1bmN0aW9uIHRmKGEsYixjKXtyZXR1cm57aW5zdGFuY2U6YSxsaXN0ZW5lcjpiLGN1cnJlbnRUYXJnZXQ6Y319ZnVuY3Rpb24gb2UoYSxiKXtmb3IodmFyIGM9YitcIkNhcHR1cmVcIixkPVtdO251bGwhPT1hOyl7dmFyIGU9YSxmPWUuc3RhdGVOb2RlOzU9PT1lLnRhZyYmbnVsbCE9PWYmJihlPWYsZj1LYihhLGMpLG51bGwhPWYmJmQudW5zaGlmdCh0ZihhLGYsZSkpLGY9S2IoYSxiKSxudWxsIT1mJiZkLnB1c2godGYoYSxmLGUpKSk7YT1hLnJldHVybn1yZXR1cm4gZH1mdW5jdGlvbiB2ZihhKXtpZihudWxsPT09YSlyZXR1cm4gbnVsbDtkbyBhPWEucmV0dXJuO3doaWxlKGEmJjUhPT1hLnRhZyk7cmV0dXJuIGE/YTpudWxsfVxuZnVuY3Rpb24gd2YoYSxiLGMsZCxlKXtmb3IodmFyIGY9Yi5fcmVhY3ROYW1lLGc9W107bnVsbCE9PWMmJmMhPT1kOyl7dmFyIGg9YyxrPWguYWx0ZXJuYXRlLGw9aC5zdGF0ZU5vZGU7aWYobnVsbCE9PWsmJms9PT1kKWJyZWFrOzU9PT1oLnRhZyYmbnVsbCE9PWwmJihoPWwsZT8oaz1LYihjLGYpLG51bGwhPWsmJmcudW5zaGlmdCh0ZihjLGssaCkpKTplfHwoaz1LYihjLGYpLG51bGwhPWsmJmcucHVzaCh0ZihjLGssaCkpKSk7Yz1jLnJldHVybn0wIT09Zy5sZW5ndGgmJmEucHVzaCh7ZXZlbnQ6YixsaXN0ZW5lcnM6Z30pfXZhciB4Zj0vXFxyXFxuPy9nLHlmPS9cXHUwMDAwfFxcdUZGRkQvZztmdW5jdGlvbiB6ZihhKXtyZXR1cm4oXCJzdHJpbmdcIj09PXR5cGVvZiBhP2E6XCJcIithKS5yZXBsYWNlKHhmLFwiXFxuXCIpLnJlcGxhY2UoeWYsXCJcIil9ZnVuY3Rpb24gQWYoYSxiLGMpe2I9emYoYik7aWYoemYoYSkhPT1iJiZjKXRocm93IEVycm9yKHAoNDI1KSk7fWZ1bmN0aW9uIEJmKCl7fVxudmFyIENmPW51bGwsRGY9bnVsbDtmdW5jdGlvbiBFZihhLGIpe3JldHVyblwidGV4dGFyZWFcIj09PWF8fFwibm9zY3JpcHRcIj09PWF8fFwic3RyaW5nXCI9PT10eXBlb2YgYi5jaGlsZHJlbnx8XCJudW1iZXJcIj09PXR5cGVvZiBiLmNoaWxkcmVufHxcIm9iamVjdFwiPT09dHlwZW9mIGIuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwmJm51bGwhPT1iLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MJiZudWxsIT1iLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLl9faHRtbH1cbnZhciBGZj1cImZ1bmN0aW9uXCI9PT10eXBlb2Ygc2V0VGltZW91dD9zZXRUaW1lb3V0OnZvaWQgMCxHZj1cImZ1bmN0aW9uXCI9PT10eXBlb2YgY2xlYXJUaW1lb3V0P2NsZWFyVGltZW91dDp2b2lkIDAsSGY9XCJmdW5jdGlvblwiPT09dHlwZW9mIFByb21pc2U/UHJvbWlzZTp2b2lkIDAsSmY9XCJmdW5jdGlvblwiPT09dHlwZW9mIHF1ZXVlTWljcm90YXNrP3F1ZXVlTWljcm90YXNrOlwidW5kZWZpbmVkXCIhPT10eXBlb2YgSGY/ZnVuY3Rpb24oYSl7cmV0dXJuIEhmLnJlc29sdmUobnVsbCkudGhlbihhKS5jYXRjaChJZil9OkZmO2Z1bmN0aW9uIElmKGEpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXt0aHJvdyBhO30pfVxuZnVuY3Rpb24gS2YoYSxiKXt2YXIgYz1iLGQ9MDtkb3t2YXIgZT1jLm5leHRTaWJsaW5nO2EucmVtb3ZlQ2hpbGQoYyk7aWYoZSYmOD09PWUubm9kZVR5cGUpaWYoYz1lLmRhdGEsXCIvJFwiPT09Yyl7aWYoMD09PWQpe2EucmVtb3ZlQ2hpbGQoZSk7YmQoYik7cmV0dXJufWQtLX1lbHNlXCIkXCIhPT1jJiZcIiQ/XCIhPT1jJiZcIiQhXCIhPT1jfHxkKys7Yz1lfXdoaWxlKGMpO2JkKGIpfWZ1bmN0aW9uIExmKGEpe2Zvcig7bnVsbCE9YTthPWEubmV4dFNpYmxpbmcpe3ZhciBiPWEubm9kZVR5cGU7aWYoMT09PWJ8fDM9PT1iKWJyZWFrO2lmKDg9PT1iKXtiPWEuZGF0YTtpZihcIiRcIj09PWJ8fFwiJCFcIj09PWJ8fFwiJD9cIj09PWIpYnJlYWs7aWYoXCIvJFwiPT09YilyZXR1cm4gbnVsbH19cmV0dXJuIGF9XG5mdW5jdGlvbiBNZihhKXthPWEucHJldmlvdXNTaWJsaW5nO2Zvcih2YXIgYj0wO2E7KXtpZig4PT09YS5ub2RlVHlwZSl7dmFyIGM9YS5kYXRhO2lmKFwiJFwiPT09Y3x8XCIkIVwiPT09Y3x8XCIkP1wiPT09Yyl7aWYoMD09PWIpcmV0dXJuIGE7Yi0tfWVsc2VcIi8kXCI9PT1jJiZiKyt9YT1hLnByZXZpb3VzU2libGluZ31yZXR1cm4gbnVsbH12YXIgTmY9TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiksT2Y9XCJfX3JlYWN0RmliZXIkXCIrTmYsUGY9XCJfX3JlYWN0UHJvcHMkXCIrTmYsdWY9XCJfX3JlYWN0Q29udGFpbmVyJFwiK05mLG9mPVwiX19yZWFjdEV2ZW50cyRcIitOZixRZj1cIl9fcmVhY3RMaXN0ZW5lcnMkXCIrTmYsUmY9XCJfX3JlYWN0SGFuZGxlcyRcIitOZjtcbmZ1bmN0aW9uIFdjKGEpe3ZhciBiPWFbT2ZdO2lmKGIpcmV0dXJuIGI7Zm9yKHZhciBjPWEucGFyZW50Tm9kZTtjOyl7aWYoYj1jW3VmXXx8Y1tPZl0pe2M9Yi5hbHRlcm5hdGU7aWYobnVsbCE9PWIuY2hpbGR8fG51bGwhPT1jJiZudWxsIT09Yy5jaGlsZClmb3IoYT1NZihhKTtudWxsIT09YTspe2lmKGM9YVtPZl0pcmV0dXJuIGM7YT1NZihhKX1yZXR1cm4gYn1hPWM7Yz1hLnBhcmVudE5vZGV9cmV0dXJuIG51bGx9ZnVuY3Rpb24gQ2IoYSl7YT1hW09mXXx8YVt1Zl07cmV0dXJuIWF8fDUhPT1hLnRhZyYmNiE9PWEudGFnJiYxMyE9PWEudGFnJiYzIT09YS50YWc/bnVsbDphfWZ1bmN0aW9uIHVlKGEpe2lmKDU9PT1hLnRhZ3x8Nj09PWEudGFnKXJldHVybiBhLnN0YXRlTm9kZTt0aHJvdyBFcnJvcihwKDMzKSk7fWZ1bmN0aW9uIERiKGEpe3JldHVybiBhW1BmXXx8bnVsbH12YXIgU2Y9W10sVGY9LTE7ZnVuY3Rpb24gVWYoYSl7cmV0dXJue2N1cnJlbnQ6YX19XG5mdW5jdGlvbiBFKGEpezA+VGZ8fChhLmN1cnJlbnQ9U2ZbVGZdLFNmW1RmXT1udWxsLFRmLS0pfWZ1bmN0aW9uIEcoYSxiKXtUZisrO1NmW1RmXT1hLmN1cnJlbnQ7YS5jdXJyZW50PWJ9dmFyIFZmPXt9LEg9VWYoVmYpLFdmPVVmKCExKSxYZj1WZjtmdW5jdGlvbiBZZihhLGIpe3ZhciBjPWEudHlwZS5jb250ZXh0VHlwZXM7aWYoIWMpcmV0dXJuIFZmO3ZhciBkPWEuc3RhdGVOb2RlO2lmKGQmJmQuX19yZWFjdEludGVybmFsTWVtb2l6ZWRVbm1hc2tlZENoaWxkQ29udGV4dD09PWIpcmV0dXJuIGQuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNYXNrZWRDaGlsZENvbnRleHQ7dmFyIGU9e30sZjtmb3IoZiBpbiBjKWVbZl09YltmXTtkJiYoYT1hLnN0YXRlTm9kZSxhLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkVW5tYXNrZWRDaGlsZENvbnRleHQ9YixhLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWFza2VkQ2hpbGRDb250ZXh0PWUpO3JldHVybiBlfVxuZnVuY3Rpb24gWmYoYSl7YT1hLmNoaWxkQ29udGV4dFR5cGVzO3JldHVybiBudWxsIT09YSYmdm9pZCAwIT09YX1mdW5jdGlvbiAkZigpe0UoV2YpO0UoSCl9ZnVuY3Rpb24gYWcoYSxiLGMpe2lmKEguY3VycmVudCE9PVZmKXRocm93IEVycm9yKHAoMTY4KSk7RyhILGIpO0coV2YsYyl9ZnVuY3Rpb24gYmcoYSxiLGMpe3ZhciBkPWEuc3RhdGVOb2RlO2I9Yi5jaGlsZENvbnRleHRUeXBlcztpZihcImZ1bmN0aW9uXCIhPT10eXBlb2YgZC5nZXRDaGlsZENvbnRleHQpcmV0dXJuIGM7ZD1kLmdldENoaWxkQ29udGV4dCgpO2Zvcih2YXIgZSBpbiBkKWlmKCEoZSBpbiBiKSl0aHJvdyBFcnJvcihwKDEwOCxSYShhKXx8XCJVbmtub3duXCIsZSkpO3JldHVybiBBKHt9LGMsZCl9XG5mdW5jdGlvbiBjZyhhKXthPShhPWEuc3RhdGVOb2RlKSYmYS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1lcmdlZENoaWxkQ29udGV4dHx8VmY7WGY9SC5jdXJyZW50O0coSCxhKTtHKFdmLFdmLmN1cnJlbnQpO3JldHVybiEwfWZ1bmN0aW9uIGRnKGEsYixjKXt2YXIgZD1hLnN0YXRlTm9kZTtpZighZCl0aHJvdyBFcnJvcihwKDE2OSkpO2M/KGE9YmcoYSxiLFhmKSxkLl9fcmVhY3RJbnRlcm5hbE1lbW9pemVkTWVyZ2VkQ2hpbGRDb250ZXh0PWEsRShXZiksRShIKSxHKEgsYSkpOkUoV2YpO0coV2YsYyl9dmFyIGVnPW51bGwsZmc9ITEsZ2c9ITE7ZnVuY3Rpb24gaGcoYSl7bnVsbD09PWVnP2VnPVthXTplZy5wdXNoKGEpfWZ1bmN0aW9uIGlnKGEpe2ZnPSEwO2hnKGEpfVxuZnVuY3Rpb24gamcoKXtpZighZ2cmJm51bGwhPT1lZyl7Z2c9ITA7dmFyIGE9MCxiPUM7dHJ5e3ZhciBjPWVnO2ZvcihDPTE7YTxjLmxlbmd0aDthKyspe3ZhciBkPWNbYV07ZG8gZD1kKCEwKTt3aGlsZShudWxsIT09ZCl9ZWc9bnVsbDtmZz0hMX1jYXRjaChlKXt0aHJvdyBudWxsIT09ZWcmJihlZz1lZy5zbGljZShhKzEpKSxhYyhmYyxqZyksZTt9ZmluYWxseXtDPWIsZ2c9ITF9fXJldHVybiBudWxsfXZhciBrZz1bXSxsZz0wLG1nPW51bGwsbmc9MCxvZz1bXSxwZz0wLHFnPW51bGwscmc9MSxzZz1cIlwiO2Z1bmN0aW9uIHRnKGEsYil7a2dbbGcrK109bmc7a2dbbGcrK109bWc7bWc9YTtuZz1ifVxuZnVuY3Rpb24gdWcoYSxiLGMpe29nW3BnKytdPXJnO29nW3BnKytdPXNnO29nW3BnKytdPXFnO3FnPWE7dmFyIGQ9cmc7YT1zZzt2YXIgZT0zMi1vYyhkKS0xO2QmPX4oMTw8ZSk7Yys9MTt2YXIgZj0zMi1vYyhiKStlO2lmKDMwPGYpe3ZhciBnPWUtZSU1O2Y9KGQmKDE8PGcpLTEpLnRvU3RyaW5nKDMyKTtkPj49ZztlLT1nO3JnPTE8PDMyLW9jKGIpK2V8Yzw8ZXxkO3NnPWYrYX1lbHNlIHJnPTE8PGZ8Yzw8ZXxkLHNnPWF9ZnVuY3Rpb24gdmcoYSl7bnVsbCE9PWEucmV0dXJuJiYodGcoYSwxKSx1ZyhhLDEsMCkpfWZ1bmN0aW9uIHdnKGEpe2Zvcig7YT09PW1nOyltZz1rZ1stLWxnXSxrZ1tsZ109bnVsbCxuZz1rZ1stLWxnXSxrZ1tsZ109bnVsbDtmb3IoO2E9PT1xZzspcWc9b2dbLS1wZ10sb2dbcGddPW51bGwsc2c9b2dbLS1wZ10sb2dbcGddPW51bGwscmc9b2dbLS1wZ10sb2dbcGddPW51bGx9dmFyIHhnPW51bGwseWc9bnVsbCxJPSExLHpnPW51bGw7XG5mdW5jdGlvbiBBZyhhLGIpe3ZhciBjPUJnKDUsbnVsbCxudWxsLDApO2MuZWxlbWVudFR5cGU9XCJERUxFVEVEXCI7Yy5zdGF0ZU5vZGU9YjtjLnJldHVybj1hO2I9YS5kZWxldGlvbnM7bnVsbD09PWI/KGEuZGVsZXRpb25zPVtjXSxhLmZsYWdzfD0xNik6Yi5wdXNoKGMpfVxuZnVuY3Rpb24gQ2coYSxiKXtzd2l0Y2goYS50YWcpe2Nhc2UgNTp2YXIgYz1hLnR5cGU7Yj0xIT09Yi5ub2RlVHlwZXx8Yy50b0xvd2VyQ2FzZSgpIT09Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpP251bGw6YjtyZXR1cm4gbnVsbCE9PWI/KGEuc3RhdGVOb2RlPWIseGc9YSx5Zz1MZihiLmZpcnN0Q2hpbGQpLCEwKTohMTtjYXNlIDY6cmV0dXJuIGI9XCJcIj09PWEucGVuZGluZ1Byb3BzfHwzIT09Yi5ub2RlVHlwZT9udWxsOmIsbnVsbCE9PWI/KGEuc3RhdGVOb2RlPWIseGc9YSx5Zz1udWxsLCEwKTohMTtjYXNlIDEzOnJldHVybiBiPTghPT1iLm5vZGVUeXBlP251bGw6YixudWxsIT09Yj8oYz1udWxsIT09cWc/e2lkOnJnLG92ZXJmbG93OnNnfTpudWxsLGEubWVtb2l6ZWRTdGF0ZT17ZGVoeWRyYXRlZDpiLHRyZWVDb250ZXh0OmMscmV0cnlMYW5lOjEwNzM3NDE4MjR9LGM9QmcoMTgsbnVsbCxudWxsLDApLGMuc3RhdGVOb2RlPWIsYy5yZXR1cm49YSxhLmNoaWxkPWMseGc9YSx5Zz1cbm51bGwsITApOiExO2RlZmF1bHQ6cmV0dXJuITF9fWZ1bmN0aW9uIERnKGEpe3JldHVybiAwIT09KGEubW9kZSYxKSYmMD09PShhLmZsYWdzJjEyOCl9ZnVuY3Rpb24gRWcoYSl7aWYoSSl7dmFyIGI9eWc7aWYoYil7dmFyIGM9YjtpZighQ2coYSxiKSl7aWYoRGcoYSkpdGhyb3cgRXJyb3IocCg0MTgpKTtiPUxmKGMubmV4dFNpYmxpbmcpO3ZhciBkPXhnO2ImJkNnKGEsYik/QWcoZCxjKTooYS5mbGFncz1hLmZsYWdzJi00MDk3fDIsST0hMSx4Zz1hKX19ZWxzZXtpZihEZyhhKSl0aHJvdyBFcnJvcihwKDQxOCkpO2EuZmxhZ3M9YS5mbGFncyYtNDA5N3wyO0k9ITE7eGc9YX19fWZ1bmN0aW9uIEZnKGEpe2ZvcihhPWEucmV0dXJuO251bGwhPT1hJiY1IT09YS50YWcmJjMhPT1hLnRhZyYmMTMhPT1hLnRhZzspYT1hLnJldHVybjt4Zz1hfVxuZnVuY3Rpb24gR2coYSl7aWYoYSE9PXhnKXJldHVybiExO2lmKCFJKXJldHVybiBGZyhhKSxJPSEwLCExO3ZhciBiOyhiPTMhPT1hLnRhZykmJiEoYj01IT09YS50YWcpJiYoYj1hLnR5cGUsYj1cImhlYWRcIiE9PWImJlwiYm9keVwiIT09YiYmIUVmKGEudHlwZSxhLm1lbW9pemVkUHJvcHMpKTtpZihiJiYoYj15Zykpe2lmKERnKGEpKXRocm93IEhnKCksRXJyb3IocCg0MTgpKTtmb3IoO2I7KUFnKGEsYiksYj1MZihiLm5leHRTaWJsaW5nKX1GZyhhKTtpZigxMz09PWEudGFnKXthPWEubWVtb2l6ZWRTdGF0ZTthPW51bGwhPT1hP2EuZGVoeWRyYXRlZDpudWxsO2lmKCFhKXRocm93IEVycm9yKHAoMzE3KSk7YTp7YT1hLm5leHRTaWJsaW5nO2ZvcihiPTA7YTspe2lmKDg9PT1hLm5vZGVUeXBlKXt2YXIgYz1hLmRhdGE7aWYoXCIvJFwiPT09Yyl7aWYoMD09PWIpe3lnPUxmKGEubmV4dFNpYmxpbmcpO2JyZWFrIGF9Yi0tfWVsc2VcIiRcIiE9PWMmJlwiJCFcIiE9PWMmJlwiJD9cIiE9PWN8fGIrK31hPWEubmV4dFNpYmxpbmd9eWc9XG5udWxsfX1lbHNlIHlnPXhnP0xmKGEuc3RhdGVOb2RlLm5leHRTaWJsaW5nKTpudWxsO3JldHVybiEwfWZ1bmN0aW9uIEhnKCl7Zm9yKHZhciBhPXlnO2E7KWE9TGYoYS5uZXh0U2libGluZyl9ZnVuY3Rpb24gSWcoKXt5Zz14Zz1udWxsO0k9ITF9ZnVuY3Rpb24gSmcoYSl7bnVsbD09PXpnP3pnPVthXTp6Zy5wdXNoKGEpfXZhciBLZz11YS5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZztmdW5jdGlvbiBMZyhhLGIpe2lmKGEmJmEuZGVmYXVsdFByb3BzKXtiPUEoe30sYik7YT1hLmRlZmF1bHRQcm9wcztmb3IodmFyIGMgaW4gYSl2b2lkIDA9PT1iW2NdJiYoYltjXT1hW2NdKTtyZXR1cm4gYn1yZXR1cm4gYn12YXIgTWc9VWYobnVsbCksTmc9bnVsbCxPZz1udWxsLFBnPW51bGw7ZnVuY3Rpb24gUWcoKXtQZz1PZz1OZz1udWxsfWZ1bmN0aW9uIFJnKGEpe3ZhciBiPU1nLmN1cnJlbnQ7RShNZyk7YS5fY3VycmVudFZhbHVlPWJ9XG5mdW5jdGlvbiBTZyhhLGIsYyl7Zm9yKDtudWxsIT09YTspe3ZhciBkPWEuYWx0ZXJuYXRlOyhhLmNoaWxkTGFuZXMmYikhPT1iPyhhLmNoaWxkTGFuZXN8PWIsbnVsbCE9PWQmJihkLmNoaWxkTGFuZXN8PWIpKTpudWxsIT09ZCYmKGQuY2hpbGRMYW5lcyZiKSE9PWImJihkLmNoaWxkTGFuZXN8PWIpO2lmKGE9PT1jKWJyZWFrO2E9YS5yZXR1cm59fWZ1bmN0aW9uIFRnKGEsYil7Tmc9YTtQZz1PZz1udWxsO2E9YS5kZXBlbmRlbmNpZXM7bnVsbCE9PWEmJm51bGwhPT1hLmZpcnN0Q29udGV4dCYmKDAhPT0oYS5sYW5lcyZiKSYmKFVnPSEwKSxhLmZpcnN0Q29udGV4dD1udWxsKX1cbmZ1bmN0aW9uIFZnKGEpe3ZhciBiPWEuX2N1cnJlbnRWYWx1ZTtpZihQZyE9PWEpaWYoYT17Y29udGV4dDphLG1lbW9pemVkVmFsdWU6YixuZXh0Om51bGx9LG51bGw9PT1PZyl7aWYobnVsbD09PU5nKXRocm93IEVycm9yKHAoMzA4KSk7T2c9YTtOZy5kZXBlbmRlbmNpZXM9e2xhbmVzOjAsZmlyc3RDb250ZXh0OmF9fWVsc2UgT2c9T2cubmV4dD1hO3JldHVybiBifXZhciBXZz1udWxsO2Z1bmN0aW9uIFhnKGEpe251bGw9PT1XZz9XZz1bYV06V2cucHVzaChhKX1mdW5jdGlvbiBZZyhhLGIsYyxkKXt2YXIgZT1iLmludGVybGVhdmVkO251bGw9PT1lPyhjLm5leHQ9YyxYZyhiKSk6KGMubmV4dD1lLm5leHQsZS5uZXh0PWMpO2IuaW50ZXJsZWF2ZWQ9YztyZXR1cm4gWmcoYSxkKX1cbmZ1bmN0aW9uIFpnKGEsYil7YS5sYW5lc3w9Yjt2YXIgYz1hLmFsdGVybmF0ZTtudWxsIT09YyYmKGMubGFuZXN8PWIpO2M9YTtmb3IoYT1hLnJldHVybjtudWxsIT09YTspYS5jaGlsZExhbmVzfD1iLGM9YS5hbHRlcm5hdGUsbnVsbCE9PWMmJihjLmNoaWxkTGFuZXN8PWIpLGM9YSxhPWEucmV0dXJuO3JldHVybiAzPT09Yy50YWc/Yy5zdGF0ZU5vZGU6bnVsbH12YXIgJGc9ITE7ZnVuY3Rpb24gYWgoYSl7YS51cGRhdGVRdWV1ZT17YmFzZVN0YXRlOmEubWVtb2l6ZWRTdGF0ZSxmaXJzdEJhc2VVcGRhdGU6bnVsbCxsYXN0QmFzZVVwZGF0ZTpudWxsLHNoYXJlZDp7cGVuZGluZzpudWxsLGludGVybGVhdmVkOm51bGwsbGFuZXM6MH0sZWZmZWN0czpudWxsfX1cbmZ1bmN0aW9uIGJoKGEsYil7YT1hLnVwZGF0ZVF1ZXVlO2IudXBkYXRlUXVldWU9PT1hJiYoYi51cGRhdGVRdWV1ZT17YmFzZVN0YXRlOmEuYmFzZVN0YXRlLGZpcnN0QmFzZVVwZGF0ZTphLmZpcnN0QmFzZVVwZGF0ZSxsYXN0QmFzZVVwZGF0ZTphLmxhc3RCYXNlVXBkYXRlLHNoYXJlZDphLnNoYXJlZCxlZmZlY3RzOmEuZWZmZWN0c30pfWZ1bmN0aW9uIGNoKGEsYil7cmV0dXJue2V2ZW50VGltZTphLGxhbmU6Yix0YWc6MCxwYXlsb2FkOm51bGwsY2FsbGJhY2s6bnVsbCxuZXh0Om51bGx9fVxuZnVuY3Rpb24gZGgoYSxiLGMpe3ZhciBkPWEudXBkYXRlUXVldWU7aWYobnVsbD09PWQpcmV0dXJuIG51bGw7ZD1kLnNoYXJlZDtpZigwIT09KEsmMikpe3ZhciBlPWQucGVuZGluZztudWxsPT09ZT9iLm5leHQ9YjooYi5uZXh0PWUubmV4dCxlLm5leHQ9Yik7ZC5wZW5kaW5nPWI7cmV0dXJuIFpnKGEsYyl9ZT1kLmludGVybGVhdmVkO251bGw9PT1lPyhiLm5leHQ9YixYZyhkKSk6KGIubmV4dD1lLm5leHQsZS5uZXh0PWIpO2QuaW50ZXJsZWF2ZWQ9YjtyZXR1cm4gWmcoYSxjKX1mdW5jdGlvbiBlaChhLGIsYyl7Yj1iLnVwZGF0ZVF1ZXVlO2lmKG51bGwhPT1iJiYoYj1iLnNoYXJlZCwwIT09KGMmNDE5NDI0MCkpKXt2YXIgZD1iLmxhbmVzO2QmPWEucGVuZGluZ0xhbmVzO2N8PWQ7Yi5sYW5lcz1jO0NjKGEsYyl9fVxuZnVuY3Rpb24gZmgoYSxiKXt2YXIgYz1hLnVwZGF0ZVF1ZXVlLGQ9YS5hbHRlcm5hdGU7aWYobnVsbCE9PWQmJihkPWQudXBkYXRlUXVldWUsYz09PWQpKXt2YXIgZT1udWxsLGY9bnVsbDtjPWMuZmlyc3RCYXNlVXBkYXRlO2lmKG51bGwhPT1jKXtkb3t2YXIgZz17ZXZlbnRUaW1lOmMuZXZlbnRUaW1lLGxhbmU6Yy5sYW5lLHRhZzpjLnRhZyxwYXlsb2FkOmMucGF5bG9hZCxjYWxsYmFjazpjLmNhbGxiYWNrLG5leHQ6bnVsbH07bnVsbD09PWY/ZT1mPWc6Zj1mLm5leHQ9ZztjPWMubmV4dH13aGlsZShudWxsIT09Yyk7bnVsbD09PWY/ZT1mPWI6Zj1mLm5leHQ9Yn1lbHNlIGU9Zj1iO2M9e2Jhc2VTdGF0ZTpkLmJhc2VTdGF0ZSxmaXJzdEJhc2VVcGRhdGU6ZSxsYXN0QmFzZVVwZGF0ZTpmLHNoYXJlZDpkLnNoYXJlZCxlZmZlY3RzOmQuZWZmZWN0c307YS51cGRhdGVRdWV1ZT1jO3JldHVybn1hPWMubGFzdEJhc2VVcGRhdGU7bnVsbD09PWE/Yy5maXJzdEJhc2VVcGRhdGU9YjphLm5leHQ9XG5iO2MubGFzdEJhc2VVcGRhdGU9Yn1cbmZ1bmN0aW9uIGdoKGEsYixjLGQpe3ZhciBlPWEudXBkYXRlUXVldWU7JGc9ITE7dmFyIGY9ZS5maXJzdEJhc2VVcGRhdGUsZz1lLmxhc3RCYXNlVXBkYXRlLGg9ZS5zaGFyZWQucGVuZGluZztpZihudWxsIT09aCl7ZS5zaGFyZWQucGVuZGluZz1udWxsO3ZhciBrPWgsbD1rLm5leHQ7ay5uZXh0PW51bGw7bnVsbD09PWc/Zj1sOmcubmV4dD1sO2c9azt2YXIgbT1hLmFsdGVybmF0ZTtudWxsIT09bSYmKG09bS51cGRhdGVRdWV1ZSxoPW0ubGFzdEJhc2VVcGRhdGUsaCE9PWcmJihudWxsPT09aD9tLmZpcnN0QmFzZVVwZGF0ZT1sOmgubmV4dD1sLG0ubGFzdEJhc2VVcGRhdGU9aykpfWlmKG51bGwhPT1mKXt2YXIgcT1lLmJhc2VTdGF0ZTtnPTA7bT1sPWs9bnVsbDtoPWY7ZG97dmFyIHI9aC5sYW5lLHk9aC5ldmVudFRpbWU7aWYoKGQmcik9PT1yKXtudWxsIT09bSYmKG09bS5uZXh0PXtldmVudFRpbWU6eSxsYW5lOjAsdGFnOmgudGFnLHBheWxvYWQ6aC5wYXlsb2FkLGNhbGxiYWNrOmguY2FsbGJhY2ssXG5uZXh0Om51bGx9KTthOnt2YXIgbj1hLHQ9aDtyPWI7eT1jO3N3aXRjaCh0LnRhZyl7Y2FzZSAxOm49dC5wYXlsb2FkO2lmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBuKXtxPW4uY2FsbCh5LHEscik7YnJlYWsgYX1xPW47YnJlYWsgYTtjYXNlIDM6bi5mbGFncz1uLmZsYWdzJi02NTUzN3wxMjg7Y2FzZSAwOm49dC5wYXlsb2FkO3I9XCJmdW5jdGlvblwiPT09dHlwZW9mIG4/bi5jYWxsKHkscSxyKTpuO2lmKG51bGw9PT1yfHx2b2lkIDA9PT1yKWJyZWFrIGE7cT1BKHt9LHEscik7YnJlYWsgYTtjYXNlIDI6JGc9ITB9fW51bGwhPT1oLmNhbGxiYWNrJiYwIT09aC5sYW5lJiYoYS5mbGFnc3w9NjQscj1lLmVmZmVjdHMsbnVsbD09PXI/ZS5lZmZlY3RzPVtoXTpyLnB1c2goaCkpfWVsc2UgeT17ZXZlbnRUaW1lOnksbGFuZTpyLHRhZzpoLnRhZyxwYXlsb2FkOmgucGF5bG9hZCxjYWxsYmFjazpoLmNhbGxiYWNrLG5leHQ6bnVsbH0sbnVsbD09PW0/KGw9bT15LGs9cSk6bT1tLm5leHQ9eSxnfD1yO1xuaD1oLm5leHQ7aWYobnVsbD09PWgpaWYoaD1lLnNoYXJlZC5wZW5kaW5nLG51bGw9PT1oKWJyZWFrO2Vsc2Ugcj1oLGg9ci5uZXh0LHIubmV4dD1udWxsLGUubGFzdEJhc2VVcGRhdGU9cixlLnNoYXJlZC5wZW5kaW5nPW51bGx9d2hpbGUoMSk7bnVsbD09PW0mJihrPXEpO2UuYmFzZVN0YXRlPWs7ZS5maXJzdEJhc2VVcGRhdGU9bDtlLmxhc3RCYXNlVXBkYXRlPW07Yj1lLnNoYXJlZC5pbnRlcmxlYXZlZDtpZihudWxsIT09Yil7ZT1iO2RvIGd8PWUubGFuZSxlPWUubmV4dDt3aGlsZShlIT09Yil9ZWxzZSBudWxsPT09ZiYmKGUuc2hhcmVkLmxhbmVzPTApO2hofD1nO2EubGFuZXM9ZzthLm1lbW9pemVkU3RhdGU9cX19XG5mdW5jdGlvbiBpaChhLGIsYyl7YT1iLmVmZmVjdHM7Yi5lZmZlY3RzPW51bGw7aWYobnVsbCE9PWEpZm9yKGI9MDtiPGEubGVuZ3RoO2IrKyl7dmFyIGQ9YVtiXSxlPWQuY2FsbGJhY2s7aWYobnVsbCE9PWUpe2QuY2FsbGJhY2s9bnVsbDtkPWM7aWYoXCJmdW5jdGlvblwiIT09dHlwZW9mIGUpdGhyb3cgRXJyb3IocCgxOTEsZSkpO2UuY2FsbChkKX19fXZhciBqaD0obmV3IGFhLkNvbXBvbmVudCkucmVmcztmdW5jdGlvbiBraChhLGIsYyxkKXtiPWEubWVtb2l6ZWRTdGF0ZTtjPWMoZCxiKTtjPW51bGw9PT1jfHx2b2lkIDA9PT1jP2I6QSh7fSxiLGMpO2EubWVtb2l6ZWRTdGF0ZT1jOzA9PT1hLmxhbmVzJiYoYS51cGRhdGVRdWV1ZS5iYXNlU3RhdGU9Yyl9XG52YXIgbmg9e2lzTW91bnRlZDpmdW5jdGlvbihhKXtyZXR1cm4oYT1hLl9yZWFjdEludGVybmFscyk/VmIoYSk9PT1hOiExfSxlbnF1ZXVlU2V0U3RhdGU6ZnVuY3Rpb24oYSxiLGMpe2E9YS5fcmVhY3RJbnRlcm5hbHM7dmFyIGQ9TCgpLGU9bGgoYSksZj1jaChkLGUpO2YucGF5bG9hZD1iO3ZvaWQgMCE9PWMmJm51bGwhPT1jJiYoZi5jYWxsYmFjaz1jKTtiPWRoKGEsZixlKTtudWxsIT09YiYmKG1oKGIsYSxlLGQpLGVoKGIsYSxlKSl9LGVucXVldWVSZXBsYWNlU3RhdGU6ZnVuY3Rpb24oYSxiLGMpe2E9YS5fcmVhY3RJbnRlcm5hbHM7dmFyIGQ9TCgpLGU9bGgoYSksZj1jaChkLGUpO2YudGFnPTE7Zi5wYXlsb2FkPWI7dm9pZCAwIT09YyYmbnVsbCE9PWMmJihmLmNhbGxiYWNrPWMpO2I9ZGgoYSxmLGUpO251bGwhPT1iJiYobWgoYixhLGUsZCksZWgoYixhLGUpKX0sZW5xdWV1ZUZvcmNlVXBkYXRlOmZ1bmN0aW9uKGEsYil7YT1hLl9yZWFjdEludGVybmFsczt2YXIgYz1MKCksZD1cbmxoKGEpLGU9Y2goYyxkKTtlLnRhZz0yO3ZvaWQgMCE9PWImJm51bGwhPT1iJiYoZS5jYWxsYmFjaz1iKTtiPWRoKGEsZSxkKTtudWxsIT09YiYmKG1oKGIsYSxkLGMpLGVoKGIsYSxkKSl9fTtmdW5jdGlvbiBvaChhLGIsYyxkLGUsZixnKXthPWEuc3RhdGVOb2RlO3JldHVyblwiZnVuY3Rpb25cIj09PXR5cGVvZiBhLnNob3VsZENvbXBvbmVudFVwZGF0ZT9hLnNob3VsZENvbXBvbmVudFVwZGF0ZShkLGYsZyk6Yi5wcm90b3R5cGUmJmIucHJvdG90eXBlLmlzUHVyZVJlYWN0Q29tcG9uZW50PyFJZShjLGQpfHwhSWUoZSxmKTohMH1cbmZ1bmN0aW9uIHBoKGEsYixjKXt2YXIgZD0hMSxlPVZmO3ZhciBmPWIuY29udGV4dFR5cGU7XCJvYmplY3RcIj09PXR5cGVvZiBmJiZudWxsIT09Zj9mPVZnKGYpOihlPVpmKGIpP1hmOkguY3VycmVudCxkPWIuY29udGV4dFR5cGVzLGY9KGQ9bnVsbCE9PWQmJnZvaWQgMCE9PWQpP1lmKGEsZSk6VmYpO2I9bmV3IGIoYyxmKTthLm1lbW9pemVkU3RhdGU9bnVsbCE9PWIuc3RhdGUmJnZvaWQgMCE9PWIuc3RhdGU/Yi5zdGF0ZTpudWxsO2IudXBkYXRlcj1uaDthLnN0YXRlTm9kZT1iO2IuX3JlYWN0SW50ZXJuYWxzPWE7ZCYmKGE9YS5zdGF0ZU5vZGUsYS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZFVubWFza2VkQ2hpbGRDb250ZXh0PWUsYS5fX3JlYWN0SW50ZXJuYWxNZW1vaXplZE1hc2tlZENoaWxkQ29udGV4dD1mKTtyZXR1cm4gYn1cbmZ1bmN0aW9uIHFoKGEsYixjLGQpe2E9Yi5zdGF0ZTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJiZiLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMoYyxkKTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyYmYi5VTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhjLGQpO2Iuc3RhdGUhPT1hJiZuaC5lbnF1ZXVlUmVwbGFjZVN0YXRlKGIsYi5zdGF0ZSxudWxsKX1cbmZ1bmN0aW9uIHJoKGEsYixjLGQpe3ZhciBlPWEuc3RhdGVOb2RlO2UucHJvcHM9YztlLnN0YXRlPWEubWVtb2l6ZWRTdGF0ZTtlLnJlZnM9amg7YWgoYSk7dmFyIGY9Yi5jb250ZXh0VHlwZTtcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mP2UuY29udGV4dD1WZyhmKTooZj1aZihiKT9YZjpILmN1cnJlbnQsZS5jb250ZXh0PVlmKGEsZikpO2Uuc3RhdGU9YS5tZW1vaXplZFN0YXRlO2Y9Yi5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHM7XCJmdW5jdGlvblwiPT09dHlwZW9mIGYmJihraChhLGIsZixjKSxlLnN0YXRlPWEubWVtb2l6ZWRTdGF0ZSk7XCJmdW5jdGlvblwiPT09dHlwZW9mIGIuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzfHxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZXx8XCJmdW5jdGlvblwiIT09dHlwZW9mIGUuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCYmXCJmdW5jdGlvblwiIT09dHlwZW9mIGUuY29tcG9uZW50V2lsbE1vdW50fHwoYj1lLnN0YXRlLFxuXCJmdW5jdGlvblwiPT09dHlwZW9mIGUuY29tcG9uZW50V2lsbE1vdW50JiZlLmNvbXBvbmVudFdpbGxNb3VudCgpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBlLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQmJmUuVU5TQUZFX2NvbXBvbmVudFdpbGxNb3VudCgpLGIhPT1lLnN0YXRlJiZuaC5lbnF1ZXVlUmVwbGFjZVN0YXRlKGUsZS5zdGF0ZSxudWxsKSxnaChhLGMsZSxkKSxlLnN0YXRlPWEubWVtb2l6ZWRTdGF0ZSk7XCJmdW5jdGlvblwiPT09dHlwZW9mIGUuY29tcG9uZW50RGlkTW91bnQmJihhLmZsYWdzfD00MTk0MzA4KX1cbmZ1bmN0aW9uIHNoKGEsYixjKXthPWMucmVmO2lmKG51bGwhPT1hJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgYSYmXCJvYmplY3RcIiE9PXR5cGVvZiBhKXtpZihjLl9vd25lcil7Yz1jLl9vd25lcjtpZihjKXtpZigxIT09Yy50YWcpdGhyb3cgRXJyb3IocCgzMDkpKTt2YXIgZD1jLnN0YXRlTm9kZX1pZighZCl0aHJvdyBFcnJvcihwKDE0NyxhKSk7dmFyIGU9ZCxmPVwiXCIrYTtpZihudWxsIT09YiYmbnVsbCE9PWIucmVmJiZcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi5yZWYmJmIucmVmLl9zdHJpbmdSZWY9PT1mKXJldHVybiBiLnJlZjtiPWZ1bmN0aW9uKGEpe3ZhciBiPWUucmVmcztiPT09amgmJihiPWUucmVmcz17fSk7bnVsbD09PWE/ZGVsZXRlIGJbZl06YltmXT1hfTtiLl9zdHJpbmdSZWY9ZjtyZXR1cm4gYn1pZihcInN0cmluZ1wiIT09dHlwZW9mIGEpdGhyb3cgRXJyb3IocCgyODQpKTtpZighYy5fb3duZXIpdGhyb3cgRXJyb3IocCgyOTAsYSkpO31yZXR1cm4gYX1cbmZ1bmN0aW9uIHRoKGEsYil7YT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYik7dGhyb3cgRXJyb3IocCgzMSxcIltvYmplY3QgT2JqZWN0XVwiPT09YT9cIm9iamVjdCB3aXRoIGtleXMge1wiK09iamVjdC5rZXlzKGIpLmpvaW4oXCIsIFwiKStcIn1cIjphKSk7fWZ1bmN0aW9uIHVoKGEpe3ZhciBiPWEuX2luaXQ7cmV0dXJuIGIoYS5fcGF5bG9hZCl9XG5mdW5jdGlvbiB2aChhKXtmdW5jdGlvbiBiKGIsYyl7aWYoYSl7dmFyIGQ9Yi5kZWxldGlvbnM7bnVsbD09PWQ/KGIuZGVsZXRpb25zPVtjXSxiLmZsYWdzfD0xNik6ZC5wdXNoKGMpfX1mdW5jdGlvbiBjKGMsZCl7aWYoIWEpcmV0dXJuIG51bGw7Zm9yKDtudWxsIT09ZDspYihjLGQpLGQ9ZC5zaWJsaW5nO3JldHVybiBudWxsfWZ1bmN0aW9uIGQoYSxiKXtmb3IoYT1uZXcgTWFwO251bGwhPT1iOyludWxsIT09Yi5rZXk/YS5zZXQoYi5rZXksYik6YS5zZXQoYi5pbmRleCxiKSxiPWIuc2libGluZztyZXR1cm4gYX1mdW5jdGlvbiBlKGEsYil7YT13aChhLGIpO2EuaW5kZXg9MDthLnNpYmxpbmc9bnVsbDtyZXR1cm4gYX1mdW5jdGlvbiBmKGIsYyxkKXtiLmluZGV4PWQ7aWYoIWEpcmV0dXJuIGIuZmxhZ3N8PTEwNDg1NzYsYztkPWIuYWx0ZXJuYXRlO2lmKG51bGwhPT1kKXJldHVybiBkPWQuaW5kZXgsZDxjPyhiLmZsYWdzfD0yLGMpOmQ7Yi5mbGFnc3w9MjtyZXR1cm4gY31mdW5jdGlvbiBnKGIpe2EmJlxubnVsbD09PWIuYWx0ZXJuYXRlJiYoYi5mbGFnc3w9Mik7cmV0dXJuIGJ9ZnVuY3Rpb24gaChhLGIsYyxkKXtpZihudWxsPT09Ynx8NiE9PWIudGFnKXJldHVybiBiPXhoKGMsYS5tb2RlLGQpLGIucmV0dXJuPWEsYjtiPWUoYixjKTtiLnJldHVybj1hO3JldHVybiBifWZ1bmN0aW9uIGsoYSxiLGMsZCl7dmFyIGY9Yy50eXBlO2lmKGY9PT15YSlyZXR1cm4gbShhLGIsYy5wcm9wcy5jaGlsZHJlbixkLGMua2V5KTtpZihudWxsIT09YiYmKGIuZWxlbWVudFR5cGU9PT1mfHxcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mJiZmLiQkdHlwZW9mPT09SGEmJnVoKGYpPT09Yi50eXBlKSlyZXR1cm4gZD1lKGIsYy5wcm9wcyksZC5yZWY9c2goYSxiLGMpLGQucmV0dXJuPWEsZDtkPXloKGMudHlwZSxjLmtleSxjLnByb3BzLG51bGwsYS5tb2RlLGQpO2QucmVmPXNoKGEsYixjKTtkLnJldHVybj1hO3JldHVybiBkfWZ1bmN0aW9uIGwoYSxiLGMsZCl7aWYobnVsbD09PWJ8fDQhPT1iLnRhZ3x8XG5iLnN0YXRlTm9kZS5jb250YWluZXJJbmZvIT09Yy5jb250YWluZXJJbmZvfHxiLnN0YXRlTm9kZS5pbXBsZW1lbnRhdGlvbiE9PWMuaW1wbGVtZW50YXRpb24pcmV0dXJuIGI9emgoYyxhLm1vZGUsZCksYi5yZXR1cm49YSxiO2I9ZShiLGMuY2hpbGRyZW58fFtdKTtiLnJldHVybj1hO3JldHVybiBifWZ1bmN0aW9uIG0oYSxiLGMsZCxmKXtpZihudWxsPT09Ynx8NyE9PWIudGFnKXJldHVybiBiPUFoKGMsYS5tb2RlLGQsZiksYi5yZXR1cm49YSxiO2I9ZShiLGMpO2IucmV0dXJuPWE7cmV0dXJuIGJ9ZnVuY3Rpb24gcShhLGIsYyl7aWYoXCJzdHJpbmdcIj09PXR5cGVvZiBiJiZcIlwiIT09Ynx8XCJudW1iZXJcIj09PXR5cGVvZiBiKXJldHVybiBiPXhoKFwiXCIrYixhLm1vZGUsYyksYi5yZXR1cm49YSxiO2lmKFwib2JqZWN0XCI9PT10eXBlb2YgYiYmbnVsbCE9PWIpe3N3aXRjaChiLiQkdHlwZW9mKXtjYXNlIHZhOnJldHVybiBjPXloKGIudHlwZSxiLmtleSxiLnByb3BzLG51bGwsYS5tb2RlLGMpLFxuYy5yZWY9c2goYSxudWxsLGIpLGMucmV0dXJuPWEsYztjYXNlIHdhOnJldHVybiBiPXpoKGIsYS5tb2RlLGMpLGIucmV0dXJuPWEsYjtjYXNlIEhhOnZhciBkPWIuX2luaXQ7cmV0dXJuIHEoYSxkKGIuX3BheWxvYWQpLGMpfWlmKGViKGIpfHxLYShiKSlyZXR1cm4gYj1BaChiLGEubW9kZSxjLG51bGwpLGIucmV0dXJuPWEsYjt0aChhLGIpfXJldHVybiBudWxsfWZ1bmN0aW9uIHIoYSxiLGMsZCl7dmFyIGU9bnVsbCE9PWI/Yi5rZXk6bnVsbDtpZihcInN0cmluZ1wiPT09dHlwZW9mIGMmJlwiXCIhPT1jfHxcIm51bWJlclwiPT09dHlwZW9mIGMpcmV0dXJuIG51bGwhPT1lP251bGw6aChhLGIsXCJcIitjLGQpO2lmKFwib2JqZWN0XCI9PT10eXBlb2YgYyYmbnVsbCE9PWMpe3N3aXRjaChjLiQkdHlwZW9mKXtjYXNlIHZhOnJldHVybiBjLmtleT09PWU/ayhhLGIsYyxkKTpudWxsO2Nhc2Ugd2E6cmV0dXJuIGMua2V5PT09ZT9sKGEsYixjLGQpOm51bGw7Y2FzZSBIYTpyZXR1cm4gZT1jLl9pbml0LHIoYSxcbmIsZShjLl9wYXlsb2FkKSxkKX1pZihlYihjKXx8S2EoYykpcmV0dXJuIG51bGwhPT1lP251bGw6bShhLGIsYyxkLG51bGwpO3RoKGEsYyl9cmV0dXJuIG51bGx9ZnVuY3Rpb24geShhLGIsYyxkLGUpe2lmKFwic3RyaW5nXCI9PT10eXBlb2YgZCYmXCJcIiE9PWR8fFwibnVtYmVyXCI9PT10eXBlb2YgZClyZXR1cm4gYT1hLmdldChjKXx8bnVsbCxoKGIsYSxcIlwiK2QsZSk7aWYoXCJvYmplY3RcIj09PXR5cGVvZiBkJiZudWxsIT09ZCl7c3dpdGNoKGQuJCR0eXBlb2Ype2Nhc2UgdmE6cmV0dXJuIGE9YS5nZXQobnVsbD09PWQua2V5P2M6ZC5rZXkpfHxudWxsLGsoYixhLGQsZSk7Y2FzZSB3YTpyZXR1cm4gYT1hLmdldChudWxsPT09ZC5rZXk/YzpkLmtleSl8fG51bGwsbChiLGEsZCxlKTtjYXNlIEhhOnZhciBmPWQuX2luaXQ7cmV0dXJuIHkoYSxiLGMsZihkLl9wYXlsb2FkKSxlKX1pZihlYihkKXx8S2EoZCkpcmV0dXJuIGE9YS5nZXQoYyl8fG51bGwsbShiLGEsZCxlLG51bGwpO3RoKGIsZCl9cmV0dXJuIG51bGx9XG5mdW5jdGlvbiBuKGUsZyxoLGspe2Zvcih2YXIgbD1udWxsLG09bnVsbCx1PWcsdz1nPTAseD1udWxsO251bGwhPT11JiZ3PGgubGVuZ3RoO3crKyl7dS5pbmRleD53Pyh4PXUsdT1udWxsKTp4PXUuc2libGluZzt2YXIgbj1yKGUsdSxoW3ddLGspO2lmKG51bGw9PT1uKXtudWxsPT09dSYmKHU9eCk7YnJlYWt9YSYmdSYmbnVsbD09PW4uYWx0ZXJuYXRlJiZiKGUsdSk7Zz1mKG4sZyx3KTtudWxsPT09bT9sPW46bS5zaWJsaW5nPW47bT1uO3U9eH1pZih3PT09aC5sZW5ndGgpcmV0dXJuIGMoZSx1KSxJJiZ0ZyhlLHcpLGw7aWYobnVsbD09PXUpe2Zvcig7dzxoLmxlbmd0aDt3KyspdT1xKGUsaFt3XSxrKSxudWxsIT09dSYmKGc9Zih1LGcsdyksbnVsbD09PW0/bD11Om0uc2libGluZz11LG09dSk7SSYmdGcoZSx3KTtyZXR1cm4gbH1mb3IodT1kKGUsdSk7dzxoLmxlbmd0aDt3KyspeD15KHUsZSx3LGhbd10sayksbnVsbCE9PXgmJihhJiZudWxsIT09eC5hbHRlcm5hdGUmJnUuZGVsZXRlKG51bGw9PT1cbngua2V5P3c6eC5rZXkpLGc9Zih4LGcsdyksbnVsbD09PW0/bD14Om0uc2libGluZz14LG09eCk7YSYmdS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3JldHVybiBiKGUsYSl9KTtJJiZ0ZyhlLHcpO3JldHVybiBsfWZ1bmN0aW9uIHQoZSxnLGgsayl7dmFyIGw9S2EoaCk7aWYoXCJmdW5jdGlvblwiIT09dHlwZW9mIGwpdGhyb3cgRXJyb3IocCgxNTApKTtoPWwuY2FsbChoKTtpZihudWxsPT1oKXRocm93IEVycm9yKHAoMTUxKSk7Zm9yKHZhciB1PWw9bnVsbCxtPWcsdz1nPTAseD1udWxsLG49aC5uZXh0KCk7bnVsbCE9PW0mJiFuLmRvbmU7dysrLG49aC5uZXh0KCkpe20uaW5kZXg+dz8oeD1tLG09bnVsbCk6eD1tLnNpYmxpbmc7dmFyIHQ9cihlLG0sbi52YWx1ZSxrKTtpZihudWxsPT09dCl7bnVsbD09PW0mJihtPXgpO2JyZWFrfWEmJm0mJm51bGw9PT10LmFsdGVybmF0ZSYmYihlLG0pO2c9Zih0LGcsdyk7bnVsbD09PXU/bD10OnUuc2libGluZz10O3U9dDttPXh9aWYobi5kb25lKXJldHVybiBjKGUsXG5tKSxJJiZ0ZyhlLHcpLGw7aWYobnVsbD09PW0pe2Zvcig7IW4uZG9uZTt3Kyssbj1oLm5leHQoKSluPXEoZSxuLnZhbHVlLGspLG51bGwhPT1uJiYoZz1mKG4sZyx3KSxudWxsPT09dT9sPW46dS5zaWJsaW5nPW4sdT1uKTtJJiZ0ZyhlLHcpO3JldHVybiBsfWZvcihtPWQoZSxtKTshbi5kb25lO3crKyxuPWgubmV4dCgpKW49eShtLGUsdyxuLnZhbHVlLGspLG51bGwhPT1uJiYoYSYmbnVsbCE9PW4uYWx0ZXJuYXRlJiZtLmRlbGV0ZShudWxsPT09bi5rZXk/dzpuLmtleSksZz1mKG4sZyx3KSxudWxsPT09dT9sPW46dS5zaWJsaW5nPW4sdT1uKTthJiZtLmZvckVhY2goZnVuY3Rpb24oYSl7cmV0dXJuIGIoZSxhKX0pO0kmJnRnKGUsdyk7cmV0dXJuIGx9ZnVuY3Rpb24gSihhLGQsZixoKXtcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mJiZmLnR5cGU9PT15YSYmbnVsbD09PWYua2V5JiYoZj1mLnByb3BzLmNoaWxkcmVuKTtpZihcIm9iamVjdFwiPT09dHlwZW9mIGYmJm51bGwhPT1mKXtzd2l0Y2goZi4kJHR5cGVvZil7Y2FzZSB2YTphOntmb3IodmFyIGs9XG5mLmtleSxsPWQ7bnVsbCE9PWw7KXtpZihsLmtleT09PWspe2s9Zi50eXBlO2lmKGs9PT15YSl7aWYoNz09PWwudGFnKXtjKGEsbC5zaWJsaW5nKTtkPWUobCxmLnByb3BzLmNoaWxkcmVuKTtkLnJldHVybj1hO2E9ZDticmVhayBhfX1lbHNlIGlmKGwuZWxlbWVudFR5cGU9PT1rfHxcIm9iamVjdFwiPT09dHlwZW9mIGsmJm51bGwhPT1rJiZrLiQkdHlwZW9mPT09SGEmJnVoKGspPT09bC50eXBlKXtjKGEsbC5zaWJsaW5nKTtkPWUobCxmLnByb3BzKTtkLnJlZj1zaChhLGwsZik7ZC5yZXR1cm49YTthPWQ7YnJlYWsgYX1jKGEsbCk7YnJlYWt9ZWxzZSBiKGEsbCk7bD1sLnNpYmxpbmd9Zi50eXBlPT09eWE/KGQ9QWgoZi5wcm9wcy5jaGlsZHJlbixhLm1vZGUsaCxmLmtleSksZC5yZXR1cm49YSxhPWQpOihoPXloKGYudHlwZSxmLmtleSxmLnByb3BzLG51bGwsYS5tb2RlLGgpLGgucmVmPXNoKGEsZCxmKSxoLnJldHVybj1hLGE9aCl9cmV0dXJuIGcoYSk7Y2FzZSB3YTphOntmb3IobD1mLmtleTtudWxsIT09XG5kOyl7aWYoZC5rZXk9PT1sKWlmKDQ9PT1kLnRhZyYmZC5zdGF0ZU5vZGUuY29udGFpbmVySW5mbz09PWYuY29udGFpbmVySW5mbyYmZC5zdGF0ZU5vZGUuaW1wbGVtZW50YXRpb249PT1mLmltcGxlbWVudGF0aW9uKXtjKGEsZC5zaWJsaW5nKTtkPWUoZCxmLmNoaWxkcmVufHxbXSk7ZC5yZXR1cm49YTthPWQ7YnJlYWsgYX1lbHNle2MoYSxkKTticmVha31lbHNlIGIoYSxkKTtkPWQuc2libGluZ31kPXpoKGYsYS5tb2RlLGgpO2QucmV0dXJuPWE7YT1kfXJldHVybiBnKGEpO2Nhc2UgSGE6cmV0dXJuIGw9Zi5faW5pdCxKKGEsZCxsKGYuX3BheWxvYWQpLGgpfWlmKGViKGYpKXJldHVybiBuKGEsZCxmLGgpO2lmKEthKGYpKXJldHVybiB0KGEsZCxmLGgpO3RoKGEsZil9cmV0dXJuXCJzdHJpbmdcIj09PXR5cGVvZiBmJiZcIlwiIT09Znx8XCJudW1iZXJcIj09PXR5cGVvZiBmPyhmPVwiXCIrZixudWxsIT09ZCYmNj09PWQudGFnPyhjKGEsZC5zaWJsaW5nKSxkPWUoZCxmKSxkLnJldHVybj1hLGE9ZCk6XG4oYyhhLGQpLGQ9eGgoZixhLm1vZGUsaCksZC5yZXR1cm49YSxhPWQpLGcoYSkpOmMoYSxkKX1yZXR1cm4gSn12YXIgQmg9dmgoITApLENoPXZoKCExKSxEaD17fSxFaD1VZihEaCksRmg9VWYoRGgpLEdoPVVmKERoKTtmdW5jdGlvbiBIaChhKXtpZihhPT09RGgpdGhyb3cgRXJyb3IocCgxNzQpKTtyZXR1cm4gYX1mdW5jdGlvbiBJaChhLGIpe0coR2gsYik7RyhGaCxhKTtHKEVoLERoKTthPWIubm9kZVR5cGU7c3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDExOmI9KGI9Yi5kb2N1bWVudEVsZW1lbnQpP2IubmFtZXNwYWNlVVJJOmxiKG51bGwsXCJcIik7YnJlYWs7ZGVmYXVsdDphPTg9PT1hP2IucGFyZW50Tm9kZTpiLGI9YS5uYW1lc3BhY2VVUkl8fG51bGwsYT1hLnRhZ05hbWUsYj1sYihiLGEpfUUoRWgpO0coRWgsYil9ZnVuY3Rpb24gSmgoKXtFKEVoKTtFKEZoKTtFKEdoKX1cbmZ1bmN0aW9uIEtoKGEpe0hoKEdoLmN1cnJlbnQpO3ZhciBiPUhoKEVoLmN1cnJlbnQpO3ZhciBjPWxiKGIsYS50eXBlKTtiIT09YyYmKEcoRmgsYSksRyhFaCxjKSl9ZnVuY3Rpb24gTGgoYSl7RmguY3VycmVudD09PWEmJihFKEVoKSxFKEZoKSl9dmFyIE09VWYoMCk7XG5mdW5jdGlvbiBNaChhKXtmb3IodmFyIGI9YTtudWxsIT09Yjspe2lmKDEzPT09Yi50YWcpe3ZhciBjPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09YyYmKGM9Yy5kZWh5ZHJhdGVkLG51bGw9PT1jfHxcIiQ/XCI9PT1jLmRhdGF8fFwiJCFcIj09PWMuZGF0YSkpcmV0dXJuIGJ9ZWxzZSBpZigxOT09PWIudGFnJiZ2b2lkIDAhPT1iLm1lbW9pemVkUHJvcHMucmV2ZWFsT3JkZXIpe2lmKDAhPT0oYi5mbGFncyYxMjgpKXJldHVybiBifWVsc2UgaWYobnVsbCE9PWIuY2hpbGQpe2IuY2hpbGQucmV0dXJuPWI7Yj1iLmNoaWxkO2NvbnRpbnVlfWlmKGI9PT1hKWJyZWFrO2Zvcig7bnVsbD09PWIuc2libGluZzspe2lmKG51bGw9PT1iLnJldHVybnx8Yi5yZXR1cm49PT1hKXJldHVybiBudWxsO2I9Yi5yZXR1cm59Yi5zaWJsaW5nLnJldHVybj1iLnJldHVybjtiPWIuc2libGluZ31yZXR1cm4gbnVsbH12YXIgTmg9W107XG5mdW5jdGlvbiBPaCgpe2Zvcih2YXIgYT0wO2E8TmgubGVuZ3RoO2ErKylOaFthXS5fd29ya0luUHJvZ3Jlc3NWZXJzaW9uUHJpbWFyeT1udWxsO05oLmxlbmd0aD0wfXZhciBQaD11YS5SZWFjdEN1cnJlbnREaXNwYXRjaGVyLFFoPXVhLlJlYWN0Q3VycmVudEJhdGNoQ29uZmlnLFJoPTAsTj1udWxsLE89bnVsbCxQPW51bGwsU2g9ITEsVGg9ITEsVWg9MCxWaD0wO2Z1bmN0aW9uIFEoKXt0aHJvdyBFcnJvcihwKDMyMSkpO31mdW5jdGlvbiBXaChhLGIpe2lmKG51bGw9PT1iKXJldHVybiExO2Zvcih2YXIgYz0wO2M8Yi5sZW5ndGgmJmM8YS5sZW5ndGg7YysrKWlmKCFIZShhW2NdLGJbY10pKXJldHVybiExO3JldHVybiEwfVxuZnVuY3Rpb24gWGgoYSxiLGMsZCxlLGYpe1JoPWY7Tj1iO2IubWVtb2l6ZWRTdGF0ZT1udWxsO2IudXBkYXRlUXVldWU9bnVsbDtiLmxhbmVzPTA7UGguY3VycmVudD1udWxsPT09YXx8bnVsbD09PWEubWVtb2l6ZWRTdGF0ZT9ZaDpaaDthPWMoZCxlKTtpZihUaCl7Zj0wO2Rve1RoPSExO1VoPTA7aWYoMjU8PWYpdGhyb3cgRXJyb3IocCgzMDEpKTtmKz0xO1A9Tz1udWxsO2IudXBkYXRlUXVldWU9bnVsbDtQaC5jdXJyZW50PSRoO2E9YyhkLGUpfXdoaWxlKFRoKX1QaC5jdXJyZW50PWFpO2I9bnVsbCE9PU8mJm51bGwhPT1PLm5leHQ7Umg9MDtQPU89Tj1udWxsO1NoPSExO2lmKGIpdGhyb3cgRXJyb3IocCgzMDApKTtyZXR1cm4gYX1mdW5jdGlvbiBiaSgpe3ZhciBhPTAhPT1VaDtVaD0wO3JldHVybiBhfVxuZnVuY3Rpb24gY2koKXt2YXIgYT17bWVtb2l6ZWRTdGF0ZTpudWxsLGJhc2VTdGF0ZTpudWxsLGJhc2VRdWV1ZTpudWxsLHF1ZXVlOm51bGwsbmV4dDpudWxsfTtudWxsPT09UD9OLm1lbW9pemVkU3RhdGU9UD1hOlA9UC5uZXh0PWE7cmV0dXJuIFB9ZnVuY3Rpb24gZGkoKXtpZihudWxsPT09Tyl7dmFyIGE9Ti5hbHRlcm5hdGU7YT1udWxsIT09YT9hLm1lbW9pemVkU3RhdGU6bnVsbH1lbHNlIGE9Ty5uZXh0O3ZhciBiPW51bGw9PT1QP04ubWVtb2l6ZWRTdGF0ZTpQLm5leHQ7aWYobnVsbCE9PWIpUD1iLE89YTtlbHNle2lmKG51bGw9PT1hKXRocm93IEVycm9yKHAoMzEwKSk7Tz1hO2E9e21lbW9pemVkU3RhdGU6Ty5tZW1vaXplZFN0YXRlLGJhc2VTdGF0ZTpPLmJhc2VTdGF0ZSxiYXNlUXVldWU6Ty5iYXNlUXVldWUscXVldWU6Ty5xdWV1ZSxuZXh0Om51bGx9O251bGw9PT1QP04ubWVtb2l6ZWRTdGF0ZT1QPWE6UD1QLm5leHQ9YX1yZXR1cm4gUH1cbmZ1bmN0aW9uIGVpKGEsYil7cmV0dXJuXCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YihhKTpifVxuZnVuY3Rpb24gZmkoYSl7dmFyIGI9ZGkoKSxjPWIucXVldWU7aWYobnVsbD09PWMpdGhyb3cgRXJyb3IocCgzMTEpKTtjLmxhc3RSZW5kZXJlZFJlZHVjZXI9YTt2YXIgZD1PLGU9ZC5iYXNlUXVldWUsZj1jLnBlbmRpbmc7aWYobnVsbCE9PWYpe2lmKG51bGwhPT1lKXt2YXIgZz1lLm5leHQ7ZS5uZXh0PWYubmV4dDtmLm5leHQ9Z31kLmJhc2VRdWV1ZT1lPWY7Yy5wZW5kaW5nPW51bGx9aWYobnVsbCE9PWUpe2Y9ZS5uZXh0O2Q9ZC5iYXNlU3RhdGU7dmFyIGg9Zz1udWxsLGs9bnVsbCxsPWY7ZG97dmFyIG09bC5sYW5lO2lmKChSaCZtKT09PW0pbnVsbCE9PWsmJihrPWsubmV4dD17bGFuZTowLGFjdGlvbjpsLmFjdGlvbixoYXNFYWdlclN0YXRlOmwuaGFzRWFnZXJTdGF0ZSxlYWdlclN0YXRlOmwuZWFnZXJTdGF0ZSxuZXh0Om51bGx9KSxkPWwuaGFzRWFnZXJTdGF0ZT9sLmVhZ2VyU3RhdGU6YShkLGwuYWN0aW9uKTtlbHNle3ZhciBxPXtsYW5lOm0sYWN0aW9uOmwuYWN0aW9uLGhhc0VhZ2VyU3RhdGU6bC5oYXNFYWdlclN0YXRlLFxuZWFnZXJTdGF0ZTpsLmVhZ2VyU3RhdGUsbmV4dDpudWxsfTtudWxsPT09az8oaD1rPXEsZz1kKTprPWsubmV4dD1xO04ubGFuZXN8PW07aGh8PW19bD1sLm5leHR9d2hpbGUobnVsbCE9PWwmJmwhPT1mKTtudWxsPT09az9nPWQ6ay5uZXh0PWg7SGUoZCxiLm1lbW9pemVkU3RhdGUpfHwoVWc9ITApO2IubWVtb2l6ZWRTdGF0ZT1kO2IuYmFzZVN0YXRlPWc7Yi5iYXNlUXVldWU9aztjLmxhc3RSZW5kZXJlZFN0YXRlPWR9YT1jLmludGVybGVhdmVkO2lmKG51bGwhPT1hKXtlPWE7ZG8gZj1lLmxhbmUsTi5sYW5lc3w9ZixoaHw9ZixlPWUubmV4dDt3aGlsZShlIT09YSl9ZWxzZSBudWxsPT09ZSYmKGMubGFuZXM9MCk7cmV0dXJuW2IubWVtb2l6ZWRTdGF0ZSxjLmRpc3BhdGNoXX1cbmZ1bmN0aW9uIGdpKGEpe3ZhciBiPWRpKCksYz1iLnF1ZXVlO2lmKG51bGw9PT1jKXRocm93IEVycm9yKHAoMzExKSk7Yy5sYXN0UmVuZGVyZWRSZWR1Y2VyPWE7dmFyIGQ9Yy5kaXNwYXRjaCxlPWMucGVuZGluZyxmPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09ZSl7Yy5wZW5kaW5nPW51bGw7dmFyIGc9ZT1lLm5leHQ7ZG8gZj1hKGYsZy5hY3Rpb24pLGc9Zy5uZXh0O3doaWxlKGchPT1lKTtIZShmLGIubWVtb2l6ZWRTdGF0ZSl8fChVZz0hMCk7Yi5tZW1vaXplZFN0YXRlPWY7bnVsbD09PWIuYmFzZVF1ZXVlJiYoYi5iYXNlU3RhdGU9Zik7Yy5sYXN0UmVuZGVyZWRTdGF0ZT1mfXJldHVybltmLGRdfWZ1bmN0aW9uIGhpKCl7fVxuZnVuY3Rpb24gaWkoYSxiKXt2YXIgYz1OLGQ9ZGkoKSxlPWIoKSxmPSFIZShkLm1lbW9pemVkU3RhdGUsZSk7ZiYmKGQubWVtb2l6ZWRTdGF0ZT1lLFVnPSEwKTtkPWQucXVldWU7amkoa2kuYmluZChudWxsLGMsZCxhKSxbYV0pO2lmKGQuZ2V0U25hcHNob3QhPT1ifHxmfHxudWxsIT09UCYmUC5tZW1vaXplZFN0YXRlLnRhZyYxKXtjLmZsYWdzfD0yMDQ4O2xpKDksbWkuYmluZChudWxsLGMsZCxlLGIpLHZvaWQgMCxudWxsKTtpZihudWxsPT09Uil0aHJvdyBFcnJvcihwKDM0OSkpOzAhPT0oUmgmMzApfHxuaShjLGIsZSl9cmV0dXJuIGV9ZnVuY3Rpb24gbmkoYSxiLGMpe2EuZmxhZ3N8PTE2Mzg0O2E9e2dldFNuYXBzaG90OmIsdmFsdWU6Y307Yj1OLnVwZGF0ZVF1ZXVlO251bGw9PT1iPyhiPXtsYXN0RWZmZWN0Om51bGwsc3RvcmVzOm51bGx9LE4udXBkYXRlUXVldWU9YixiLnN0b3Jlcz1bYV0pOihjPWIuc3RvcmVzLG51bGw9PT1jP2Iuc3RvcmVzPVthXTpjLnB1c2goYSkpfVxuZnVuY3Rpb24gbWkoYSxiLGMsZCl7Yi52YWx1ZT1jO2IuZ2V0U25hcHNob3Q9ZDtvaShiKSYmcGkoYSl9ZnVuY3Rpb24ga2koYSxiLGMpe3JldHVybiBjKGZ1bmN0aW9uKCl7b2koYikmJnBpKGEpfSl9ZnVuY3Rpb24gb2koYSl7dmFyIGI9YS5nZXRTbmFwc2hvdDthPWEudmFsdWU7dHJ5e3ZhciBjPWIoKTtyZXR1cm4hSGUoYSxjKX1jYXRjaChkKXtyZXR1cm4hMH19ZnVuY3Rpb24gcGkoYSl7dmFyIGI9WmcoYSwxKTtudWxsIT09YiYmbWgoYixhLDEsLTEpfVxuZnVuY3Rpb24gcWkoYSl7dmFyIGI9Y2koKTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgYSYmKGE9YSgpKTtiLm1lbW9pemVkU3RhdGU9Yi5iYXNlU3RhdGU9YTthPXtwZW5kaW5nOm51bGwsaW50ZXJsZWF2ZWQ6bnVsbCxsYW5lczowLGRpc3BhdGNoOm51bGwsbGFzdFJlbmRlcmVkUmVkdWNlcjplaSxsYXN0UmVuZGVyZWRTdGF0ZTphfTtiLnF1ZXVlPWE7YT1hLmRpc3BhdGNoPXJpLmJpbmQobnVsbCxOLGEpO3JldHVybltiLm1lbW9pemVkU3RhdGUsYV19XG5mdW5jdGlvbiBsaShhLGIsYyxkKXthPXt0YWc6YSxjcmVhdGU6YixkZXN0cm95OmMsZGVwczpkLG5leHQ6bnVsbH07Yj1OLnVwZGF0ZVF1ZXVlO251bGw9PT1iPyhiPXtsYXN0RWZmZWN0Om51bGwsc3RvcmVzOm51bGx9LE4udXBkYXRlUXVldWU9YixiLmxhc3RFZmZlY3Q9YS5uZXh0PWEpOihjPWIubGFzdEVmZmVjdCxudWxsPT09Yz9iLmxhc3RFZmZlY3Q9YS5uZXh0PWE6KGQ9Yy5uZXh0LGMubmV4dD1hLGEubmV4dD1kLGIubGFzdEVmZmVjdD1hKSk7cmV0dXJuIGF9ZnVuY3Rpb24gc2koKXtyZXR1cm4gZGkoKS5tZW1vaXplZFN0YXRlfWZ1bmN0aW9uIHRpKGEsYixjLGQpe3ZhciBlPWNpKCk7Ti5mbGFnc3w9YTtlLm1lbW9pemVkU3RhdGU9bGkoMXxiLGMsdm9pZCAwLHZvaWQgMD09PWQ/bnVsbDpkKX1cbmZ1bmN0aW9uIHVpKGEsYixjLGQpe3ZhciBlPWRpKCk7ZD12b2lkIDA9PT1kP251bGw6ZDt2YXIgZj12b2lkIDA7aWYobnVsbCE9PU8pe3ZhciBnPU8ubWVtb2l6ZWRTdGF0ZTtmPWcuZGVzdHJveTtpZihudWxsIT09ZCYmV2goZCxnLmRlcHMpKXtlLm1lbW9pemVkU3RhdGU9bGkoYixjLGYsZCk7cmV0dXJufX1OLmZsYWdzfD1hO2UubWVtb2l6ZWRTdGF0ZT1saSgxfGIsYyxmLGQpfWZ1bmN0aW9uIHZpKGEsYil7cmV0dXJuIHRpKDgzOTA2NTYsOCxhLGIpfWZ1bmN0aW9uIGppKGEsYil7cmV0dXJuIHVpKDIwNDgsOCxhLGIpfWZ1bmN0aW9uIHdpKGEsYil7cmV0dXJuIHVpKDQsMixhLGIpfWZ1bmN0aW9uIHhpKGEsYil7cmV0dXJuIHVpKDQsNCxhLGIpfVxuZnVuY3Rpb24geWkoYSxiKXtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYilyZXR1cm4gYT1hKCksYihhKSxmdW5jdGlvbigpe2IobnVsbCl9O2lmKG51bGwhPT1iJiZ2b2lkIDAhPT1iKXJldHVybiBhPWEoKSxiLmN1cnJlbnQ9YSxmdW5jdGlvbigpe2IuY3VycmVudD1udWxsfX1mdW5jdGlvbiB6aShhLGIsYyl7Yz1udWxsIT09YyYmdm9pZCAwIT09Yz9jLmNvbmNhdChbYV0pOm51bGw7cmV0dXJuIHVpKDQsNCx5aS5iaW5kKG51bGwsYixhKSxjKX1mdW5jdGlvbiBBaSgpe31mdW5jdGlvbiBCaShhLGIpe3ZhciBjPWRpKCk7Yj12b2lkIDA9PT1iP251bGw6Yjt2YXIgZD1jLm1lbW9pemVkU3RhdGU7aWYobnVsbCE9PWQmJm51bGwhPT1iJiZXaChiLGRbMV0pKXJldHVybiBkWzBdO2MubWVtb2l6ZWRTdGF0ZT1bYSxiXTtyZXR1cm4gYX1cbmZ1bmN0aW9uIENpKGEsYil7dmFyIGM9ZGkoKTtiPXZvaWQgMD09PWI/bnVsbDpiO3ZhciBkPWMubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09ZCYmbnVsbCE9PWImJldoKGIsZFsxXSkpcmV0dXJuIGRbMF07YT1hKCk7Yy5tZW1vaXplZFN0YXRlPVthLGJdO3JldHVybiBhfWZ1bmN0aW9uIERpKGEsYixjKXtpZigwPT09KFJoJjIxKSlyZXR1cm4gYS5iYXNlU3RhdGUmJihhLmJhc2VTdGF0ZT0hMSxVZz0hMCksYS5tZW1vaXplZFN0YXRlPWM7SGUoYyxiKXx8KGM9eWMoKSxOLmxhbmVzfD1jLGhofD1jLGEuYmFzZVN0YXRlPSEwKTtyZXR1cm4gYn1mdW5jdGlvbiBFaShhLGIpe3ZhciBjPUM7Qz0wIT09YyYmND5jP2M6NDthKCEwKTt2YXIgZD1RaC50cmFuc2l0aW9uO1FoLnRyYW5zaXRpb249e307dHJ5e2EoITEpLGIoKX1maW5hbGx5e0M9YyxRaC50cmFuc2l0aW9uPWR9fWZ1bmN0aW9uIEZpKCl7cmV0dXJuIGRpKCkubWVtb2l6ZWRTdGF0ZX1cbmZ1bmN0aW9uIEdpKGEsYixjKXt2YXIgZD1saChhKTtjPXtsYW5lOmQsYWN0aW9uOmMsaGFzRWFnZXJTdGF0ZTohMSxlYWdlclN0YXRlOm51bGwsbmV4dDpudWxsfTtpZihIaShhKSlJaShiLGMpO2Vsc2UgaWYoYz1ZZyhhLGIsYyxkKSxudWxsIT09Yyl7dmFyIGU9TCgpO21oKGMsYSxkLGUpO0ppKGMsYixkKX19XG5mdW5jdGlvbiByaShhLGIsYyl7dmFyIGQ9bGgoYSksZT17bGFuZTpkLGFjdGlvbjpjLGhhc0VhZ2VyU3RhdGU6ITEsZWFnZXJTdGF0ZTpudWxsLG5leHQ6bnVsbH07aWYoSGkoYSkpSWkoYixlKTtlbHNle3ZhciBmPWEuYWx0ZXJuYXRlO2lmKDA9PT1hLmxhbmVzJiYobnVsbD09PWZ8fDA9PT1mLmxhbmVzKSYmKGY9Yi5sYXN0UmVuZGVyZWRSZWR1Y2VyLG51bGwhPT1mKSl0cnl7dmFyIGc9Yi5sYXN0UmVuZGVyZWRTdGF0ZSxoPWYoZyxjKTtlLmhhc0VhZ2VyU3RhdGU9ITA7ZS5lYWdlclN0YXRlPWg7aWYoSGUoaCxnKSl7dmFyIGs9Yi5pbnRlcmxlYXZlZDtudWxsPT09az8oZS5uZXh0PWUsWGcoYikpOihlLm5leHQ9ay5uZXh0LGsubmV4dD1lKTtiLmludGVybGVhdmVkPWU7cmV0dXJufX1jYXRjaChsKXt9ZmluYWxseXt9Yz1ZZyhhLGIsZSxkKTtudWxsIT09YyYmKGU9TCgpLG1oKGMsYSxkLGUpLEppKGMsYixkKSl9fVxuZnVuY3Rpb24gSGkoYSl7dmFyIGI9YS5hbHRlcm5hdGU7cmV0dXJuIGE9PT1OfHxudWxsIT09YiYmYj09PU59ZnVuY3Rpb24gSWkoYSxiKXtUaD1TaD0hMDt2YXIgYz1hLnBlbmRpbmc7bnVsbD09PWM/Yi5uZXh0PWI6KGIubmV4dD1jLm5leHQsYy5uZXh0PWIpO2EucGVuZGluZz1ifWZ1bmN0aW9uIEppKGEsYixjKXtpZigwIT09KGMmNDE5NDI0MCkpe3ZhciBkPWIubGFuZXM7ZCY9YS5wZW5kaW5nTGFuZXM7Y3w9ZDtiLmxhbmVzPWM7Q2MoYSxjKX19XG52YXIgYWk9e3JlYWRDb250ZXh0OlZnLHVzZUNhbGxiYWNrOlEsdXNlQ29udGV4dDpRLHVzZUVmZmVjdDpRLHVzZUltcGVyYXRpdmVIYW5kbGU6USx1c2VJbnNlcnRpb25FZmZlY3Q6USx1c2VMYXlvdXRFZmZlY3Q6USx1c2VNZW1vOlEsdXNlUmVkdWNlcjpRLHVzZVJlZjpRLHVzZVN0YXRlOlEsdXNlRGVidWdWYWx1ZTpRLHVzZURlZmVycmVkVmFsdWU6USx1c2VUcmFuc2l0aW9uOlEsdXNlTXV0YWJsZVNvdXJjZTpRLHVzZVN5bmNFeHRlcm5hbFN0b3JlOlEsdXNlSWQ6USx1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6ITF9LFloPXtyZWFkQ29udGV4dDpWZyx1c2VDYWxsYmFjazpmdW5jdGlvbihhLGIpe2NpKCkubWVtb2l6ZWRTdGF0ZT1bYSx2b2lkIDA9PT1iP251bGw6Yl07cmV0dXJuIGF9LHVzZUNvbnRleHQ6VmcsdXNlRWZmZWN0OnZpLHVzZUltcGVyYXRpdmVIYW5kbGU6ZnVuY3Rpb24oYSxiLGMpe2M9bnVsbCE9PWMmJnZvaWQgMCE9PWM/Yy5jb25jYXQoW2FdKTpudWxsO3JldHVybiB0aSg0MTk0MzA4LFxuNCx5aS5iaW5kKG51bGwsYixhKSxjKX0sdXNlTGF5b3V0RWZmZWN0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRpKDQxOTQzMDgsNCxhLGIpfSx1c2VJbnNlcnRpb25FZmZlY3Q6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGkoNCwyLGEsYil9LHVzZU1lbW86ZnVuY3Rpb24oYSxiKXt2YXIgYz1jaSgpO2I9dm9pZCAwPT09Yj9udWxsOmI7YT1hKCk7Yy5tZW1vaXplZFN0YXRlPVthLGJdO3JldHVybiBhfSx1c2VSZWR1Y2VyOmZ1bmN0aW9uKGEsYixjKXt2YXIgZD1jaSgpO2I9dm9pZCAwIT09Yz9jKGIpOmI7ZC5tZW1vaXplZFN0YXRlPWQuYmFzZVN0YXRlPWI7YT17cGVuZGluZzpudWxsLGludGVybGVhdmVkOm51bGwsbGFuZXM6MCxkaXNwYXRjaDpudWxsLGxhc3RSZW5kZXJlZFJlZHVjZXI6YSxsYXN0UmVuZGVyZWRTdGF0ZTpifTtkLnF1ZXVlPWE7YT1hLmRpc3BhdGNoPUdpLmJpbmQobnVsbCxOLGEpO3JldHVybltkLm1lbW9pemVkU3RhdGUsYV19LHVzZVJlZjpmdW5jdGlvbihhKXt2YXIgYj1cbmNpKCk7YT17Y3VycmVudDphfTtyZXR1cm4gYi5tZW1vaXplZFN0YXRlPWF9LHVzZVN0YXRlOnFpLHVzZURlYnVnVmFsdWU6QWksdXNlRGVmZXJyZWRWYWx1ZTpmdW5jdGlvbihhKXtyZXR1cm4gY2koKS5tZW1vaXplZFN0YXRlPWF9LHVzZVRyYW5zaXRpb246ZnVuY3Rpb24oKXt2YXIgYT1xaSghMSksYj1hWzBdO2E9RWkuYmluZChudWxsLGFbMV0pO2NpKCkubWVtb2l6ZWRTdGF0ZT1hO3JldHVybltiLGFdfSx1c2VNdXRhYmxlU291cmNlOmZ1bmN0aW9uKCl7fSx1c2VTeW5jRXh0ZXJuYWxTdG9yZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9TixlPWNpKCk7aWYoSSl7aWYodm9pZCAwPT09Yyl0aHJvdyBFcnJvcihwKDQwNykpO2M9YygpfWVsc2V7Yz1iKCk7aWYobnVsbD09PVIpdGhyb3cgRXJyb3IocCgzNDkpKTswIT09KFJoJjMwKXx8bmkoZCxiLGMpfWUubWVtb2l6ZWRTdGF0ZT1jO3ZhciBmPXt2YWx1ZTpjLGdldFNuYXBzaG90OmJ9O2UucXVldWU9Zjt2aShraS5iaW5kKG51bGwsZCxcbmYsYSksW2FdKTtkLmZsYWdzfD0yMDQ4O2xpKDksbWkuYmluZChudWxsLGQsZixjLGIpLHZvaWQgMCxudWxsKTtyZXR1cm4gY30sdXNlSWQ6ZnVuY3Rpb24oKXt2YXIgYT1jaSgpLGI9Ui5pZGVudGlmaWVyUHJlZml4O2lmKEkpe3ZhciBjPXNnO3ZhciBkPXJnO2M9KGQmfigxPDwzMi1vYyhkKS0xKSkudG9TdHJpbmcoMzIpK2M7Yj1cIjpcIitiK1wiUlwiK2M7Yz1VaCsrOzA8YyYmKGIrPVwiSFwiK2MudG9TdHJpbmcoMzIpKTtiKz1cIjpcIn1lbHNlIGM9VmgrKyxiPVwiOlwiK2IrXCJyXCIrYy50b1N0cmluZygzMikrXCI6XCI7cmV0dXJuIGEubWVtb2l6ZWRTdGF0ZT1ifSx1bnN0YWJsZV9pc05ld1JlY29uY2lsZXI6ITF9LFpoPXtyZWFkQ29udGV4dDpWZyx1c2VDYWxsYmFjazpCaSx1c2VDb250ZXh0OlZnLHVzZUVmZmVjdDpqaSx1c2VJbXBlcmF0aXZlSGFuZGxlOnppLHVzZUluc2VydGlvbkVmZmVjdDp3aSx1c2VMYXlvdXRFZmZlY3Q6eGksdXNlTWVtbzpDaSx1c2VSZWR1Y2VyOmZpLHVzZVJlZjpzaSx1c2VTdGF0ZTpmdW5jdGlvbigpe3JldHVybiBmaShlaSl9LFxudXNlRGVidWdWYWx1ZTpBaSx1c2VEZWZlcnJlZFZhbHVlOmZ1bmN0aW9uKGEpe3ZhciBiPWRpKCk7cmV0dXJuIERpKGIsTy5tZW1vaXplZFN0YXRlLGEpfSx1c2VUcmFuc2l0aW9uOmZ1bmN0aW9uKCl7dmFyIGE9ZmkoZWkpWzBdLGI9ZGkoKS5tZW1vaXplZFN0YXRlO3JldHVyblthLGJdfSx1c2VNdXRhYmxlU291cmNlOmhpLHVzZVN5bmNFeHRlcm5hbFN0b3JlOmlpLHVzZUlkOkZpLHVuc3RhYmxlX2lzTmV3UmVjb25jaWxlcjohMX0sJGg9e3JlYWRDb250ZXh0OlZnLHVzZUNhbGxiYWNrOkJpLHVzZUNvbnRleHQ6VmcsdXNlRWZmZWN0OmppLHVzZUltcGVyYXRpdmVIYW5kbGU6emksdXNlSW5zZXJ0aW9uRWZmZWN0OndpLHVzZUxheW91dEVmZmVjdDp4aSx1c2VNZW1vOkNpLHVzZVJlZHVjZXI6Z2ksdXNlUmVmOnNpLHVzZVN0YXRlOmZ1bmN0aW9uKCl7cmV0dXJuIGdpKGVpKX0sdXNlRGVidWdWYWx1ZTpBaSx1c2VEZWZlcnJlZFZhbHVlOmZ1bmN0aW9uKGEpe3ZhciBiPWRpKCk7cmV0dXJuIG51bGw9PT1cbk8/Yi5tZW1vaXplZFN0YXRlPWE6RGkoYixPLm1lbW9pemVkU3RhdGUsYSl9LHVzZVRyYW5zaXRpb246ZnVuY3Rpb24oKXt2YXIgYT1naShlaSlbMF0sYj1kaSgpLm1lbW9pemVkU3RhdGU7cmV0dXJuW2EsYl19LHVzZU11dGFibGVTb3VyY2U6aGksdXNlU3luY0V4dGVybmFsU3RvcmU6aWksdXNlSWQ6RmksdW5zdGFibGVfaXNOZXdSZWNvbmNpbGVyOiExfTtmdW5jdGlvbiBLaShhLGIpe3RyeXt2YXIgYz1cIlwiLGQ9YjtkbyBjKz1QYShkKSxkPWQucmV0dXJuO3doaWxlKGQpO3ZhciBlPWN9Y2F0Y2goZil7ZT1cIlxcbkVycm9yIGdlbmVyYXRpbmcgc3RhY2s6IFwiK2YubWVzc2FnZStcIlxcblwiK2Yuc3RhY2t9cmV0dXJue3ZhbHVlOmEsc291cmNlOmIsc3RhY2s6ZSxkaWdlc3Q6bnVsbH19ZnVuY3Rpb24gTGkoYSxiLGMpe3JldHVybnt2YWx1ZTphLHNvdXJjZTpudWxsLHN0YWNrOm51bGwhPWM/YzpudWxsLGRpZ2VzdDpudWxsIT1iP2I6bnVsbH19XG5mdW5jdGlvbiBNaShhLGIpe3RyeXtjb25zb2xlLmVycm9yKGIudmFsdWUpfWNhdGNoKGMpe3NldFRpbWVvdXQoZnVuY3Rpb24oKXt0aHJvdyBjO30pfX12YXIgTmk9XCJmdW5jdGlvblwiPT09dHlwZW9mIFdlYWtNYXA/V2Vha01hcDpNYXA7ZnVuY3Rpb24gT2koYSxiLGMpe2M9Y2goLTEsYyk7Yy50YWc9MztjLnBheWxvYWQ9e2VsZW1lbnQ6bnVsbH07dmFyIGQ9Yi52YWx1ZTtjLmNhbGxiYWNrPWZ1bmN0aW9uKCl7UGl8fChQaT0hMCxRaT1kKTtNaShhLGIpfTtyZXR1cm4gY31cbmZ1bmN0aW9uIFJpKGEsYixjKXtjPWNoKC0xLGMpO2MudGFnPTM7dmFyIGQ9YS50eXBlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcjtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZCl7dmFyIGU9Yi52YWx1ZTtjLnBheWxvYWQ9ZnVuY3Rpb24oKXtyZXR1cm4gZChlKX07Yy5jYWxsYmFjaz1mdW5jdGlvbigpe01pKGEsYil9fXZhciBmPWEuc3RhdGVOb2RlO251bGwhPT1mJiZcImZ1bmN0aW9uXCI9PT10eXBlb2YgZi5jb21wb25lbnREaWRDYXRjaCYmKGMuY2FsbGJhY2s9ZnVuY3Rpb24oKXtNaShhLGIpO1wiZnVuY3Rpb25cIiE9PXR5cGVvZiBkJiYobnVsbD09PVNpP1NpPW5ldyBTZXQoW3RoaXNdKTpTaS5hZGQodGhpcykpO3ZhciBjPWIuc3RhY2s7dGhpcy5jb21wb25lbnREaWRDYXRjaChiLnZhbHVlLHtjb21wb25lbnRTdGFjazpudWxsIT09Yz9jOlwiXCJ9KX0pO3JldHVybiBjfVxuZnVuY3Rpb24gVGkoYSxiLGMpe3ZhciBkPWEucGluZ0NhY2hlO2lmKG51bGw9PT1kKXtkPWEucGluZ0NhY2hlPW5ldyBOaTt2YXIgZT1uZXcgU2V0O2Quc2V0KGIsZSl9ZWxzZSBlPWQuZ2V0KGIpLHZvaWQgMD09PWUmJihlPW5ldyBTZXQsZC5zZXQoYixlKSk7ZS5oYXMoYyl8fChlLmFkZChjKSxhPVVpLmJpbmQobnVsbCxhLGIsYyksYi50aGVuKGEsYSkpfWZ1bmN0aW9uIFZpKGEpe2Rve3ZhciBiO2lmKGI9MTM9PT1hLnRhZyliPWEubWVtb2l6ZWRTdGF0ZSxiPW51bGwhPT1iP251bGwhPT1iLmRlaHlkcmF0ZWQ/ITA6ITE6ITA7aWYoYilyZXR1cm4gYTthPWEucmV0dXJufXdoaWxlKG51bGwhPT1hKTtyZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFdpKGEsYixjLGQsZSl7aWYoMD09PShhLm1vZGUmMSkpcmV0dXJuIGE9PT1iP2EuZmxhZ3N8PTY1NTM2OihhLmZsYWdzfD0xMjgsYy5mbGFnc3w9MTMxMDcyLGMuZmxhZ3MmPS01MjgwNSwxPT09Yy50YWcmJihudWxsPT09Yy5hbHRlcm5hdGU/Yy50YWc9MTc6KGI9Y2goLTEsMSksYi50YWc9MixkaChjLGIsMSkpKSxjLmxhbmVzfD0xKSxhO2EuZmxhZ3N8PTY1NTM2O2EubGFuZXM9ZTtyZXR1cm4gYX12YXIgWGk9dWEuUmVhY3RDdXJyZW50T3duZXIsVWc9ITE7ZnVuY3Rpb24gWWkoYSxiLGMsZCl7Yi5jaGlsZD1udWxsPT09YT9DaChiLG51bGwsYyxkKTpCaChiLGEuY2hpbGQsYyxkKX1cbmZ1bmN0aW9uIFppKGEsYixjLGQsZSl7Yz1jLnJlbmRlcjt2YXIgZj1iLnJlZjtUZyhiLGUpO2Q9WGgoYSxiLGMsZCxmLGUpO2M9YmkoKTtpZihudWxsIT09YSYmIVVnKXJldHVybiBiLnVwZGF0ZVF1ZXVlPWEudXBkYXRlUXVldWUsYi5mbGFncyY9LTIwNTMsYS5sYW5lcyY9fmUsJGkoYSxiLGUpO0kmJmMmJnZnKGIpO2IuZmxhZ3N8PTE7WWkoYSxiLGQsZSk7cmV0dXJuIGIuY2hpbGR9XG5mdW5jdGlvbiBhaihhLGIsYyxkLGUpe2lmKG51bGw9PT1hKXt2YXIgZj1jLnR5cGU7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGYmJiFiaihmKSYmdm9pZCAwPT09Zi5kZWZhdWx0UHJvcHMmJm51bGw9PT1jLmNvbXBhcmUmJnZvaWQgMD09PWMuZGVmYXVsdFByb3BzKXJldHVybiBiLnRhZz0xNSxiLnR5cGU9ZixjaihhLGIsZixkLGUpO2E9eWgoYy50eXBlLG51bGwsZCxiLGIubW9kZSxlKTthLnJlZj1iLnJlZjthLnJldHVybj1iO3JldHVybiBiLmNoaWxkPWF9Zj1hLmNoaWxkO2lmKDA9PT0oYS5sYW5lcyZlKSl7dmFyIGc9Zi5tZW1vaXplZFByb3BzO2M9Yy5jb21wYXJlO2M9bnVsbCE9PWM/YzpJZTtpZihjKGcsZCkmJmEucmVmPT09Yi5yZWYpcmV0dXJuICRpKGEsYixlKX1iLmZsYWdzfD0xO2E9d2goZixkKTthLnJlZj1iLnJlZjthLnJldHVybj1iO3JldHVybiBiLmNoaWxkPWF9XG5mdW5jdGlvbiBjaihhLGIsYyxkLGUpe2lmKG51bGwhPT1hKXt2YXIgZj1hLm1lbW9pemVkUHJvcHM7aWYoSWUoZixkKSYmYS5yZWY9PT1iLnJlZilpZihVZz0hMSxiLnBlbmRpbmdQcm9wcz1kPWYsMCE9PShhLmxhbmVzJmUpKTAhPT0oYS5mbGFncyYxMzEwNzIpJiYoVWc9ITApO2Vsc2UgcmV0dXJuIGIubGFuZXM9YS5sYW5lcywkaShhLGIsZSl9cmV0dXJuIGRqKGEsYixjLGQsZSl9XG5mdW5jdGlvbiBlaihhLGIsYyl7dmFyIGQ9Yi5wZW5kaW5nUHJvcHMsZT1kLmNoaWxkcmVuLGY9bnVsbCE9PWE/YS5tZW1vaXplZFN0YXRlOm51bGw7aWYoXCJoaWRkZW5cIj09PWQubW9kZSlpZigwPT09KGIubW9kZSYxKSliLm1lbW9pemVkU3RhdGU9e2Jhc2VMYW5lczowLGNhY2hlUG9vbDpudWxsLHRyYW5zaXRpb25zOm51bGx9LEcoZmosZ2opLGdqfD1jO2Vsc2V7aWYoMD09PShjJjEwNzM3NDE4MjQpKXJldHVybiBhPW51bGwhPT1mP2YuYmFzZUxhbmVzfGM6YyxiLmxhbmVzPWIuY2hpbGRMYW5lcz0xMDczNzQxODI0LGIubWVtb2l6ZWRTdGF0ZT17YmFzZUxhbmVzOmEsY2FjaGVQb29sOm51bGwsdHJhbnNpdGlvbnM6bnVsbH0sYi51cGRhdGVRdWV1ZT1udWxsLEcoZmosZ2opLGdqfD1hLG51bGw7Yi5tZW1vaXplZFN0YXRlPXtiYXNlTGFuZXM6MCxjYWNoZVBvb2w6bnVsbCx0cmFuc2l0aW9uczpudWxsfTtkPW51bGwhPT1mP2YuYmFzZUxhbmVzOmM7Ryhmaixnaik7Z2p8PWR9ZWxzZSBudWxsIT09XG5mPyhkPWYuYmFzZUxhbmVzfGMsYi5tZW1vaXplZFN0YXRlPW51bGwpOmQ9YyxHKGZqLGdqKSxnanw9ZDtZaShhLGIsZSxjKTtyZXR1cm4gYi5jaGlsZH1mdW5jdGlvbiBoaihhLGIpe3ZhciBjPWIucmVmO2lmKG51bGw9PT1hJiZudWxsIT09Y3x8bnVsbCE9PWEmJmEucmVmIT09YyliLmZsYWdzfD01MTIsYi5mbGFnc3w9MjA5NzE1Mn1mdW5jdGlvbiBkaihhLGIsYyxkLGUpe3ZhciBmPVpmKGMpP1hmOkguY3VycmVudDtmPVlmKGIsZik7VGcoYixlKTtjPVhoKGEsYixjLGQsZixlKTtkPWJpKCk7aWYobnVsbCE9PWEmJiFVZylyZXR1cm4gYi51cGRhdGVRdWV1ZT1hLnVwZGF0ZVF1ZXVlLGIuZmxhZ3MmPS0yMDUzLGEubGFuZXMmPX5lLCRpKGEsYixlKTtJJiZkJiZ2ZyhiKTtiLmZsYWdzfD0xO1lpKGEsYixjLGUpO3JldHVybiBiLmNoaWxkfVxuZnVuY3Rpb24gaWooYSxiLGMsZCxlKXtpZihaZihjKSl7dmFyIGY9ITA7Y2coYil9ZWxzZSBmPSExO1RnKGIsZSk7aWYobnVsbD09PWIuc3RhdGVOb2RlKWpqKGEsYikscGgoYixjLGQpLHJoKGIsYyxkLGUpLGQ9ITA7ZWxzZSBpZihudWxsPT09YSl7dmFyIGc9Yi5zdGF0ZU5vZGUsaD1iLm1lbW9pemVkUHJvcHM7Zy5wcm9wcz1oO3ZhciBrPWcuY29udGV4dCxsPWMuY29udGV4dFR5cGU7XCJvYmplY3RcIj09PXR5cGVvZiBsJiZudWxsIT09bD9sPVZnKGwpOihsPVpmKGMpP1hmOkguY3VycmVudCxsPVlmKGIsbCkpO3ZhciBtPWMuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzLHE9XCJmdW5jdGlvblwiPT09dHlwZW9mIG18fFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlO3F8fFwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLlVOU0FGRV9jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzfHxcbihoIT09ZHx8ayE9PWwpJiZxaChiLGcsZCxsKTskZz0hMTt2YXIgcj1iLm1lbW9pemVkU3RhdGU7Zy5zdGF0ZT1yO2doKGIsZCxnLGUpO2s9Yi5tZW1vaXplZFN0YXRlO2ghPT1kfHxyIT09a3x8V2YuY3VycmVudHx8JGc/KFwiZnVuY3Rpb25cIj09PXR5cGVvZiBtJiYoa2goYixjLG0sZCksaz1iLm1lbW9pemVkU3RhdGUpLChoPSRnfHxvaChiLGMsaCxkLHIsayxsKSk/KHF8fFwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQmJlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxNb3VudHx8KFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxNb3VudCYmZy5jb21wb25lbnRXaWxsTW91bnQoKSxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZy5VTlNBRkVfY29tcG9uZW50V2lsbE1vdW50JiZnLlVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQoKSksXCJmdW5jdGlvblwiPT09dHlwZW9mIGcuY29tcG9uZW50RGlkTW91bnQmJihiLmZsYWdzfD00MTk0MzA4KSk6XG4oXCJmdW5jdGlvblwiPT09dHlwZW9mIGcuY29tcG9uZW50RGlkTW91bnQmJihiLmZsYWdzfD00MTk0MzA4KSxiLm1lbW9pemVkUHJvcHM9ZCxiLm1lbW9pemVkU3RhdGU9ayksZy5wcm9wcz1kLGcuc3RhdGU9ayxnLmNvbnRleHQ9bCxkPWgpOihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZy5jb21wb25lbnREaWRNb3VudCYmKGIuZmxhZ3N8PTQxOTQzMDgpLGQ9ITEpfWVsc2V7Zz1iLnN0YXRlTm9kZTtiaChhLGIpO2g9Yi5tZW1vaXplZFByb3BzO2w9Yi50eXBlPT09Yi5lbGVtZW50VHlwZT9oOkxnKGIudHlwZSxoKTtnLnByb3BzPWw7cT1iLnBlbmRpbmdQcm9wcztyPWcuY29udGV4dDtrPWMuY29udGV4dFR5cGU7XCJvYmplY3RcIj09PXR5cGVvZiBrJiZudWxsIT09az9rPVZnKGspOihrPVpmKGMpP1hmOkguY3VycmVudCxrPVlmKGIsaykpO3ZhciB5PWMuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzOyhtPVwiZnVuY3Rpb25cIj09PXR5cGVvZiB5fHxcImZ1bmN0aW9uXCI9PT10eXBlb2YgZy5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZSl8fFxuXCJmdW5jdGlvblwiIT09dHlwZW9mIGcuVU5TQUZFX2NvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMmJlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHN8fChoIT09cXx8ciE9PWspJiZxaChiLGcsZCxrKTskZz0hMTtyPWIubWVtb2l6ZWRTdGF0ZTtnLnN0YXRlPXI7Z2goYixkLGcsZSk7dmFyIG49Yi5tZW1vaXplZFN0YXRlO2ghPT1xfHxyIT09bnx8V2YuY3VycmVudHx8JGc/KFwiZnVuY3Rpb25cIj09PXR5cGVvZiB5JiYoa2goYixjLHksZCksbj1iLm1lbW9pemVkU3RhdGUpLChsPSRnfHxvaChiLGMsbCxkLHIsbixrKXx8ITEpPyhtfHxcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZSYmXCJmdW5jdGlvblwiIT09dHlwZW9mIGcuY29tcG9uZW50V2lsbFVwZGF0ZXx8KFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmNvbXBvbmVudFdpbGxVcGRhdGUmJmcuY29tcG9uZW50V2lsbFVwZGF0ZShkLG4sayksXCJmdW5jdGlvblwiPT09dHlwZW9mIGcuVU5TQUZFX2NvbXBvbmVudFdpbGxVcGRhdGUmJlxuZy5VTlNBRkVfY29tcG9uZW50V2lsbFVwZGF0ZShkLG4saykpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmNvbXBvbmVudERpZFVwZGF0ZSYmKGIuZmxhZ3N8PTQpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBnLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlJiYoYi5mbGFnc3w9MTAyNCkpOihcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5jb21wb25lbnREaWRVcGRhdGV8fGg9PT1hLm1lbW9pemVkUHJvcHMmJnI9PT1hLm1lbW9pemVkU3RhdGV8fChiLmZsYWdzfD00KSxcImZ1bmN0aW9uXCIhPT10eXBlb2YgZy5nZXRTbmFwc2hvdEJlZm9yZVVwZGF0ZXx8aD09PWEubWVtb2l6ZWRQcm9wcyYmcj09PWEubWVtb2l6ZWRTdGF0ZXx8KGIuZmxhZ3N8PTEwMjQpLGIubWVtb2l6ZWRQcm9wcz1kLGIubWVtb2l6ZWRTdGF0ZT1uKSxnLnByb3BzPWQsZy5zdGF0ZT1uLGcuY29udGV4dD1rLGQ9bCk6KFwiZnVuY3Rpb25cIiE9PXR5cGVvZiBnLmNvbXBvbmVudERpZFVwZGF0ZXx8aD09PWEubWVtb2l6ZWRQcm9wcyYmcj09PVxuYS5tZW1vaXplZFN0YXRlfHwoYi5mbGFnc3w9NCksXCJmdW5jdGlvblwiIT09dHlwZW9mIGcuZ2V0U25hcHNob3RCZWZvcmVVcGRhdGV8fGg9PT1hLm1lbW9pemVkUHJvcHMmJnI9PT1hLm1lbW9pemVkU3RhdGV8fChiLmZsYWdzfD0xMDI0KSxkPSExKX1yZXR1cm4ga2ooYSxiLGMsZCxmLGUpfVxuZnVuY3Rpb24ga2ooYSxiLGMsZCxlLGYpe2hqKGEsYik7dmFyIGc9MCE9PShiLmZsYWdzJjEyOCk7aWYoIWQmJiFnKXJldHVybiBlJiZkZyhiLGMsITEpLCRpKGEsYixmKTtkPWIuc3RhdGVOb2RlO1hpLmN1cnJlbnQ9Yjt2YXIgaD1nJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgYy5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3I/bnVsbDpkLnJlbmRlcigpO2IuZmxhZ3N8PTE7bnVsbCE9PWEmJmc/KGIuY2hpbGQ9QmgoYixhLmNoaWxkLG51bGwsZiksYi5jaGlsZD1CaChiLG51bGwsaCxmKSk6WWkoYSxiLGgsZik7Yi5tZW1vaXplZFN0YXRlPWQuc3RhdGU7ZSYmZGcoYixjLCEwKTtyZXR1cm4gYi5jaGlsZH1mdW5jdGlvbiBsaihhKXt2YXIgYj1hLnN0YXRlTm9kZTtiLnBlbmRpbmdDb250ZXh0P2FnKGEsYi5wZW5kaW5nQ29udGV4dCxiLnBlbmRpbmdDb250ZXh0IT09Yi5jb250ZXh0KTpiLmNvbnRleHQmJmFnKGEsYi5jb250ZXh0LCExKTtJaChhLGIuY29udGFpbmVySW5mbyl9XG5mdW5jdGlvbiBtaihhLGIsYyxkLGUpe0lnKCk7SmcoZSk7Yi5mbGFnc3w9MjU2O1lpKGEsYixjLGQpO3JldHVybiBiLmNoaWxkfXZhciBuaj17ZGVoeWRyYXRlZDpudWxsLHRyZWVDb250ZXh0Om51bGwscmV0cnlMYW5lOjB9O2Z1bmN0aW9uIG9qKGEpe3JldHVybntiYXNlTGFuZXM6YSxjYWNoZVBvb2w6bnVsbCx0cmFuc2l0aW9uczpudWxsfX1cbmZ1bmN0aW9uIHBqKGEsYixjKXt2YXIgZD1iLnBlbmRpbmdQcm9wcyxlPU0uY3VycmVudCxmPSExLGc9MCE9PShiLmZsYWdzJjEyOCksaDsoaD1nKXx8KGg9bnVsbCE9PWEmJm51bGw9PT1hLm1lbW9pemVkU3RhdGU/ITE6MCE9PShlJjIpKTtpZihoKWY9ITAsYi5mbGFncyY9LTEyOTtlbHNlIGlmKG51bGw9PT1hfHxudWxsIT09YS5tZW1vaXplZFN0YXRlKWV8PTE7RyhNLGUmMSk7aWYobnVsbD09PWEpe0VnKGIpO2E9Yi5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1hJiYoYT1hLmRlaHlkcmF0ZWQsbnVsbCE9PWEpKXJldHVybiAwPT09KGIubW9kZSYxKT9iLmxhbmVzPTE6XCIkIVwiPT09YS5kYXRhP2IubGFuZXM9ODpiLmxhbmVzPTEwNzM3NDE4MjQsbnVsbDtnPWQuY2hpbGRyZW47YT1kLmZhbGxiYWNrO3JldHVybiBmPyhkPWIubW9kZSxmPWIuY2hpbGQsZz17bW9kZTpcImhpZGRlblwiLGNoaWxkcmVuOmd9LDA9PT0oZCYxKSYmbnVsbCE9PWY/KGYuY2hpbGRMYW5lcz0wLGYucGVuZGluZ1Byb3BzPVxuZyk6Zj1xaihnLGQsMCxudWxsKSxhPUFoKGEsZCxjLG51bGwpLGYucmV0dXJuPWIsYS5yZXR1cm49YixmLnNpYmxpbmc9YSxiLmNoaWxkPWYsYi5jaGlsZC5tZW1vaXplZFN0YXRlPW9qKGMpLGIubWVtb2l6ZWRTdGF0ZT1uaixhKTpyaihiLGcpfWU9YS5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1lJiYoaD1lLmRlaHlkcmF0ZWQsbnVsbCE9PWgpKXJldHVybiBzaihhLGIsZyxkLGgsZSxjKTtpZihmKXtmPWQuZmFsbGJhY2s7Zz1iLm1vZGU7ZT1hLmNoaWxkO2g9ZS5zaWJsaW5nO3ZhciBrPXttb2RlOlwiaGlkZGVuXCIsY2hpbGRyZW46ZC5jaGlsZHJlbn07MD09PShnJjEpJiZiLmNoaWxkIT09ZT8oZD1iLmNoaWxkLGQuY2hpbGRMYW5lcz0wLGQucGVuZGluZ1Byb3BzPWssYi5kZWxldGlvbnM9bnVsbCk6KGQ9d2goZSxrKSxkLnN1YnRyZWVGbGFncz1lLnN1YnRyZWVGbGFncyYxNDY4MDA2NCk7bnVsbCE9PWg/Zj13aChoLGYpOihmPUFoKGYsZyxjLG51bGwpLGYuZmxhZ3N8PTIpO2YucmV0dXJuPVxuYjtkLnJldHVybj1iO2Quc2libGluZz1mO2IuY2hpbGQ9ZDtkPWY7Zj1iLmNoaWxkO2c9YS5jaGlsZC5tZW1vaXplZFN0YXRlO2c9bnVsbD09PWc/b2ooYyk6e2Jhc2VMYW5lczpnLmJhc2VMYW5lc3xjLGNhY2hlUG9vbDpudWxsLHRyYW5zaXRpb25zOmcudHJhbnNpdGlvbnN9O2YubWVtb2l6ZWRTdGF0ZT1nO2YuY2hpbGRMYW5lcz1hLmNoaWxkTGFuZXMmfmM7Yi5tZW1vaXplZFN0YXRlPW5qO3JldHVybiBkfWY9YS5jaGlsZDthPWYuc2libGluZztkPXdoKGYse21vZGU6XCJ2aXNpYmxlXCIsY2hpbGRyZW46ZC5jaGlsZHJlbn0pOzA9PT0oYi5tb2RlJjEpJiYoZC5sYW5lcz1jKTtkLnJldHVybj1iO2Quc2libGluZz1udWxsO251bGwhPT1hJiYoYz1iLmRlbGV0aW9ucyxudWxsPT09Yz8oYi5kZWxldGlvbnM9W2FdLGIuZmxhZ3N8PTE2KTpjLnB1c2goYSkpO2IuY2hpbGQ9ZDtiLm1lbW9pemVkU3RhdGU9bnVsbDtyZXR1cm4gZH1cbmZ1bmN0aW9uIHJqKGEsYil7Yj1xaih7bW9kZTpcInZpc2libGVcIixjaGlsZHJlbjpifSxhLm1vZGUsMCxudWxsKTtiLnJldHVybj1hO3JldHVybiBhLmNoaWxkPWJ9ZnVuY3Rpb24gdGooYSxiLGMsZCl7bnVsbCE9PWQmJkpnKGQpO0JoKGIsYS5jaGlsZCxudWxsLGMpO2E9cmooYixiLnBlbmRpbmdQcm9wcy5jaGlsZHJlbik7YS5mbGFnc3w9MjtiLm1lbW9pemVkU3RhdGU9bnVsbDtyZXR1cm4gYX1cbmZ1bmN0aW9uIHNqKGEsYixjLGQsZSxmLGcpe2lmKGMpe2lmKGIuZmxhZ3MmMjU2KXJldHVybiBiLmZsYWdzJj0tMjU3LGQ9TGkoRXJyb3IocCg0MjIpKSksdGooYSxiLGcsZCk7aWYobnVsbCE9PWIubWVtb2l6ZWRTdGF0ZSlyZXR1cm4gYi5jaGlsZD1hLmNoaWxkLGIuZmxhZ3N8PTEyOCxudWxsO2Y9ZC5mYWxsYmFjaztlPWIubW9kZTtkPXFqKHttb2RlOlwidmlzaWJsZVwiLGNoaWxkcmVuOmQuY2hpbGRyZW59LGUsMCxudWxsKTtmPUFoKGYsZSxnLG51bGwpO2YuZmxhZ3N8PTI7ZC5yZXR1cm49YjtmLnJldHVybj1iO2Quc2libGluZz1mO2IuY2hpbGQ9ZDswIT09KGIubW9kZSYxKSYmQmgoYixhLmNoaWxkLG51bGwsZyk7Yi5jaGlsZC5tZW1vaXplZFN0YXRlPW9qKGcpO2IubWVtb2l6ZWRTdGF0ZT1uajtyZXR1cm4gZn1pZigwPT09KGIubW9kZSYxKSlyZXR1cm4gdGooYSxiLGcsbnVsbCk7aWYoXCIkIVwiPT09ZS5kYXRhKXtkPWUubmV4dFNpYmxpbmcmJmUubmV4dFNpYmxpbmcuZGF0YXNldDtcbmlmKGQpdmFyIGg9ZC5kZ3N0O2Q9aDtmPUVycm9yKHAoNDE5KSk7ZD1MaShmLGQsdm9pZCAwKTtyZXR1cm4gdGooYSxiLGcsZCl9aD0wIT09KGcmYS5jaGlsZExhbmVzKTtpZihVZ3x8aCl7ZD1SO2lmKG51bGwhPT1kKXtzd2l0Y2goZyYtZyl7Y2FzZSA0OmU9MjticmVhaztjYXNlIDE2OmU9ODticmVhaztjYXNlIDY0OmNhc2UgMTI4OmNhc2UgMjU2OmNhc2UgNTEyOmNhc2UgMTAyNDpjYXNlIDIwNDg6Y2FzZSA0MDk2OmNhc2UgODE5MjpjYXNlIDE2Mzg0OmNhc2UgMzI3Njg6Y2FzZSA2NTUzNjpjYXNlIDEzMTA3MjpjYXNlIDI2MjE0NDpjYXNlIDUyNDI4ODpjYXNlIDEwNDg1NzY6Y2FzZSAyMDk3MTUyOmNhc2UgNDE5NDMwNDpjYXNlIDgzODg2MDg6Y2FzZSAxNjc3NzIxNjpjYXNlIDMzNTU0NDMyOmNhc2UgNjcxMDg4NjQ6ZT0zMjticmVhaztjYXNlIDUzNjg3MDkxMjplPTI2ODQzNTQ1NjticmVhaztkZWZhdWx0OmU9MH1lPTAhPT0oZSYoZC5zdXNwZW5kZWRMYW5lc3xnKSk/MDplO1xuMCE9PWUmJmUhPT1mLnJldHJ5TGFuZSYmKGYucmV0cnlMYW5lPWUsWmcoYSxlKSxtaChkLGEsZSwtMSkpfXVqKCk7ZD1MaShFcnJvcihwKDQyMSkpKTtyZXR1cm4gdGooYSxiLGcsZCl9aWYoXCIkP1wiPT09ZS5kYXRhKXJldHVybiBiLmZsYWdzfD0xMjgsYi5jaGlsZD1hLmNoaWxkLGI9dmouYmluZChudWxsLGEpLGUuX3JlYWN0UmV0cnk9YixudWxsO2E9Zi50cmVlQ29udGV4dDt5Zz1MZihlLm5leHRTaWJsaW5nKTt4Zz1iO0k9ITA7emc9bnVsbDtudWxsIT09YSYmKG9nW3BnKytdPXJnLG9nW3BnKytdPXNnLG9nW3BnKytdPXFnLHJnPWEuaWQsc2c9YS5vdmVyZmxvdyxxZz1iKTtiPXJqKGIsZC5jaGlsZHJlbik7Yi5mbGFnc3w9NDA5NjtyZXR1cm4gYn1mdW5jdGlvbiB3aihhLGIsYyl7YS5sYW5lc3w9Yjt2YXIgZD1hLmFsdGVybmF0ZTtudWxsIT09ZCYmKGQubGFuZXN8PWIpO1NnKGEucmV0dXJuLGIsYyl9XG5mdW5jdGlvbiB4aihhLGIsYyxkLGUpe3ZhciBmPWEubWVtb2l6ZWRTdGF0ZTtudWxsPT09Zj9hLm1lbW9pemVkU3RhdGU9e2lzQmFja3dhcmRzOmIscmVuZGVyaW5nOm51bGwscmVuZGVyaW5nU3RhcnRUaW1lOjAsbGFzdDpkLHRhaWw6Yyx0YWlsTW9kZTplfTooZi5pc0JhY2t3YXJkcz1iLGYucmVuZGVyaW5nPW51bGwsZi5yZW5kZXJpbmdTdGFydFRpbWU9MCxmLmxhc3Q9ZCxmLnRhaWw9YyxmLnRhaWxNb2RlPWUpfVxuZnVuY3Rpb24geWooYSxiLGMpe3ZhciBkPWIucGVuZGluZ1Byb3BzLGU9ZC5yZXZlYWxPcmRlcixmPWQudGFpbDtZaShhLGIsZC5jaGlsZHJlbixjKTtkPU0uY3VycmVudDtpZigwIT09KGQmMikpZD1kJjF8MixiLmZsYWdzfD0xMjg7ZWxzZXtpZihudWxsIT09YSYmMCE9PShhLmZsYWdzJjEyOCkpYTpmb3IoYT1iLmNoaWxkO251bGwhPT1hOyl7aWYoMTM9PT1hLnRhZyludWxsIT09YS5tZW1vaXplZFN0YXRlJiZ3aihhLGMsYik7ZWxzZSBpZigxOT09PWEudGFnKXdqKGEsYyxiKTtlbHNlIGlmKG51bGwhPT1hLmNoaWxkKXthLmNoaWxkLnJldHVybj1hO2E9YS5jaGlsZDtjb250aW51ZX1pZihhPT09YilicmVhayBhO2Zvcig7bnVsbD09PWEuc2libGluZzspe2lmKG51bGw9PT1hLnJldHVybnx8YS5yZXR1cm49PT1iKWJyZWFrIGE7YT1hLnJldHVybn1hLnNpYmxpbmcucmV0dXJuPWEucmV0dXJuO2E9YS5zaWJsaW5nfWQmPTF9RyhNLGQpO2lmKDA9PT0oYi5tb2RlJjEpKWIubWVtb2l6ZWRTdGF0ZT1cbm51bGw7ZWxzZSBzd2l0Y2goZSl7Y2FzZSBcImZvcndhcmRzXCI6Yz1iLmNoaWxkO2ZvcihlPW51bGw7bnVsbCE9PWM7KWE9Yy5hbHRlcm5hdGUsbnVsbCE9PWEmJm51bGw9PT1NaChhKSYmKGU9YyksYz1jLnNpYmxpbmc7Yz1lO251bGw9PT1jPyhlPWIuY2hpbGQsYi5jaGlsZD1udWxsKTooZT1jLnNpYmxpbmcsYy5zaWJsaW5nPW51bGwpO3hqKGIsITEsZSxjLGYpO2JyZWFrO2Nhc2UgXCJiYWNrd2FyZHNcIjpjPW51bGw7ZT1iLmNoaWxkO2ZvcihiLmNoaWxkPW51bGw7bnVsbCE9PWU7KXthPWUuYWx0ZXJuYXRlO2lmKG51bGwhPT1hJiZudWxsPT09TWgoYSkpe2IuY2hpbGQ9ZTticmVha31hPWUuc2libGluZztlLnNpYmxpbmc9YztjPWU7ZT1hfXhqKGIsITAsYyxudWxsLGYpO2JyZWFrO2Nhc2UgXCJ0b2dldGhlclwiOnhqKGIsITEsbnVsbCxudWxsLHZvaWQgMCk7YnJlYWs7ZGVmYXVsdDpiLm1lbW9pemVkU3RhdGU9bnVsbH1yZXR1cm4gYi5jaGlsZH1cbmZ1bmN0aW9uIGpqKGEsYil7MD09PShiLm1vZGUmMSkmJm51bGwhPT1hJiYoYS5hbHRlcm5hdGU9bnVsbCxiLmFsdGVybmF0ZT1udWxsLGIuZmxhZ3N8PTIpfWZ1bmN0aW9uICRpKGEsYixjKXtudWxsIT09YSYmKGIuZGVwZW5kZW5jaWVzPWEuZGVwZW5kZW5jaWVzKTtoaHw9Yi5sYW5lcztpZigwPT09KGMmYi5jaGlsZExhbmVzKSlyZXR1cm4gbnVsbDtpZihudWxsIT09YSYmYi5jaGlsZCE9PWEuY2hpbGQpdGhyb3cgRXJyb3IocCgxNTMpKTtpZihudWxsIT09Yi5jaGlsZCl7YT1iLmNoaWxkO2M9d2goYSxhLnBlbmRpbmdQcm9wcyk7Yi5jaGlsZD1jO2ZvcihjLnJldHVybj1iO251bGwhPT1hLnNpYmxpbmc7KWE9YS5zaWJsaW5nLGM9Yy5zaWJsaW5nPXdoKGEsYS5wZW5kaW5nUHJvcHMpLGMucmV0dXJuPWI7Yy5zaWJsaW5nPW51bGx9cmV0dXJuIGIuY2hpbGR9XG5mdW5jdGlvbiB6aihhLGIsYyl7c3dpdGNoKGIudGFnKXtjYXNlIDM6bGooYik7SWcoKTticmVhaztjYXNlIDU6S2goYik7YnJlYWs7Y2FzZSAxOlpmKGIudHlwZSkmJmNnKGIpO2JyZWFrO2Nhc2UgNDpJaChiLGIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8pO2JyZWFrO2Nhc2UgMTA6dmFyIGQ9Yi50eXBlLl9jb250ZXh0LGU9Yi5tZW1vaXplZFByb3BzLnZhbHVlO0coTWcsZC5fY3VycmVudFZhbHVlKTtkLl9jdXJyZW50VmFsdWU9ZTticmVhaztjYXNlIDEzOmQ9Yi5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1kKXtpZihudWxsIT09ZC5kZWh5ZHJhdGVkKXJldHVybiBHKE0sTS5jdXJyZW50JjEpLGIuZmxhZ3N8PTEyOCxudWxsO2lmKDAhPT0oYyZiLmNoaWxkLmNoaWxkTGFuZXMpKXJldHVybiBwaihhLGIsYyk7RyhNLE0uY3VycmVudCYxKTthPSRpKGEsYixjKTtyZXR1cm4gbnVsbCE9PWE/YS5zaWJsaW5nOm51bGx9RyhNLE0uY3VycmVudCYxKTticmVhaztjYXNlIDE5OmQ9MCE9PShjJlxuYi5jaGlsZExhbmVzKTtpZigwIT09KGEuZmxhZ3MmMTI4KSl7aWYoZClyZXR1cm4geWooYSxiLGMpO2IuZmxhZ3N8PTEyOH1lPWIubWVtb2l6ZWRTdGF0ZTtudWxsIT09ZSYmKGUucmVuZGVyaW5nPW51bGwsZS50YWlsPW51bGwsZS5sYXN0RWZmZWN0PW51bGwpO0coTSxNLmN1cnJlbnQpO2lmKGQpYnJlYWs7ZWxzZSByZXR1cm4gbnVsbDtjYXNlIDIyOmNhc2UgMjM6cmV0dXJuIGIubGFuZXM9MCxlaihhLGIsYyl9cmV0dXJuICRpKGEsYixjKX12YXIgQWosQmosQ2osRGo7XG5Baj1mdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1iLmNoaWxkO251bGwhPT1jOyl7aWYoNT09PWMudGFnfHw2PT09Yy50YWcpYS5hcHBlbmRDaGlsZChjLnN0YXRlTm9kZSk7ZWxzZSBpZig0IT09Yy50YWcmJm51bGwhPT1jLmNoaWxkKXtjLmNoaWxkLnJldHVybj1jO2M9Yy5jaGlsZDtjb250aW51ZX1pZihjPT09YilicmVhaztmb3IoO251bGw9PT1jLnNpYmxpbmc7KXtpZihudWxsPT09Yy5yZXR1cm58fGMucmV0dXJuPT09YilyZXR1cm47Yz1jLnJldHVybn1jLnNpYmxpbmcucmV0dXJuPWMucmV0dXJuO2M9Yy5zaWJsaW5nfX07Qmo9ZnVuY3Rpb24oKXt9O1xuQ2o9ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9YS5tZW1vaXplZFByb3BzO2lmKGUhPT1kKXthPWIuc3RhdGVOb2RlO0hoKEVoLmN1cnJlbnQpO3ZhciBmPW51bGw7c3dpdGNoKGMpe2Nhc2UgXCJpbnB1dFwiOmU9WWEoYSxlKTtkPVlhKGEsZCk7Zj1bXTticmVhaztjYXNlIFwic2VsZWN0XCI6ZT1BKHt9LGUse3ZhbHVlOnZvaWQgMH0pO2Q9QSh7fSxkLHt2YWx1ZTp2b2lkIDB9KTtmPVtdO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmU9Z2IoYSxlKTtkPWdiKGEsZCk7Zj1bXTticmVhaztkZWZhdWx0OlwiZnVuY3Rpb25cIiE9PXR5cGVvZiBlLm9uQ2xpY2smJlwiZnVuY3Rpb25cIj09PXR5cGVvZiBkLm9uQ2xpY2smJihhLm9uY2xpY2s9QmYpfXViKGMsZCk7dmFyIGc7Yz1udWxsO2ZvcihsIGluIGUpaWYoIWQuaGFzT3duUHJvcGVydHkobCkmJmUuaGFzT3duUHJvcGVydHkobCkmJm51bGwhPWVbbF0paWYoXCJzdHlsZVwiPT09bCl7dmFyIGg9ZVtsXTtmb3IoZyBpbiBoKWguaGFzT3duUHJvcGVydHkoZykmJlxuKGN8fChjPXt9KSxjW2ddPVwiXCIpfWVsc2VcImRhbmdlcm91c2x5U2V0SW5uZXJIVE1MXCIhPT1sJiZcImNoaWxkcmVuXCIhPT1sJiZcInN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZ1wiIT09bCYmXCJzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmdcIiE9PWwmJlwiYXV0b0ZvY3VzXCIhPT1sJiYoZWEuaGFzT3duUHJvcGVydHkobCk/Znx8KGY9W10pOihmPWZ8fFtdKS5wdXNoKGwsbnVsbCkpO2ZvcihsIGluIGQpe3ZhciBrPWRbbF07aD1udWxsIT1lP2VbbF06dm9pZCAwO2lmKGQuaGFzT3duUHJvcGVydHkobCkmJmshPT1oJiYobnVsbCE9a3x8bnVsbCE9aCkpaWYoXCJzdHlsZVwiPT09bClpZihoKXtmb3IoZyBpbiBoKSFoLmhhc093blByb3BlcnR5KGcpfHxrJiZrLmhhc093blByb3BlcnR5KGcpfHwoY3x8KGM9e30pLGNbZ109XCJcIik7Zm9yKGcgaW4gaylrLmhhc093blByb3BlcnR5KGcpJiZoW2ddIT09a1tnXSYmKGN8fChjPXt9KSxjW2ddPWtbZ10pfWVsc2UgY3x8KGZ8fChmPVtdKSxmLnB1c2gobCxcbmMpKSxjPWs7ZWxzZVwiZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUxcIj09PWw/KGs9az9rLl9faHRtbDp2b2lkIDAsaD1oP2guX19odG1sOnZvaWQgMCxudWxsIT1rJiZoIT09ayYmKGY9Znx8W10pLnB1c2gobCxrKSk6XCJjaGlsZHJlblwiPT09bD9cInN0cmluZ1wiIT09dHlwZW9mIGsmJlwibnVtYmVyXCIhPT10eXBlb2Yga3x8KGY9Znx8W10pLnB1c2gobCxcIlwiK2spOlwic3VwcHJlc3NDb250ZW50RWRpdGFibGVXYXJuaW5nXCIhPT1sJiZcInN1cHByZXNzSHlkcmF0aW9uV2FybmluZ1wiIT09bCYmKGVhLmhhc093blByb3BlcnR5KGwpPyhudWxsIT1rJiZcIm9uU2Nyb2xsXCI9PT1sJiZEKFwic2Nyb2xsXCIsYSksZnx8aD09PWt8fChmPVtdKSk6KGY9Znx8W10pLnB1c2gobCxrKSl9YyYmKGY9Znx8W10pLnB1c2goXCJzdHlsZVwiLGMpO3ZhciBsPWY7aWYoYi51cGRhdGVRdWV1ZT1sKWIuZmxhZ3N8PTR9fTtEaj1mdW5jdGlvbihhLGIsYyxkKXtjIT09ZCYmKGIuZmxhZ3N8PTQpfTtcbmZ1bmN0aW9uIEVqKGEsYil7aWYoIUkpc3dpdGNoKGEudGFpbE1vZGUpe2Nhc2UgXCJoaWRkZW5cIjpiPWEudGFpbDtmb3IodmFyIGM9bnVsbDtudWxsIT09YjspbnVsbCE9PWIuYWx0ZXJuYXRlJiYoYz1iKSxiPWIuc2libGluZztudWxsPT09Yz9hLnRhaWw9bnVsbDpjLnNpYmxpbmc9bnVsbDticmVhaztjYXNlIFwiY29sbGFwc2VkXCI6Yz1hLnRhaWw7Zm9yKHZhciBkPW51bGw7bnVsbCE9PWM7KW51bGwhPT1jLmFsdGVybmF0ZSYmKGQ9YyksYz1jLnNpYmxpbmc7bnVsbD09PWQ/Ynx8bnVsbD09PWEudGFpbD9hLnRhaWw9bnVsbDphLnRhaWwuc2libGluZz1udWxsOmQuc2libGluZz1udWxsfX1cbmZ1bmN0aW9uIFMoYSl7dmFyIGI9bnVsbCE9PWEuYWx0ZXJuYXRlJiZhLmFsdGVybmF0ZS5jaGlsZD09PWEuY2hpbGQsYz0wLGQ9MDtpZihiKWZvcih2YXIgZT1hLmNoaWxkO251bGwhPT1lOyljfD1lLmxhbmVzfGUuY2hpbGRMYW5lcyxkfD1lLnN1YnRyZWVGbGFncyYxNDY4MDA2NCxkfD1lLmZsYWdzJjE0NjgwMDY0LGUucmV0dXJuPWEsZT1lLnNpYmxpbmc7ZWxzZSBmb3IoZT1hLmNoaWxkO251bGwhPT1lOyljfD1lLmxhbmVzfGUuY2hpbGRMYW5lcyxkfD1lLnN1YnRyZWVGbGFncyxkfD1lLmZsYWdzLGUucmV0dXJuPWEsZT1lLnNpYmxpbmc7YS5zdWJ0cmVlRmxhZ3N8PWQ7YS5jaGlsZExhbmVzPWM7cmV0dXJuIGJ9XG5mdW5jdGlvbiBGaihhLGIsYyl7dmFyIGQ9Yi5wZW5kaW5nUHJvcHM7d2coYik7c3dpdGNoKGIudGFnKXtjYXNlIDI6Y2FzZSAxNjpjYXNlIDE1OmNhc2UgMDpjYXNlIDExOmNhc2UgNzpjYXNlIDg6Y2FzZSAxMjpjYXNlIDk6Y2FzZSAxNDpyZXR1cm4gUyhiKSxudWxsO2Nhc2UgMTpyZXR1cm4gWmYoYi50eXBlKSYmJGYoKSxTKGIpLG51bGw7Y2FzZSAzOmQ9Yi5zdGF0ZU5vZGU7SmgoKTtFKFdmKTtFKEgpO09oKCk7ZC5wZW5kaW5nQ29udGV4dCYmKGQuY29udGV4dD1kLnBlbmRpbmdDb250ZXh0LGQucGVuZGluZ0NvbnRleHQ9bnVsbCk7aWYobnVsbD09PWF8fG51bGw9PT1hLmNoaWxkKUdnKGIpP2IuZmxhZ3N8PTQ6bnVsbD09PWF8fGEubWVtb2l6ZWRTdGF0ZS5pc0RlaHlkcmF0ZWQmJjA9PT0oYi5mbGFncyYyNTYpfHwoYi5mbGFnc3w9MTAyNCxudWxsIT09emcmJihHaih6Zyksemc9bnVsbCkpO0JqKGEsYik7UyhiKTtyZXR1cm4gbnVsbDtjYXNlIDU6TGgoYik7dmFyIGU9SGgoR2guY3VycmVudCk7XG5jPWIudHlwZTtpZihudWxsIT09YSYmbnVsbCE9Yi5zdGF0ZU5vZGUpQ2ooYSxiLGMsZCxlKSxhLnJlZiE9PWIucmVmJiYoYi5mbGFnc3w9NTEyLGIuZmxhZ3N8PTIwOTcxNTIpO2Vsc2V7aWYoIWQpe2lmKG51bGw9PT1iLnN0YXRlTm9kZSl0aHJvdyBFcnJvcihwKDE2NikpO1MoYik7cmV0dXJuIG51bGx9YT1IaChFaC5jdXJyZW50KTtpZihHZyhiKSl7ZD1iLnN0YXRlTm9kZTtjPWIudHlwZTt2YXIgZj1iLm1lbW9pemVkUHJvcHM7ZFtPZl09YjtkW1BmXT1mO2E9MCE9PShiLm1vZGUmMSk7c3dpdGNoKGMpe2Nhc2UgXCJkaWFsb2dcIjpEKFwiY2FuY2VsXCIsZCk7RChcImNsb3NlXCIsZCk7YnJlYWs7Y2FzZSBcImlmcmFtZVwiOmNhc2UgXCJvYmplY3RcIjpjYXNlIFwiZW1iZWRcIjpEKFwibG9hZFwiLGQpO2JyZWFrO2Nhc2UgXCJ2aWRlb1wiOmNhc2UgXCJhdWRpb1wiOmZvcihlPTA7ZTxsZi5sZW5ndGg7ZSsrKUQobGZbZV0sZCk7YnJlYWs7Y2FzZSBcInNvdXJjZVwiOkQoXCJlcnJvclwiLGQpO2JyZWFrO2Nhc2UgXCJpbWdcIjpjYXNlIFwiaW1hZ2VcIjpjYXNlIFwibGlua1wiOkQoXCJlcnJvclwiLFxuZCk7RChcImxvYWRcIixkKTticmVhaztjYXNlIFwiZGV0YWlsc1wiOkQoXCJ0b2dnbGVcIixkKTticmVhaztjYXNlIFwiaW5wdXRcIjpaYShkLGYpO0QoXCJpbnZhbGlkXCIsZCk7YnJlYWs7Y2FzZSBcInNlbGVjdFwiOmQuX3dyYXBwZXJTdGF0ZT17d2FzTXVsdGlwbGU6ISFmLm11bHRpcGxlfTtEKFwiaW52YWxpZFwiLGQpO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmhiKGQsZiksRChcImludmFsaWRcIixkKX11YihjLGYpO2U9bnVsbDtmb3IodmFyIGcgaW4gZilpZihmLmhhc093blByb3BlcnR5KGcpKXt2YXIgaD1mW2ddO1wiY2hpbGRyZW5cIj09PWc/XCJzdHJpbmdcIj09PXR5cGVvZiBoP2QudGV4dENvbnRlbnQhPT1oJiYoITAhPT1mLnN1cHByZXNzSHlkcmF0aW9uV2FybmluZyYmQWYoZC50ZXh0Q29udGVudCxoLGEpLGU9W1wiY2hpbGRyZW5cIixoXSk6XCJudW1iZXJcIj09PXR5cGVvZiBoJiZkLnRleHRDb250ZW50IT09XCJcIitoJiYoITAhPT1mLnN1cHByZXNzSHlkcmF0aW9uV2FybmluZyYmQWYoZC50ZXh0Q29udGVudCxcbmgsYSksZT1bXCJjaGlsZHJlblwiLFwiXCIraF0pOmVhLmhhc093blByb3BlcnR5KGcpJiZudWxsIT1oJiZcIm9uU2Nyb2xsXCI9PT1nJiZEKFwic2Nyb2xsXCIsZCl9c3dpdGNoKGMpe2Nhc2UgXCJpbnB1dFwiOlZhKGQpO2RiKGQsZiwhMCk7YnJlYWs7Y2FzZSBcInRleHRhcmVhXCI6VmEoZCk7amIoZCk7YnJlYWs7Y2FzZSBcInNlbGVjdFwiOmNhc2UgXCJvcHRpb25cIjpicmVhaztkZWZhdWx0OlwiZnVuY3Rpb25cIj09PXR5cGVvZiBmLm9uQ2xpY2smJihkLm9uY2xpY2s9QmYpfWQ9ZTtiLnVwZGF0ZVF1ZXVlPWQ7bnVsbCE9PWQmJihiLmZsYWdzfD00KX1lbHNle2c9OT09PWUubm9kZVR5cGU/ZTplLm93bmVyRG9jdW1lbnQ7XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI9PT1hJiYoYT1rYihjKSk7XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI9PT1hP1wic2NyaXB0XCI9PT1jPyhhPWcuY3JlYXRlRWxlbWVudChcImRpdlwiKSxhLmlubmVySFRNTD1cIjxzY3JpcHQ+XFx4M2Mvc2NyaXB0PlwiLGE9YS5yZW1vdmVDaGlsZChhLmZpcnN0Q2hpbGQpKTpcblwic3RyaW5nXCI9PT10eXBlb2YgZC5pcz9hPWcuY3JlYXRlRWxlbWVudChjLHtpczpkLmlzfSk6KGE9Zy5jcmVhdGVFbGVtZW50KGMpLFwic2VsZWN0XCI9PT1jJiYoZz1hLGQubXVsdGlwbGU/Zy5tdWx0aXBsZT0hMDpkLnNpemUmJihnLnNpemU9ZC5zaXplKSkpOmE9Zy5jcmVhdGVFbGVtZW50TlMoYSxjKTthW09mXT1iO2FbUGZdPWQ7QWooYSxiLCExLCExKTtiLnN0YXRlTm9kZT1hO2E6e2c9dmIoYyxkKTtzd2l0Y2goYyl7Y2FzZSBcImRpYWxvZ1wiOkQoXCJjYW5jZWxcIixhKTtEKFwiY2xvc2VcIixhKTtlPWQ7YnJlYWs7Y2FzZSBcImlmcmFtZVwiOmNhc2UgXCJvYmplY3RcIjpjYXNlIFwiZW1iZWRcIjpEKFwibG9hZFwiLGEpO2U9ZDticmVhaztjYXNlIFwidmlkZW9cIjpjYXNlIFwiYXVkaW9cIjpmb3IoZT0wO2U8bGYubGVuZ3RoO2UrKylEKGxmW2VdLGEpO2U9ZDticmVhaztjYXNlIFwic291cmNlXCI6RChcImVycm9yXCIsYSk7ZT1kO2JyZWFrO2Nhc2UgXCJpbWdcIjpjYXNlIFwiaW1hZ2VcIjpjYXNlIFwibGlua1wiOkQoXCJlcnJvclwiLFxuYSk7RChcImxvYWRcIixhKTtlPWQ7YnJlYWs7Y2FzZSBcImRldGFpbHNcIjpEKFwidG9nZ2xlXCIsYSk7ZT1kO2JyZWFrO2Nhc2UgXCJpbnB1dFwiOlphKGEsZCk7ZT1ZYShhLGQpO0QoXCJpbnZhbGlkXCIsYSk7YnJlYWs7Y2FzZSBcIm9wdGlvblwiOmU9ZDticmVhaztjYXNlIFwic2VsZWN0XCI6YS5fd3JhcHBlclN0YXRlPXt3YXNNdWx0aXBsZTohIWQubXVsdGlwbGV9O2U9QSh7fSxkLHt2YWx1ZTp2b2lkIDB9KTtEKFwiaW52YWxpZFwiLGEpO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmhiKGEsZCk7ZT1nYihhLGQpO0QoXCJpbnZhbGlkXCIsYSk7YnJlYWs7ZGVmYXVsdDplPWR9dWIoYyxlKTtoPWU7Zm9yKGYgaW4gaClpZihoLmhhc093blByb3BlcnR5KGYpKXt2YXIgaz1oW2ZdO1wic3R5bGVcIj09PWY/c2IoYSxrKTpcImRhbmdlcm91c2x5U2V0SW5uZXJIVE1MXCI9PT1mPyhrPWs/ay5fX2h0bWw6dm9pZCAwLG51bGwhPWsmJm5iKGEsaykpOlwiY2hpbGRyZW5cIj09PWY/XCJzdHJpbmdcIj09PXR5cGVvZiBrPyhcInRleHRhcmVhXCIhPT1cbmN8fFwiXCIhPT1rKSYmb2IoYSxrKTpcIm51bWJlclwiPT09dHlwZW9mIGsmJm9iKGEsXCJcIitrKTpcInN1cHByZXNzQ29udGVudEVkaXRhYmxlV2FybmluZ1wiIT09ZiYmXCJzdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmdcIiE9PWYmJlwiYXV0b0ZvY3VzXCIhPT1mJiYoZWEuaGFzT3duUHJvcGVydHkoZik/bnVsbCE9ayYmXCJvblNjcm9sbFwiPT09ZiYmRChcInNjcm9sbFwiLGEpOm51bGwhPWsmJnRhKGEsZixrLGcpKX1zd2l0Y2goYyl7Y2FzZSBcImlucHV0XCI6VmEoYSk7ZGIoYSxkLCExKTticmVhaztjYXNlIFwidGV4dGFyZWFcIjpWYShhKTtqYihhKTticmVhaztjYXNlIFwib3B0aW9uXCI6bnVsbCE9ZC52YWx1ZSYmYS5zZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiLFwiXCIrU2EoZC52YWx1ZSkpO2JyZWFrO2Nhc2UgXCJzZWxlY3RcIjphLm11bHRpcGxlPSEhZC5tdWx0aXBsZTtmPWQudmFsdWU7bnVsbCE9Zj9mYihhLCEhZC5tdWx0aXBsZSxmLCExKTpudWxsIT1kLmRlZmF1bHRWYWx1ZSYmZmIoYSwhIWQubXVsdGlwbGUsZC5kZWZhdWx0VmFsdWUsXG4hMCk7YnJlYWs7ZGVmYXVsdDpcImZ1bmN0aW9uXCI9PT10eXBlb2YgZS5vbkNsaWNrJiYoYS5vbmNsaWNrPUJmKX1zd2l0Y2goYyl7Y2FzZSBcImJ1dHRvblwiOmNhc2UgXCJpbnB1dFwiOmNhc2UgXCJzZWxlY3RcIjpjYXNlIFwidGV4dGFyZWFcIjpkPSEhZC5hdXRvRm9jdXM7YnJlYWsgYTtjYXNlIFwiaW1nXCI6ZD0hMDticmVhayBhO2RlZmF1bHQ6ZD0hMX19ZCYmKGIuZmxhZ3N8PTQpfW51bGwhPT1iLnJlZiYmKGIuZmxhZ3N8PTUxMixiLmZsYWdzfD0yMDk3MTUyKX1TKGIpO3JldHVybiBudWxsO2Nhc2UgNjppZihhJiZudWxsIT1iLnN0YXRlTm9kZSlEaihhLGIsYS5tZW1vaXplZFByb3BzLGQpO2Vsc2V7aWYoXCJzdHJpbmdcIiE9PXR5cGVvZiBkJiZudWxsPT09Yi5zdGF0ZU5vZGUpdGhyb3cgRXJyb3IocCgxNjYpKTtjPUhoKEdoLmN1cnJlbnQpO0hoKEVoLmN1cnJlbnQpO2lmKEdnKGIpKXtkPWIuc3RhdGVOb2RlO2M9Yi5tZW1vaXplZFByb3BzO2RbT2ZdPWI7aWYoZj1kLm5vZGVWYWx1ZSE9PWMpaWYoYT1cbnhnLG51bGwhPT1hKXN3aXRjaChhLnRhZyl7Y2FzZSAzOkFmKGQubm9kZVZhbHVlLGMsMCE9PShhLm1vZGUmMSkpO2JyZWFrO2Nhc2UgNTohMCE9PWEubWVtb2l6ZWRQcm9wcy5zdXBwcmVzc0h5ZHJhdGlvbldhcm5pbmcmJkFmKGQubm9kZVZhbHVlLGMsMCE9PShhLm1vZGUmMSkpfWYmJihiLmZsYWdzfD00KX1lbHNlIGQ9KDk9PT1jLm5vZGVUeXBlP2M6Yy5vd25lckRvY3VtZW50KS5jcmVhdGVUZXh0Tm9kZShkKSxkW09mXT1iLGIuc3RhdGVOb2RlPWR9UyhiKTtyZXR1cm4gbnVsbDtjYXNlIDEzOkUoTSk7ZD1iLm1lbW9pemVkU3RhdGU7aWYobnVsbD09PWF8fG51bGwhPT1hLm1lbW9pemVkU3RhdGUmJm51bGwhPT1hLm1lbW9pemVkU3RhdGUuZGVoeWRyYXRlZCl7aWYoSSYmbnVsbCE9PXlnJiYwIT09KGIubW9kZSYxKSYmMD09PShiLmZsYWdzJjEyOCkpSGcoKSxJZygpLGIuZmxhZ3N8PTk4NTYwLGY9ITE7ZWxzZSBpZihmPUdnKGIpLG51bGwhPT1kJiZudWxsIT09ZC5kZWh5ZHJhdGVkKXtpZihudWxsPT09XG5hKXtpZighZil0aHJvdyBFcnJvcihwKDMxOCkpO2Y9Yi5tZW1vaXplZFN0YXRlO2Y9bnVsbCE9PWY/Zi5kZWh5ZHJhdGVkOm51bGw7aWYoIWYpdGhyb3cgRXJyb3IocCgzMTcpKTtmW09mXT1ifWVsc2UgSWcoKSwwPT09KGIuZmxhZ3MmMTI4KSYmKGIubWVtb2l6ZWRTdGF0ZT1udWxsKSxiLmZsYWdzfD00O1MoYik7Zj0hMX1lbHNlIG51bGwhPT16ZyYmKEdqKHpnKSx6Zz1udWxsKSxmPSEwO2lmKCFmKXJldHVybiBiLmZsYWdzJjY1NTM2P2I6bnVsbH1pZigwIT09KGIuZmxhZ3MmMTI4KSlyZXR1cm4gYi5sYW5lcz1jLGI7ZD1udWxsIT09ZDtkIT09KG51bGwhPT1hJiZudWxsIT09YS5tZW1vaXplZFN0YXRlKSYmZCYmKGIuY2hpbGQuZmxhZ3N8PTgxOTIsMCE9PShiLm1vZGUmMSkmJihudWxsPT09YXx8MCE9PShNLmN1cnJlbnQmMSk/MD09PVQmJihUPTMpOnVqKCkpKTtudWxsIT09Yi51cGRhdGVRdWV1ZSYmKGIuZmxhZ3N8PTQpO1MoYik7cmV0dXJuIG51bGw7Y2FzZSA0OnJldHVybiBKaCgpLFxuQmooYSxiKSxudWxsPT09YSYmc2YoYi5zdGF0ZU5vZGUuY29udGFpbmVySW5mbyksUyhiKSxudWxsO2Nhc2UgMTA6cmV0dXJuIFJnKGIudHlwZS5fY29udGV4dCksUyhiKSxudWxsO2Nhc2UgMTc6cmV0dXJuIFpmKGIudHlwZSkmJiRmKCksUyhiKSxudWxsO2Nhc2UgMTk6RShNKTtmPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsPT09ZilyZXR1cm4gUyhiKSxudWxsO2Q9MCE9PShiLmZsYWdzJjEyOCk7Zz1mLnJlbmRlcmluZztpZihudWxsPT09ZylpZihkKUVqKGYsITEpO2Vsc2V7aWYoMCE9PVR8fG51bGwhPT1hJiYwIT09KGEuZmxhZ3MmMTI4KSlmb3IoYT1iLmNoaWxkO251bGwhPT1hOyl7Zz1NaChhKTtpZihudWxsIT09Zyl7Yi5mbGFnc3w9MTI4O0VqKGYsITEpO2Q9Zy51cGRhdGVRdWV1ZTtudWxsIT09ZCYmKGIudXBkYXRlUXVldWU9ZCxiLmZsYWdzfD00KTtiLnN1YnRyZWVGbGFncz0wO2Q9Yztmb3IoYz1iLmNoaWxkO251bGwhPT1jOylmPWMsYT1kLGYuZmxhZ3MmPTE0NjgwMDY2LFxuZz1mLmFsdGVybmF0ZSxudWxsPT09Zz8oZi5jaGlsZExhbmVzPTAsZi5sYW5lcz1hLGYuY2hpbGQ9bnVsbCxmLnN1YnRyZWVGbGFncz0wLGYubWVtb2l6ZWRQcm9wcz1udWxsLGYubWVtb2l6ZWRTdGF0ZT1udWxsLGYudXBkYXRlUXVldWU9bnVsbCxmLmRlcGVuZGVuY2llcz1udWxsLGYuc3RhdGVOb2RlPW51bGwpOihmLmNoaWxkTGFuZXM9Zy5jaGlsZExhbmVzLGYubGFuZXM9Zy5sYW5lcyxmLmNoaWxkPWcuY2hpbGQsZi5zdWJ0cmVlRmxhZ3M9MCxmLmRlbGV0aW9ucz1udWxsLGYubWVtb2l6ZWRQcm9wcz1nLm1lbW9pemVkUHJvcHMsZi5tZW1vaXplZFN0YXRlPWcubWVtb2l6ZWRTdGF0ZSxmLnVwZGF0ZVF1ZXVlPWcudXBkYXRlUXVldWUsZi50eXBlPWcudHlwZSxhPWcuZGVwZW5kZW5jaWVzLGYuZGVwZW5kZW5jaWVzPW51bGw9PT1hP251bGw6e2xhbmVzOmEubGFuZXMsZmlyc3RDb250ZXh0OmEuZmlyc3RDb250ZXh0fSksYz1jLnNpYmxpbmc7RyhNLE0uY3VycmVudCYxfDIpO3JldHVybiBiLmNoaWxkfWE9XG5hLnNpYmxpbmd9bnVsbCE9PWYudGFpbCYmQigpPkhqJiYoYi5mbGFnc3w9MTI4LGQ9ITAsRWooZiwhMSksYi5sYW5lcz00MTk0MzA0KX1lbHNle2lmKCFkKWlmKGE9TWgoZyksbnVsbCE9PWEpe2lmKGIuZmxhZ3N8PTEyOCxkPSEwLGM9YS51cGRhdGVRdWV1ZSxudWxsIT09YyYmKGIudXBkYXRlUXVldWU9YyxiLmZsYWdzfD00KSxFaihmLCEwKSxudWxsPT09Zi50YWlsJiZcImhpZGRlblwiPT09Zi50YWlsTW9kZSYmIWcuYWx0ZXJuYXRlJiYhSSlyZXR1cm4gUyhiKSxudWxsfWVsc2UgMipCKCktZi5yZW5kZXJpbmdTdGFydFRpbWU+SGomJjEwNzM3NDE4MjQhPT1jJiYoYi5mbGFnc3w9MTI4LGQ9ITAsRWooZiwhMSksYi5sYW5lcz00MTk0MzA0KTtmLmlzQmFja3dhcmRzPyhnLnNpYmxpbmc9Yi5jaGlsZCxiLmNoaWxkPWcpOihjPWYubGFzdCxudWxsIT09Yz9jLnNpYmxpbmc9ZzpiLmNoaWxkPWcsZi5sYXN0PWcpfWlmKG51bGwhPT1mLnRhaWwpcmV0dXJuIGI9Zi50YWlsLGYucmVuZGVyaW5nPVxuYixmLnRhaWw9Yi5zaWJsaW5nLGYucmVuZGVyaW5nU3RhcnRUaW1lPUIoKSxiLnNpYmxpbmc9bnVsbCxjPU0uY3VycmVudCxHKE0sZD9jJjF8MjpjJjEpLGI7UyhiKTtyZXR1cm4gbnVsbDtjYXNlIDIyOmNhc2UgMjM6cmV0dXJuIElqKCksZD1udWxsIT09Yi5tZW1vaXplZFN0YXRlLG51bGwhPT1hJiZudWxsIT09YS5tZW1vaXplZFN0YXRlIT09ZCYmKGIuZmxhZ3N8PTgxOTIpLGQmJjAhPT0oYi5tb2RlJjEpPzAhPT0oZ2omMTA3Mzc0MTgyNCkmJihTKGIpLGIuc3VidHJlZUZsYWdzJjYmJihiLmZsYWdzfD04MTkyKSk6UyhiKSxudWxsO2Nhc2UgMjQ6cmV0dXJuIG51bGw7Y2FzZSAyNTpyZXR1cm4gbnVsbH10aHJvdyBFcnJvcihwKDE1NixiLnRhZykpO31cbmZ1bmN0aW9uIEpqKGEsYil7d2coYik7c3dpdGNoKGIudGFnKXtjYXNlIDE6cmV0dXJuIFpmKGIudHlwZSkmJiRmKCksYT1iLmZsYWdzLGEmNjU1MzY/KGIuZmxhZ3M9YSYtNjU1Mzd8MTI4LGIpOm51bGw7Y2FzZSAzOnJldHVybiBKaCgpLEUoV2YpLEUoSCksT2goKSxhPWIuZmxhZ3MsMCE9PShhJjY1NTM2KSYmMD09PShhJjEyOCk/KGIuZmxhZ3M9YSYtNjU1Mzd8MTI4LGIpOm51bGw7Y2FzZSA1OnJldHVybiBMaChiKSxudWxsO2Nhc2UgMTM6RShNKTthPWIubWVtb2l6ZWRTdGF0ZTtpZihudWxsIT09YSYmbnVsbCE9PWEuZGVoeWRyYXRlZCl7aWYobnVsbD09PWIuYWx0ZXJuYXRlKXRocm93IEVycm9yKHAoMzQwKSk7SWcoKX1hPWIuZmxhZ3M7cmV0dXJuIGEmNjU1MzY/KGIuZmxhZ3M9YSYtNjU1Mzd8MTI4LGIpOm51bGw7Y2FzZSAxOTpyZXR1cm4gRShNKSxudWxsO2Nhc2UgNDpyZXR1cm4gSmgoKSxudWxsO2Nhc2UgMTA6cmV0dXJuIFJnKGIudHlwZS5fY29udGV4dCksbnVsbDtjYXNlIDIyOmNhc2UgMjM6cmV0dXJuIElqKCksXG5udWxsO2Nhc2UgMjQ6cmV0dXJuIG51bGw7ZGVmYXVsdDpyZXR1cm4gbnVsbH19dmFyIEtqPSExLFU9ITEsTGo9XCJmdW5jdGlvblwiPT09dHlwZW9mIFdlYWtTZXQ/V2Vha1NldDpTZXQsVj1udWxsO2Z1bmN0aW9uIE1qKGEsYil7dmFyIGM9YS5yZWY7aWYobnVsbCE9PWMpaWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGMpdHJ5e2MobnVsbCl9Y2F0Y2goZCl7VyhhLGIsZCl9ZWxzZSBjLmN1cnJlbnQ9bnVsbH1mdW5jdGlvbiBOaihhLGIsYyl7dHJ5e2MoKX1jYXRjaChkKXtXKGEsYixkKX19dmFyIE9qPSExO1xuZnVuY3Rpb24gUGooYSxiKXtDZj1kZDthPU1lKCk7aWYoTmUoYSkpe2lmKFwic2VsZWN0aW9uU3RhcnRcImluIGEpdmFyIGM9e3N0YXJ0OmEuc2VsZWN0aW9uU3RhcnQsZW5kOmEuc2VsZWN0aW9uRW5kfTtlbHNlIGE6e2M9KGM9YS5vd25lckRvY3VtZW50KSYmYy5kZWZhdWx0Vmlld3x8d2luZG93O3ZhciBkPWMuZ2V0U2VsZWN0aW9uJiZjLmdldFNlbGVjdGlvbigpO2lmKGQmJjAhPT1kLnJhbmdlQ291bnQpe2M9ZC5hbmNob3JOb2RlO3ZhciBlPWQuYW5jaG9yT2Zmc2V0LGY9ZC5mb2N1c05vZGU7ZD1kLmZvY3VzT2Zmc2V0O3RyeXtjLm5vZGVUeXBlLGYubm9kZVR5cGV9Y2F0Y2goRil7Yz1udWxsO2JyZWFrIGF9dmFyIGc9MCxoPS0xLGs9LTEsbD0wLG09MCxxPWEscj1udWxsO2I6Zm9yKDs7KXtmb3IodmFyIHk7Oyl7cSE9PWN8fDAhPT1lJiYzIT09cS5ub2RlVHlwZXx8KGg9ZytlKTtxIT09Znx8MCE9PWQmJjMhPT1xLm5vZGVUeXBlfHwoaz1nK2QpOzM9PT1xLm5vZGVUeXBlJiYoZys9XG5xLm5vZGVWYWx1ZS5sZW5ndGgpO2lmKG51bGw9PT0oeT1xLmZpcnN0Q2hpbGQpKWJyZWFrO3I9cTtxPXl9Zm9yKDs7KXtpZihxPT09YSlicmVhayBiO3I9PT1jJiYrK2w9PT1lJiYoaD1nKTtyPT09ZiYmKyttPT09ZCYmKGs9Zyk7aWYobnVsbCE9PSh5PXEubmV4dFNpYmxpbmcpKWJyZWFrO3E9cjtyPXEucGFyZW50Tm9kZX1xPXl9Yz0tMT09PWh8fC0xPT09az9udWxsOntzdGFydDpoLGVuZDprfX1lbHNlIGM9bnVsbH1jPWN8fHtzdGFydDowLGVuZDowfX1lbHNlIGM9bnVsbDtEZj17Zm9jdXNlZEVsZW06YSxzZWxlY3Rpb25SYW5nZTpjfTtkZD0hMTtmb3IoVj1iO251bGwhPT1WOylpZihiPVYsYT1iLmNoaWxkLDAhPT0oYi5zdWJ0cmVlRmxhZ3MmMTAyOCkmJm51bGwhPT1hKWEucmV0dXJuPWIsVj1hO2Vsc2UgZm9yKDtudWxsIT09Vjspe2I9Vjt0cnl7dmFyIG49Yi5hbHRlcm5hdGU7aWYoMCE9PShiLmZsYWdzJjEwMjQpKXN3aXRjaChiLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNTpicmVhaztcbmNhc2UgMTppZihudWxsIT09bil7dmFyIHQ9bi5tZW1vaXplZFByb3BzLEo9bi5tZW1vaXplZFN0YXRlLHg9Yi5zdGF0ZU5vZGUsdz14LmdldFNuYXBzaG90QmVmb3JlVXBkYXRlKGIuZWxlbWVudFR5cGU9PT1iLnR5cGU/dDpMZyhiLnR5cGUsdCksSik7eC5fX3JlYWN0SW50ZXJuYWxTbmFwc2hvdEJlZm9yZVVwZGF0ZT13fWJyZWFrO2Nhc2UgMzp2YXIgdT1iLnN0YXRlTm9kZS5jb250YWluZXJJbmZvOzE9PT11Lm5vZGVUeXBlP3UudGV4dENvbnRlbnQ9XCJcIjo5PT09dS5ub2RlVHlwZSYmdS5kb2N1bWVudEVsZW1lbnQmJnUucmVtb3ZlQ2hpbGQodS5kb2N1bWVudEVsZW1lbnQpO2JyZWFrO2Nhc2UgNTpjYXNlIDY6Y2FzZSA0OmNhc2UgMTc6YnJlYWs7ZGVmYXVsdDp0aHJvdyBFcnJvcihwKDE2MykpO319Y2F0Y2goRil7VyhiLGIucmV0dXJuLEYpfWE9Yi5zaWJsaW5nO2lmKG51bGwhPT1hKXthLnJldHVybj1iLnJldHVybjtWPWE7YnJlYWt9Vj1iLnJldHVybn1uPU9qO09qPSExO3JldHVybiBufVxuZnVuY3Rpb24gUWooYSxiLGMpe3ZhciBkPWIudXBkYXRlUXVldWU7ZD1udWxsIT09ZD9kLmxhc3RFZmZlY3Q6bnVsbDtpZihudWxsIT09ZCl7dmFyIGU9ZD1kLm5leHQ7ZG97aWYoKGUudGFnJmEpPT09YSl7dmFyIGY9ZS5kZXN0cm95O2UuZGVzdHJveT12b2lkIDA7dm9pZCAwIT09ZiYmTmooYixjLGYpfWU9ZS5uZXh0fXdoaWxlKGUhPT1kKX19ZnVuY3Rpb24gUmooYSxiKXtiPWIudXBkYXRlUXVldWU7Yj1udWxsIT09Yj9iLmxhc3RFZmZlY3Q6bnVsbDtpZihudWxsIT09Yil7dmFyIGM9Yj1iLm5leHQ7ZG97aWYoKGMudGFnJmEpPT09YSl7dmFyIGQ9Yy5jcmVhdGU7Yy5kZXN0cm95PWQoKX1jPWMubmV4dH13aGlsZShjIT09Yil9fWZ1bmN0aW9uIFNqKGEpe3ZhciBiPWEucmVmO2lmKG51bGwhPT1iKXt2YXIgYz1hLnN0YXRlTm9kZTtzd2l0Y2goYS50YWcpe2Nhc2UgNTphPWM7YnJlYWs7ZGVmYXVsdDphPWN9XCJmdW5jdGlvblwiPT09dHlwZW9mIGI/YihhKTpiLmN1cnJlbnQ9YX19XG5mdW5jdGlvbiBUaihhKXt2YXIgYj1hLmFsdGVybmF0ZTtudWxsIT09YiYmKGEuYWx0ZXJuYXRlPW51bGwsVGooYikpO2EuY2hpbGQ9bnVsbDthLmRlbGV0aW9ucz1udWxsO2Euc2libGluZz1udWxsOzU9PT1hLnRhZyYmKGI9YS5zdGF0ZU5vZGUsbnVsbCE9PWImJihkZWxldGUgYltPZl0sZGVsZXRlIGJbUGZdLGRlbGV0ZSBiW29mXSxkZWxldGUgYltRZl0sZGVsZXRlIGJbUmZdKSk7YS5zdGF0ZU5vZGU9bnVsbDthLnJldHVybj1udWxsO2EuZGVwZW5kZW5jaWVzPW51bGw7YS5tZW1vaXplZFByb3BzPW51bGw7YS5tZW1vaXplZFN0YXRlPW51bGw7YS5wZW5kaW5nUHJvcHM9bnVsbDthLnN0YXRlTm9kZT1udWxsO2EudXBkYXRlUXVldWU9bnVsbH1mdW5jdGlvbiBVaihhKXtyZXR1cm4gNT09PWEudGFnfHwzPT09YS50YWd8fDQ9PT1hLnRhZ31cbmZ1bmN0aW9uIFZqKGEpe2E6Zm9yKDs7KXtmb3IoO251bGw9PT1hLnNpYmxpbmc7KXtpZihudWxsPT09YS5yZXR1cm58fFVqKGEucmV0dXJuKSlyZXR1cm4gbnVsbDthPWEucmV0dXJufWEuc2libGluZy5yZXR1cm49YS5yZXR1cm47Zm9yKGE9YS5zaWJsaW5nOzUhPT1hLnRhZyYmNiE9PWEudGFnJiYxOCE9PWEudGFnOyl7aWYoYS5mbGFncyYyKWNvbnRpbnVlIGE7aWYobnVsbD09PWEuY2hpbGR8fDQ9PT1hLnRhZyljb250aW51ZSBhO2Vsc2UgYS5jaGlsZC5yZXR1cm49YSxhPWEuY2hpbGR9aWYoIShhLmZsYWdzJjIpKXJldHVybiBhLnN0YXRlTm9kZX19XG5mdW5jdGlvbiBXaihhLGIsYyl7dmFyIGQ9YS50YWc7aWYoNT09PWR8fDY9PT1kKWE9YS5zdGF0ZU5vZGUsYj84PT09Yy5ub2RlVHlwZT9jLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGEsYik6Yy5pbnNlcnRCZWZvcmUoYSxiKTooOD09PWMubm9kZVR5cGU/KGI9Yy5wYXJlbnROb2RlLGIuaW5zZXJ0QmVmb3JlKGEsYykpOihiPWMsYi5hcHBlbmRDaGlsZChhKSksYz1jLl9yZWFjdFJvb3RDb250YWluZXIsbnVsbCE9PWMmJnZvaWQgMCE9PWN8fG51bGwhPT1iLm9uY2xpY2t8fChiLm9uY2xpY2s9QmYpKTtlbHNlIGlmKDQhPT1kJiYoYT1hLmNoaWxkLG51bGwhPT1hKSlmb3IoV2ooYSxiLGMpLGE9YS5zaWJsaW5nO251bGwhPT1hOylXaihhLGIsYyksYT1hLnNpYmxpbmd9XG5mdW5jdGlvbiBYaihhLGIsYyl7dmFyIGQ9YS50YWc7aWYoNT09PWR8fDY9PT1kKWE9YS5zdGF0ZU5vZGUsYj9jLmluc2VydEJlZm9yZShhLGIpOmMuYXBwZW5kQ2hpbGQoYSk7ZWxzZSBpZig0IT09ZCYmKGE9YS5jaGlsZCxudWxsIT09YSkpZm9yKFhqKGEsYixjKSxhPWEuc2libGluZztudWxsIT09YTspWGooYSxiLGMpLGE9YS5zaWJsaW5nfXZhciBYPW51bGwsWWo9ITE7ZnVuY3Rpb24gWmooYSxiLGMpe2ZvcihjPWMuY2hpbGQ7bnVsbCE9PWM7KWFrKGEsYixjKSxjPWMuc2libGluZ31cbmZ1bmN0aW9uIGFrKGEsYixjKXtpZihsYyYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGxjLm9uQ29tbWl0RmliZXJVbm1vdW50KXRyeXtsYy5vbkNvbW1pdEZpYmVyVW5tb3VudChrYyxjKX1jYXRjaChoKXt9c3dpdGNoKGMudGFnKXtjYXNlIDU6VXx8TWooYyxiKTtjYXNlIDY6dmFyIGQ9WCxlPVlqO1g9bnVsbDtaaihhLGIsYyk7WD1kO1lqPWU7bnVsbCE9PVgmJihZaj8oYT1YLGM9Yy5zdGF0ZU5vZGUsOD09PWEubm9kZVR5cGU/YS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGMpOmEucmVtb3ZlQ2hpbGQoYykpOlgucmVtb3ZlQ2hpbGQoYy5zdGF0ZU5vZGUpKTticmVhaztjYXNlIDE4Om51bGwhPT1YJiYoWWo/KGE9WCxjPWMuc3RhdGVOb2RlLDg9PT1hLm5vZGVUeXBlP0tmKGEucGFyZW50Tm9kZSxjKToxPT09YS5ub2RlVHlwZSYmS2YoYSxjKSxiZChhKSk6S2YoWCxjLnN0YXRlTm9kZSkpO2JyZWFrO2Nhc2UgNDpkPVg7ZT1ZajtYPWMuc3RhdGVOb2RlLmNvbnRhaW5lckluZm87WWo9ITA7XG5aaihhLGIsYyk7WD1kO1lqPWU7YnJlYWs7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNDpjYXNlIDE1OmlmKCFVJiYoZD1jLnVwZGF0ZVF1ZXVlLG51bGwhPT1kJiYoZD1kLmxhc3RFZmZlY3QsbnVsbCE9PWQpKSl7ZT1kPWQubmV4dDtkb3t2YXIgZj1lLGc9Zi5kZXN0cm95O2Y9Zi50YWc7dm9pZCAwIT09ZyYmKDAhPT0oZiYyKT9OaihjLGIsZyk6MCE9PShmJjQpJiZOaihjLGIsZykpO2U9ZS5uZXh0fXdoaWxlKGUhPT1kKX1aaihhLGIsYyk7YnJlYWs7Y2FzZSAxOmlmKCFVJiYoTWooYyxiKSxkPWMuc3RhdGVOb2RlLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBkLmNvbXBvbmVudFdpbGxVbm1vdW50KSl0cnl7ZC5wcm9wcz1jLm1lbW9pemVkUHJvcHMsZC5zdGF0ZT1jLm1lbW9pemVkU3RhdGUsZC5jb21wb25lbnRXaWxsVW5tb3VudCgpfWNhdGNoKGgpe1coYyxiLGgpfVpqKGEsYixjKTticmVhaztjYXNlIDIxOlpqKGEsYixjKTticmVhaztjYXNlIDIyOmMubW9kZSYxPyhVPShkPVUpfHxudWxsIT09XG5jLm1lbW9pemVkU3RhdGUsWmooYSxiLGMpLFU9ZCk6WmooYSxiLGMpO2JyZWFrO2RlZmF1bHQ6WmooYSxiLGMpfX1mdW5jdGlvbiBiayhhKXt2YXIgYj1hLnVwZGF0ZVF1ZXVlO2lmKG51bGwhPT1iKXthLnVwZGF0ZVF1ZXVlPW51bGw7dmFyIGM9YS5zdGF0ZU5vZGU7bnVsbD09PWMmJihjPWEuc3RhdGVOb2RlPW5ldyBMaik7Yi5mb3JFYWNoKGZ1bmN0aW9uKGIpe3ZhciBkPWNrLmJpbmQobnVsbCxhLGIpO2MuaGFzKGIpfHwoYy5hZGQoYiksYi50aGVuKGQsZCkpfSl9fVxuZnVuY3Rpb24gZGsoYSxiKXt2YXIgYz1iLmRlbGV0aW9ucztpZihudWxsIT09Yylmb3IodmFyIGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGU9Y1tkXTt0cnl7dmFyIGY9YSxnPWIsaD1nO2E6Zm9yKDtudWxsIT09aDspe3N3aXRjaChoLnRhZyl7Y2FzZSA1Olg9aC5zdGF0ZU5vZGU7WWo9ITE7YnJlYWsgYTtjYXNlIDM6WD1oLnN0YXRlTm9kZS5jb250YWluZXJJbmZvO1lqPSEwO2JyZWFrIGE7Y2FzZSA0Olg9aC5zdGF0ZU5vZGUuY29udGFpbmVySW5mbztZaj0hMDticmVhayBhfWg9aC5yZXR1cm59aWYobnVsbD09PVgpdGhyb3cgRXJyb3IocCgxNjApKTthayhmLGcsZSk7WD1udWxsO1lqPSExO3ZhciBrPWUuYWx0ZXJuYXRlO251bGwhPT1rJiYoay5yZXR1cm49bnVsbCk7ZS5yZXR1cm49bnVsbH1jYXRjaChsKXtXKGUsYixsKX19aWYoYi5zdWJ0cmVlRmxhZ3MmMTI4NTQpZm9yKGI9Yi5jaGlsZDtudWxsIT09YjspZWsoYixhKSxiPWIuc2libGluZ31cbmZ1bmN0aW9uIGVrKGEsYil7dmFyIGM9YS5hbHRlcm5hdGUsZD1hLmZsYWdzO3N3aXRjaChhLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNDpjYXNlIDE1OmRrKGIsYSk7ZmsoYSk7aWYoZCY0KXt0cnl7UWooMyxhLGEucmV0dXJuKSxSaigzLGEpfWNhdGNoKHQpe1coYSxhLnJldHVybix0KX10cnl7UWooNSxhLGEucmV0dXJuKX1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWJyZWFrO2Nhc2UgMTpkayhiLGEpO2ZrKGEpO2QmNTEyJiZudWxsIT09YyYmTWooYyxjLnJldHVybik7YnJlYWs7Y2FzZSA1OmRrKGIsYSk7ZmsoYSk7ZCY1MTImJm51bGwhPT1jJiZNaihjLGMucmV0dXJuKTtpZihhLmZsYWdzJjMyKXt2YXIgZT1hLnN0YXRlTm9kZTt0cnl7b2IoZSxcIlwiKX1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWlmKGQmNCYmKGU9YS5zdGF0ZU5vZGUsbnVsbCE9ZSkpe3ZhciBmPWEubWVtb2l6ZWRQcm9wcyxnPW51bGwhPT1jP2MubWVtb2l6ZWRQcm9wczpmLGg9YS50eXBlLGs9YS51cGRhdGVRdWV1ZTtcbmEudXBkYXRlUXVldWU9bnVsbDtpZihudWxsIT09ayl0cnl7XCJpbnB1dFwiPT09aCYmXCJyYWRpb1wiPT09Zi50eXBlJiZudWxsIT1mLm5hbWUmJmFiKGUsZik7dmIoaCxnKTt2YXIgbD12YihoLGYpO2ZvcihnPTA7ZzxrLmxlbmd0aDtnKz0yKXt2YXIgbT1rW2ddLHE9a1tnKzFdO1wic3R5bGVcIj09PW0/c2IoZSxxKTpcImRhbmdlcm91c2x5U2V0SW5uZXJIVE1MXCI9PT1tP25iKGUscSk6XCJjaGlsZHJlblwiPT09bT9vYihlLHEpOnRhKGUsbSxxLGwpfXN3aXRjaChoKXtjYXNlIFwiaW5wdXRcIjpiYihlLGYpO2JyZWFrO2Nhc2UgXCJ0ZXh0YXJlYVwiOmliKGUsZik7YnJlYWs7Y2FzZSBcInNlbGVjdFwiOnZhciByPWUuX3dyYXBwZXJTdGF0ZS53YXNNdWx0aXBsZTtlLl93cmFwcGVyU3RhdGUud2FzTXVsdGlwbGU9ISFmLm11bHRpcGxlO3ZhciB5PWYudmFsdWU7bnVsbCE9eT9mYihlLCEhZi5tdWx0aXBsZSx5LCExKTpyIT09ISFmLm11bHRpcGxlJiYobnVsbCE9Zi5kZWZhdWx0VmFsdWU/ZmIoZSwhIWYubXVsdGlwbGUsXG5mLmRlZmF1bHRWYWx1ZSwhMCk6ZmIoZSwhIWYubXVsdGlwbGUsZi5tdWx0aXBsZT9bXTpcIlwiLCExKSl9ZVtQZl09Zn1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWJyZWFrO2Nhc2UgNjpkayhiLGEpO2ZrKGEpO2lmKGQmNCl7aWYobnVsbD09PWEuc3RhdGVOb2RlKXRocm93IEVycm9yKHAoMTYyKSk7ZT1hLnN0YXRlTm9kZTtmPWEubWVtb2l6ZWRQcm9wczt0cnl7ZS5ub2RlVmFsdWU9Zn1jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWJyZWFrO2Nhc2UgMzpkayhiLGEpO2ZrKGEpO2lmKGQmNCYmbnVsbCE9PWMmJmMubWVtb2l6ZWRTdGF0ZS5pc0RlaHlkcmF0ZWQpdHJ5e2JkKGIuY29udGFpbmVySW5mbyl9Y2F0Y2godCl7VyhhLGEucmV0dXJuLHQpfWJyZWFrO2Nhc2UgNDpkayhiLGEpO2ZrKGEpO2JyZWFrO2Nhc2UgMTM6ZGsoYixhKTtmayhhKTtlPWEuY2hpbGQ7ZS5mbGFncyY4MTkyJiYoZj1udWxsIT09ZS5tZW1vaXplZFN0YXRlLGUuc3RhdGVOb2RlLmlzSGlkZGVuPWYsIWZ8fFxubnVsbCE9PWUuYWx0ZXJuYXRlJiZudWxsIT09ZS5hbHRlcm5hdGUubWVtb2l6ZWRTdGF0ZXx8KGdrPUIoKSkpO2QmNCYmYmsoYSk7YnJlYWs7Y2FzZSAyMjptPW51bGwhPT1jJiZudWxsIT09Yy5tZW1vaXplZFN0YXRlO2EubW9kZSYxPyhVPShsPVUpfHxtLGRrKGIsYSksVT1sKTpkayhiLGEpO2ZrKGEpO2lmKGQmODE5Mil7bD1udWxsIT09YS5tZW1vaXplZFN0YXRlO2lmKChhLnN0YXRlTm9kZS5pc0hpZGRlbj1sKSYmIW0mJjAhPT0oYS5tb2RlJjEpKWZvcihWPWEsbT1hLmNoaWxkO251bGwhPT1tOyl7Zm9yKHE9Vj1tO251bGwhPT1WOyl7cj1WO3k9ci5jaGlsZDtzd2l0Y2goci50YWcpe2Nhc2UgMDpjYXNlIDExOmNhc2UgMTQ6Y2FzZSAxNTpRaig0LHIsci5yZXR1cm4pO2JyZWFrO2Nhc2UgMTpNaihyLHIucmV0dXJuKTt2YXIgbj1yLnN0YXRlTm9kZTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2Ygbi5jb21wb25lbnRXaWxsVW5tb3VudCl7ZD1yO2M9ci5yZXR1cm47dHJ5e2I9ZCxuLnByb3BzPVxuYi5tZW1vaXplZFByb3BzLG4uc3RhdGU9Yi5tZW1vaXplZFN0YXRlLG4uY29tcG9uZW50V2lsbFVubW91bnQoKX1jYXRjaCh0KXtXKGQsYyx0KX19YnJlYWs7Y2FzZSA1Ok1qKHIsci5yZXR1cm4pO2JyZWFrO2Nhc2UgMjI6aWYobnVsbCE9PXIubWVtb2l6ZWRTdGF0ZSl7aGsocSk7Y29udGludWV9fW51bGwhPT15Pyh5LnJldHVybj1yLFY9eSk6aGsocSl9bT1tLnNpYmxpbmd9YTpmb3IobT1udWxsLHE9YTs7KXtpZig1PT09cS50YWcpe2lmKG51bGw9PT1tKXttPXE7dHJ5e2U9cS5zdGF0ZU5vZGUsbD8oZj1lLnN0eWxlLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBmLnNldFByb3BlcnR5P2Yuc2V0UHJvcGVydHkoXCJkaXNwbGF5XCIsXCJub25lXCIsXCJpbXBvcnRhbnRcIik6Zi5kaXNwbGF5PVwibm9uZVwiKTooaD1xLnN0YXRlTm9kZSxrPXEubWVtb2l6ZWRQcm9wcy5zdHlsZSxnPXZvaWQgMCE9PWsmJm51bGwhPT1rJiZrLmhhc093blByb3BlcnR5KFwiZGlzcGxheVwiKT9rLmRpc3BsYXk6bnVsbCxoLnN0eWxlLmRpc3BsYXk9XG5yYihcImRpc3BsYXlcIixnKSl9Y2F0Y2godCl7VyhhLGEucmV0dXJuLHQpfX19ZWxzZSBpZig2PT09cS50YWcpe2lmKG51bGw9PT1tKXRyeXtxLnN0YXRlTm9kZS5ub2RlVmFsdWU9bD9cIlwiOnEubWVtb2l6ZWRQcm9wc31jYXRjaCh0KXtXKGEsYS5yZXR1cm4sdCl9fWVsc2UgaWYoKDIyIT09cS50YWcmJjIzIT09cS50YWd8fG51bGw9PT1xLm1lbW9pemVkU3RhdGV8fHE9PT1hKSYmbnVsbCE9PXEuY2hpbGQpe3EuY2hpbGQucmV0dXJuPXE7cT1xLmNoaWxkO2NvbnRpbnVlfWlmKHE9PT1hKWJyZWFrIGE7Zm9yKDtudWxsPT09cS5zaWJsaW5nOyl7aWYobnVsbD09PXEucmV0dXJufHxxLnJldHVybj09PWEpYnJlYWsgYTttPT09cSYmKG09bnVsbCk7cT1xLnJldHVybn1tPT09cSYmKG09bnVsbCk7cS5zaWJsaW5nLnJldHVybj1xLnJldHVybjtxPXEuc2libGluZ319YnJlYWs7Y2FzZSAxOTpkayhiLGEpO2ZrKGEpO2QmNCYmYmsoYSk7YnJlYWs7Y2FzZSAyMTpicmVhaztkZWZhdWx0OmRrKGIsXG5hKSxmayhhKX19ZnVuY3Rpb24gZmsoYSl7dmFyIGI9YS5mbGFncztpZihiJjIpe3RyeXthOntmb3IodmFyIGM9YS5yZXR1cm47bnVsbCE9PWM7KXtpZihVaihjKSl7dmFyIGQ9YzticmVhayBhfWM9Yy5yZXR1cm59dGhyb3cgRXJyb3IocCgxNjApKTt9c3dpdGNoKGQudGFnKXtjYXNlIDU6dmFyIGU9ZC5zdGF0ZU5vZGU7ZC5mbGFncyYzMiYmKG9iKGUsXCJcIiksZC5mbGFncyY9LTMzKTt2YXIgZj1WaihhKTtYaihhLGYsZSk7YnJlYWs7Y2FzZSAzOmNhc2UgNDp2YXIgZz1kLnN0YXRlTm9kZS5jb250YWluZXJJbmZvLGg9VmooYSk7V2ooYSxoLGcpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IocCgxNjEpKTt9fWNhdGNoKGspe1coYSxhLnJldHVybixrKX1hLmZsYWdzJj0tM31iJjQwOTYmJihhLmZsYWdzJj0tNDA5Nyl9ZnVuY3Rpb24gaWsoYSxiLGMpe1Y9YTtqayhhLGIsYyl9XG5mdW5jdGlvbiBqayhhLGIsYyl7Zm9yKHZhciBkPTAhPT0oYS5tb2RlJjEpO251bGwhPT1WOyl7dmFyIGU9VixmPWUuY2hpbGQ7aWYoMjI9PT1lLnRhZyYmZCl7dmFyIGc9bnVsbCE9PWUubWVtb2l6ZWRTdGF0ZXx8S2o7aWYoIWcpe3ZhciBoPWUuYWx0ZXJuYXRlLGs9bnVsbCE9PWgmJm51bGwhPT1oLm1lbW9pemVkU3RhdGV8fFU7aD1Lajt2YXIgbD1VO0tqPWc7aWYoKFU9aykmJiFsKWZvcihWPWU7bnVsbCE9PVY7KWc9VixrPWcuY2hpbGQsMjI9PT1nLnRhZyYmbnVsbCE9PWcubWVtb2l6ZWRTdGF0ZT9rayhlKTpudWxsIT09az8oay5yZXR1cm49ZyxWPWspOmtrKGUpO2Zvcig7bnVsbCE9PWY7KVY9ZixqayhmLGIsYyksZj1mLnNpYmxpbmc7Vj1lO0tqPWg7VT1sfWxrKGEsYixjKX1lbHNlIDAhPT0oZS5zdWJ0cmVlRmxhZ3MmODc3MikmJm51bGwhPT1mPyhmLnJldHVybj1lLFY9Zik6bGsoYSxiLGMpfX1cbmZ1bmN0aW9uIGxrKGEpe2Zvcig7bnVsbCE9PVY7KXt2YXIgYj1WO2lmKDAhPT0oYi5mbGFncyY4NzcyKSl7dmFyIGM9Yi5hbHRlcm5hdGU7dHJ5e2lmKDAhPT0oYi5mbGFncyY4NzcyKSlzd2l0Y2goYi50YWcpe2Nhc2UgMDpjYXNlIDExOmNhc2UgMTU6VXx8UmooNSxiKTticmVhaztjYXNlIDE6dmFyIGQ9Yi5zdGF0ZU5vZGU7aWYoYi5mbGFncyY0JiYhVSlpZihudWxsPT09YylkLmNvbXBvbmVudERpZE1vdW50KCk7ZWxzZXt2YXIgZT1iLmVsZW1lbnRUeXBlPT09Yi50eXBlP2MubWVtb2l6ZWRQcm9wczpMZyhiLnR5cGUsYy5tZW1vaXplZFByb3BzKTtkLmNvbXBvbmVudERpZFVwZGF0ZShlLGMubWVtb2l6ZWRTdGF0ZSxkLl9fcmVhY3RJbnRlcm5hbFNuYXBzaG90QmVmb3JlVXBkYXRlKX12YXIgZj1iLnVwZGF0ZVF1ZXVlO251bGwhPT1mJiZpaChiLGYsZCk7YnJlYWs7Y2FzZSAzOnZhciBnPWIudXBkYXRlUXVldWU7aWYobnVsbCE9PWcpe2M9bnVsbDtpZihudWxsIT09Yi5jaGlsZClzd2l0Y2goYi5jaGlsZC50YWcpe2Nhc2UgNTpjPVxuYi5jaGlsZC5zdGF0ZU5vZGU7YnJlYWs7Y2FzZSAxOmM9Yi5jaGlsZC5zdGF0ZU5vZGV9aWgoYixnLGMpfWJyZWFrO2Nhc2UgNTp2YXIgaD1iLnN0YXRlTm9kZTtpZihudWxsPT09YyYmYi5mbGFncyY0KXtjPWg7dmFyIGs9Yi5tZW1vaXplZFByb3BzO3N3aXRjaChiLnR5cGUpe2Nhc2UgXCJidXR0b25cIjpjYXNlIFwiaW5wdXRcIjpjYXNlIFwic2VsZWN0XCI6Y2FzZSBcInRleHRhcmVhXCI6ay5hdXRvRm9jdXMmJmMuZm9jdXMoKTticmVhaztjYXNlIFwiaW1nXCI6ay5zcmMmJihjLnNyYz1rLnNyYyl9fWJyZWFrO2Nhc2UgNjpicmVhaztjYXNlIDQ6YnJlYWs7Y2FzZSAxMjpicmVhaztjYXNlIDEzOmlmKG51bGw9PT1iLm1lbW9pemVkU3RhdGUpe3ZhciBsPWIuYWx0ZXJuYXRlO2lmKG51bGwhPT1sKXt2YXIgbT1sLm1lbW9pemVkU3RhdGU7aWYobnVsbCE9PW0pe3ZhciBxPW0uZGVoeWRyYXRlZDtudWxsIT09cSYmYmQocSl9fX1icmVhaztjYXNlIDE5OmNhc2UgMTc6Y2FzZSAyMTpjYXNlIDIyOmNhc2UgMjM6Y2FzZSAyNTpicmVhaztcbmRlZmF1bHQ6dGhyb3cgRXJyb3IocCgxNjMpKTt9VXx8Yi5mbGFncyY1MTImJlNqKGIpfWNhdGNoKHIpe1coYixiLnJldHVybixyKX19aWYoYj09PWEpe1Y9bnVsbDticmVha31jPWIuc2libGluZztpZihudWxsIT09Yyl7Yy5yZXR1cm49Yi5yZXR1cm47Vj1jO2JyZWFrfVY9Yi5yZXR1cm59fWZ1bmN0aW9uIGhrKGEpe2Zvcig7bnVsbCE9PVY7KXt2YXIgYj1WO2lmKGI9PT1hKXtWPW51bGw7YnJlYWt9dmFyIGM9Yi5zaWJsaW5nO2lmKG51bGwhPT1jKXtjLnJldHVybj1iLnJldHVybjtWPWM7YnJlYWt9Vj1iLnJldHVybn19XG5mdW5jdGlvbiBrayhhKXtmb3IoO251bGwhPT1WOyl7dmFyIGI9Vjt0cnl7c3dpdGNoKGIudGFnKXtjYXNlIDA6Y2FzZSAxMTpjYXNlIDE1OnZhciBjPWIucmV0dXJuO3RyeXtSaig0LGIpfWNhdGNoKGspe1coYixjLGspfWJyZWFrO2Nhc2UgMTp2YXIgZD1iLnN0YXRlTm9kZTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgZC5jb21wb25lbnREaWRNb3VudCl7dmFyIGU9Yi5yZXR1cm47dHJ5e2QuY29tcG9uZW50RGlkTW91bnQoKX1jYXRjaChrKXtXKGIsZSxrKX19dmFyIGY9Yi5yZXR1cm47dHJ5e1NqKGIpfWNhdGNoKGspe1coYixmLGspfWJyZWFrO2Nhc2UgNTp2YXIgZz1iLnJldHVybjt0cnl7U2ooYil9Y2F0Y2goayl7VyhiLGcsayl9fX1jYXRjaChrKXtXKGIsYi5yZXR1cm4sayl9aWYoYj09PWEpe1Y9bnVsbDticmVha312YXIgaD1iLnNpYmxpbmc7aWYobnVsbCE9PWgpe2gucmV0dXJuPWIucmV0dXJuO1Y9aDticmVha31WPWIucmV0dXJufX1cbnZhciBtaz1NYXRoLmNlaWwsbms9dWEuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixvaz11YS5SZWFjdEN1cnJlbnRPd25lcixwaz11YS5SZWFjdEN1cnJlbnRCYXRjaENvbmZpZyxLPTAsUj1udWxsLFk9bnVsbCxaPTAsZ2o9MCxmaj1VZigwKSxUPTAscWs9bnVsbCxoaD0wLHJrPTAsc2s9MCx0az1udWxsLHVrPW51bGwsZ2s9MCxIaj1JbmZpbml0eSx2az1udWxsLFBpPSExLFFpPW51bGwsU2k9bnVsbCx3az0hMSx4az1udWxsLHlrPTAsems9MCxBaz1udWxsLEJrPS0xLENrPTA7ZnVuY3Rpb24gTCgpe3JldHVybiAwIT09KEsmNik/QigpOi0xIT09Qms/Qms6Qms9QigpfVxuZnVuY3Rpb24gbGgoYSl7aWYoMD09PShhLm1vZGUmMSkpcmV0dXJuIDE7aWYoMCE9PShLJjIpJiYwIT09WilyZXR1cm4gWiYtWjtpZihudWxsIT09S2cudHJhbnNpdGlvbilyZXR1cm4gMD09PUNrJiYoQ2s9eWMoKSksQ2s7YT1DO2lmKDAhPT1hKXJldHVybiBhO2E9d2luZG93LmV2ZW50O2E9dm9pZCAwPT09YT8xNjpqZChhLnR5cGUpO3JldHVybiBhfWZ1bmN0aW9uIG1oKGEsYixjLGQpe2lmKDUwPHprKXRocm93IHprPTAsQWs9bnVsbCxFcnJvcihwKDE4NSkpO0FjKGEsYyxkKTtpZigwPT09KEsmMil8fGEhPT1SKWE9PT1SJiYoMD09PShLJjIpJiYocmt8PWMpLDQ9PT1UJiZEayhhLFopKSxFayhhLGQpLDE9PT1jJiYwPT09SyYmMD09PShiLm1vZGUmMSkmJihIaj1CKCkrNTAwLGZnJiZqZygpKX1cbmZ1bmN0aW9uIEVrKGEsYil7dmFyIGM9YS5jYWxsYmFja05vZGU7d2MoYSxiKTt2YXIgZD11YyhhLGE9PT1SP1o6MCk7aWYoMD09PWQpbnVsbCE9PWMmJmJjKGMpLGEuY2FsbGJhY2tOb2RlPW51bGwsYS5jYWxsYmFja1ByaW9yaXR5PTA7ZWxzZSBpZihiPWQmLWQsYS5jYWxsYmFja1ByaW9yaXR5IT09Yil7bnVsbCE9YyYmYmMoYyk7aWYoMT09PWIpMD09PWEudGFnP2lnKEZrLmJpbmQobnVsbCxhKSk6aGcoRmsuYmluZChudWxsLGEpKSxKZihmdW5jdGlvbigpezA9PT0oSyY2KSYmamcoKX0pLGM9bnVsbDtlbHNle3N3aXRjaChEYyhkKSl7Y2FzZSAxOmM9ZmM7YnJlYWs7Y2FzZSA0OmM9Z2M7YnJlYWs7Y2FzZSAxNjpjPWhjO2JyZWFrO2Nhc2UgNTM2ODcwOTEyOmM9amM7YnJlYWs7ZGVmYXVsdDpjPWhjfWM9R2soYyxIay5iaW5kKG51bGwsYSkpfWEuY2FsbGJhY2tQcmlvcml0eT1iO2EuY2FsbGJhY2tOb2RlPWN9fVxuZnVuY3Rpb24gSGsoYSxiKXtCaz0tMTtDaz0wO2lmKDAhPT0oSyY2KSl0aHJvdyBFcnJvcihwKDMyNykpO3ZhciBjPWEuY2FsbGJhY2tOb2RlO2lmKElrKCkmJmEuY2FsbGJhY2tOb2RlIT09YylyZXR1cm4gbnVsbDt2YXIgZD11YyhhLGE9PT1SP1o6MCk7aWYoMD09PWQpcmV0dXJuIG51bGw7aWYoMCE9PShkJjMwKXx8MCE9PShkJmEuZXhwaXJlZExhbmVzKXx8YiliPUprKGEsZCk7ZWxzZXtiPWQ7dmFyIGU9SztLfD0yO3ZhciBmPUtrKCk7aWYoUiE9PWF8fFohPT1iKXZrPW51bGwsSGo9QigpKzUwMCxMayhhLGIpO2RvIHRyeXtNaygpO2JyZWFrfWNhdGNoKGgpe05rKGEsaCl9d2hpbGUoMSk7UWcoKTtuay5jdXJyZW50PWY7Sz1lO251bGwhPT1ZP2I9MDooUj1udWxsLFo9MCxiPVQpfWlmKDAhPT1iKXsyPT09YiYmKGU9eGMoYSksMCE9PWUmJihkPWUsYj1PayhhLGUpKSk7aWYoMT09PWIpdGhyb3cgYz1xayxMayhhLDApLERrKGEsZCksRWsoYSxCKCkpLGM7aWYoNj09PWIpRGsoYSxkKTtcbmVsc2V7ZT1hLmN1cnJlbnQuYWx0ZXJuYXRlO2lmKDA9PT0oZCYzMCkmJiFQayhlKSYmKGI9SmsoYSxkKSwyPT09YiYmKGY9eGMoYSksMCE9PWYmJihkPWYsYj1PayhhLGYpKSksMT09PWIpKXRocm93IGM9cWssTGsoYSwwKSxEayhhLGQpLEVrKGEsQigpKSxjO2EuZmluaXNoZWRXb3JrPWU7YS5maW5pc2hlZExhbmVzPWQ7c3dpdGNoKGIpe2Nhc2UgMDpjYXNlIDE6dGhyb3cgRXJyb3IocCgzNDUpKTtjYXNlIDI6UWsoYSx1ayx2ayk7YnJlYWs7Y2FzZSAzOkRrKGEsZCk7aWYoKGQmMTMwMDIzNDI0KT09PWQmJihiPWdrKzUwMC1CKCksMTA8Yikpe2lmKDAhPT11YyhhLDApKWJyZWFrO2U9YS5zdXNwZW5kZWRMYW5lcztpZigoZSZkKSE9PWQpe0woKTthLnBpbmdlZExhbmVzfD1hLnN1c3BlbmRlZExhbmVzJmU7YnJlYWt9YS50aW1lb3V0SGFuZGxlPUZmKFFrLmJpbmQobnVsbCxhLHVrLHZrKSxiKTticmVha31RayhhLHVrLHZrKTticmVhaztjYXNlIDQ6RGsoYSxkKTtpZigoZCY0MTk0MjQwKT09PVxuZClicmVhaztiPWEuZXZlbnRUaW1lcztmb3IoZT0tMTswPGQ7KXt2YXIgZz0zMS1vYyhkKTtmPTE8PGc7Zz1iW2ddO2c+ZSYmKGU9Zyk7ZCY9fmZ9ZD1lO2Q9QigpLWQ7ZD0oMTIwPmQ/MTIwOjQ4MD5kPzQ4MDoxMDgwPmQ/MTA4MDoxOTIwPmQ/MTkyMDozRTM+ZD8zRTM6NDMyMD5kPzQzMjA6MTk2MCptayhkLzE5NjApKS1kO2lmKDEwPGQpe2EudGltZW91dEhhbmRsZT1GZihRay5iaW5kKG51bGwsYSx1ayx2ayksZCk7YnJlYWt9UWsoYSx1ayx2ayk7YnJlYWs7Y2FzZSA1OlFrKGEsdWssdmspO2JyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IocCgzMjkpKTt9fX1FayhhLEIoKSk7cmV0dXJuIGEuY2FsbGJhY2tOb2RlPT09Yz9Iay5iaW5kKG51bGwsYSk6bnVsbH1cbmZ1bmN0aW9uIE9rKGEsYil7dmFyIGM9dGs7YS5jdXJyZW50Lm1lbW9pemVkU3RhdGUuaXNEZWh5ZHJhdGVkJiYoTGsoYSxiKS5mbGFnc3w9MjU2KTthPUprKGEsYik7MiE9PWEmJihiPXVrLHVrPWMsbnVsbCE9PWImJkdqKGIpKTtyZXR1cm4gYX1mdW5jdGlvbiBHaihhKXtudWxsPT09dWs/dWs9YTp1ay5wdXNoLmFwcGx5KHVrLGEpfVxuZnVuY3Rpb24gUGsoYSl7Zm9yKHZhciBiPWE7Oyl7aWYoYi5mbGFncyYxNjM4NCl7dmFyIGM9Yi51cGRhdGVRdWV1ZTtpZihudWxsIT09YyYmKGM9Yy5zdG9yZXMsbnVsbCE9PWMpKWZvcih2YXIgZD0wO2Q8Yy5sZW5ndGg7ZCsrKXt2YXIgZT1jW2RdLGY9ZS5nZXRTbmFwc2hvdDtlPWUudmFsdWU7dHJ5e2lmKCFIZShmKCksZSkpcmV0dXJuITF9Y2F0Y2goZyl7cmV0dXJuITF9fX1jPWIuY2hpbGQ7aWYoYi5zdWJ0cmVlRmxhZ3MmMTYzODQmJm51bGwhPT1jKWMucmV0dXJuPWIsYj1jO2Vsc2V7aWYoYj09PWEpYnJlYWs7Zm9yKDtudWxsPT09Yi5zaWJsaW5nOyl7aWYobnVsbD09PWIucmV0dXJufHxiLnJldHVybj09PWEpcmV0dXJuITA7Yj1iLnJldHVybn1iLnNpYmxpbmcucmV0dXJuPWIucmV0dXJuO2I9Yi5zaWJsaW5nfX1yZXR1cm4hMH1cbmZ1bmN0aW9uIERrKGEsYil7YiY9fnNrO2ImPX5yazthLnN1c3BlbmRlZExhbmVzfD1iO2EucGluZ2VkTGFuZXMmPX5iO2ZvcihhPWEuZXhwaXJhdGlvblRpbWVzOzA8Yjspe3ZhciBjPTMxLW9jKGIpLGQ9MTw8YzthW2NdPS0xO2ImPX5kfX1mdW5jdGlvbiBGayhhKXtpZigwIT09KEsmNikpdGhyb3cgRXJyb3IocCgzMjcpKTtJaygpO3ZhciBiPXVjKGEsMCk7aWYoMD09PShiJjEpKXJldHVybiBFayhhLEIoKSksbnVsbDt2YXIgYz1KayhhLGIpO2lmKDAhPT1hLnRhZyYmMj09PWMpe3ZhciBkPXhjKGEpOzAhPT1kJiYoYj1kLGM9T2soYSxkKSl9aWYoMT09PWMpdGhyb3cgYz1xayxMayhhLDApLERrKGEsYiksRWsoYSxCKCkpLGM7aWYoNj09PWMpdGhyb3cgRXJyb3IocCgzNDUpKTthLmZpbmlzaGVkV29yaz1hLmN1cnJlbnQuYWx0ZXJuYXRlO2EuZmluaXNoZWRMYW5lcz1iO1FrKGEsdWssdmspO0VrKGEsQigpKTtyZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFJrKGEsYil7dmFyIGM9SztLfD0xO3RyeXtyZXR1cm4gYShiKX1maW5hbGx5e0s9YywwPT09SyYmKEhqPUIoKSs1MDAsZmcmJmpnKCkpfX1mdW5jdGlvbiBTayhhKXtudWxsIT09eGsmJjA9PT14ay50YWcmJjA9PT0oSyY2KSYmSWsoKTt2YXIgYj1LO0t8PTE7dmFyIGM9cGsudHJhbnNpdGlvbixkPUM7dHJ5e2lmKHBrLnRyYW5zaXRpb249bnVsbCxDPTEsYSlyZXR1cm4gYSgpfWZpbmFsbHl7Qz1kLHBrLnRyYW5zaXRpb249YyxLPWIsMD09PShLJjYpJiZqZygpfX1mdW5jdGlvbiBJaigpe2dqPWZqLmN1cnJlbnQ7RShmail9XG5mdW5jdGlvbiBMayhhLGIpe2EuZmluaXNoZWRXb3JrPW51bGw7YS5maW5pc2hlZExhbmVzPTA7dmFyIGM9YS50aW1lb3V0SGFuZGxlOy0xIT09YyYmKGEudGltZW91dEhhbmRsZT0tMSxHZihjKSk7aWYobnVsbCE9PVkpZm9yKGM9WS5yZXR1cm47bnVsbCE9PWM7KXt2YXIgZD1jO3dnKGQpO3N3aXRjaChkLnRhZyl7Y2FzZSAxOmQ9ZC50eXBlLmNoaWxkQ29udGV4dFR5cGVzO251bGwhPT1kJiZ2b2lkIDAhPT1kJiYkZigpO2JyZWFrO2Nhc2UgMzpKaCgpO0UoV2YpO0UoSCk7T2goKTticmVhaztjYXNlIDU6TGgoZCk7YnJlYWs7Y2FzZSA0OkpoKCk7YnJlYWs7Y2FzZSAxMzpFKE0pO2JyZWFrO2Nhc2UgMTk6RShNKTticmVhaztjYXNlIDEwOlJnKGQudHlwZS5fY29udGV4dCk7YnJlYWs7Y2FzZSAyMjpjYXNlIDIzOklqKCl9Yz1jLnJldHVybn1SPWE7WT1hPXdoKGEuY3VycmVudCxudWxsKTtaPWdqPWI7VD0wO3FrPW51bGw7c2s9cms9aGg9MDt1az10az1udWxsO2lmKG51bGwhPT1XZyl7Zm9yKGI9XG4wO2I8V2cubGVuZ3RoO2IrKylpZihjPVdnW2JdLGQ9Yy5pbnRlcmxlYXZlZCxudWxsIT09ZCl7Yy5pbnRlcmxlYXZlZD1udWxsO3ZhciBlPWQubmV4dCxmPWMucGVuZGluZztpZihudWxsIT09Zil7dmFyIGc9Zi5uZXh0O2YubmV4dD1lO2QubmV4dD1nfWMucGVuZGluZz1kfVdnPW51bGx9cmV0dXJuIGF9XG5mdW5jdGlvbiBOayhhLGIpe2Rve3ZhciBjPVk7dHJ5e1FnKCk7UGguY3VycmVudD1haTtpZihTaCl7Zm9yKHZhciBkPU4ubWVtb2l6ZWRTdGF0ZTtudWxsIT09ZDspe3ZhciBlPWQucXVldWU7bnVsbCE9PWUmJihlLnBlbmRpbmc9bnVsbCk7ZD1kLm5leHR9U2g9ITF9Umg9MDtQPU89Tj1udWxsO1RoPSExO1VoPTA7b2suY3VycmVudD1udWxsO2lmKG51bGw9PT1jfHxudWxsPT09Yy5yZXR1cm4pe1Q9MTtxaz1iO1k9bnVsbDticmVha31hOnt2YXIgZj1hLGc9Yy5yZXR1cm4saD1jLGs9YjtiPVo7aC5mbGFnc3w9MzI3Njg7aWYobnVsbCE9PWsmJlwib2JqZWN0XCI9PT10eXBlb2YgayYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGsudGhlbil7dmFyIGw9ayxtPWgscT1tLnRhZztpZigwPT09KG0ubW9kZSYxKSYmKDA9PT1xfHwxMT09PXF8fDE1PT09cSkpe3ZhciByPW0uYWx0ZXJuYXRlO3I/KG0udXBkYXRlUXVldWU9ci51cGRhdGVRdWV1ZSxtLm1lbW9pemVkU3RhdGU9ci5tZW1vaXplZFN0YXRlLFxubS5sYW5lcz1yLmxhbmVzKToobS51cGRhdGVRdWV1ZT1udWxsLG0ubWVtb2l6ZWRTdGF0ZT1udWxsKX12YXIgeT1WaShnKTtpZihudWxsIT09eSl7eS5mbGFncyY9LTI1NztXaSh5LGcsaCxmLGIpO3kubW9kZSYxJiZUaShmLGwsYik7Yj15O2s9bDt2YXIgbj1iLnVwZGF0ZVF1ZXVlO2lmKG51bGw9PT1uKXt2YXIgdD1uZXcgU2V0O3QuYWRkKGspO2IudXBkYXRlUXVldWU9dH1lbHNlIG4uYWRkKGspO2JyZWFrIGF9ZWxzZXtpZigwPT09KGImMSkpe1RpKGYsbCxiKTt1aigpO2JyZWFrIGF9az1FcnJvcihwKDQyNikpfX1lbHNlIGlmKEkmJmgubW9kZSYxKXt2YXIgSj1WaShnKTtpZihudWxsIT09Sil7MD09PShKLmZsYWdzJjY1NTM2KSYmKEouZmxhZ3N8PTI1Nik7V2koSixnLGgsZixiKTtKZyhLaShrLGgpKTticmVhayBhfX1mPWs9S2koayxoKTs0IT09VCYmKFQ9Mik7bnVsbD09PXRrP3RrPVtmXTp0ay5wdXNoKGYpO2Y9Zztkb3tzd2l0Y2goZi50YWcpe2Nhc2UgMzpmLmZsYWdzfD02NTUzNjtcbmImPS1iO2YubGFuZXN8PWI7dmFyIHg9T2koZixrLGIpO2ZoKGYseCk7YnJlYWsgYTtjYXNlIDE6aD1rO3ZhciB3PWYudHlwZSx1PWYuc3RhdGVOb2RlO2lmKDA9PT0oZi5mbGFncyYxMjgpJiYoXCJmdW5jdGlvblwiPT09dHlwZW9mIHcuZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yfHxudWxsIT09dSYmXCJmdW5jdGlvblwiPT09dHlwZW9mIHUuY29tcG9uZW50RGlkQ2F0Y2gmJihudWxsPT09U2l8fCFTaS5oYXModSkpKSl7Zi5mbGFnc3w9NjU1MzY7YiY9LWI7Zi5sYW5lc3w9Yjt2YXIgRj1SaShmLGgsYik7ZmgoZixGKTticmVhayBhfX1mPWYucmV0dXJufXdoaWxlKG51bGwhPT1mKX1UayhjKX1jYXRjaChuYSl7Yj1uYTtZPT09YyYmbnVsbCE9PWMmJihZPWM9Yy5yZXR1cm4pO2NvbnRpbnVlfWJyZWFrfXdoaWxlKDEpfWZ1bmN0aW9uIEtrKCl7dmFyIGE9bmsuY3VycmVudDtuay5jdXJyZW50PWFpO3JldHVybiBudWxsPT09YT9haTphfVxuZnVuY3Rpb24gdWooKXtpZigwPT09VHx8Mz09PVR8fDI9PT1UKVQ9NDtudWxsPT09Unx8MD09PShoaCYyNjg0MzU0NTUpJiYwPT09KHJrJjI2ODQzNTQ1NSl8fERrKFIsWil9ZnVuY3Rpb24gSmsoYSxiKXt2YXIgYz1LO0t8PTI7dmFyIGQ9S2soKTtpZihSIT09YXx8WiE9PWIpdms9bnVsbCxMayhhLGIpO2RvIHRyeXtVaygpO2JyZWFrfWNhdGNoKGUpe05rKGEsZSl9d2hpbGUoMSk7UWcoKTtLPWM7bmsuY3VycmVudD1kO2lmKG51bGwhPT1ZKXRocm93IEVycm9yKHAoMjYxKSk7Uj1udWxsO1o9MDtyZXR1cm4gVH1mdW5jdGlvbiBVaygpe2Zvcig7bnVsbCE9PVk7KVZrKFkpfWZ1bmN0aW9uIE1rKCl7Zm9yKDtudWxsIT09WSYmIWNjKCk7KVZrKFkpfWZ1bmN0aW9uIFZrKGEpe3ZhciBiPVdrKGEuYWx0ZXJuYXRlLGEsZ2opO2EubWVtb2l6ZWRQcm9wcz1hLnBlbmRpbmdQcm9wcztudWxsPT09Yj9UayhhKTpZPWI7b2suY3VycmVudD1udWxsfVxuZnVuY3Rpb24gVGsoYSl7dmFyIGI9YTtkb3t2YXIgYz1iLmFsdGVybmF0ZTthPWIucmV0dXJuO2lmKDA9PT0oYi5mbGFncyYzMjc2OCkpe2lmKGM9RmooYyxiLGdqKSxudWxsIT09Yyl7WT1jO3JldHVybn19ZWxzZXtjPUpqKGMsYik7aWYobnVsbCE9PWMpe2MuZmxhZ3MmPTMyNzY3O1k9YztyZXR1cm59aWYobnVsbCE9PWEpYS5mbGFnc3w9MzI3NjgsYS5zdWJ0cmVlRmxhZ3M9MCxhLmRlbGV0aW9ucz1udWxsO2Vsc2V7VD02O1k9bnVsbDtyZXR1cm59fWI9Yi5zaWJsaW5nO2lmKG51bGwhPT1iKXtZPWI7cmV0dXJufVk9Yj1hfXdoaWxlKG51bGwhPT1iKTswPT09VCYmKFQ9NSl9ZnVuY3Rpb24gUWsoYSxiLGMpe3ZhciBkPUMsZT1way50cmFuc2l0aW9uO3RyeXtway50cmFuc2l0aW9uPW51bGwsQz0xLFhrKGEsYixjLGQpfWZpbmFsbHl7cGsudHJhbnNpdGlvbj1lLEM9ZH1yZXR1cm4gbnVsbH1cbmZ1bmN0aW9uIFhrKGEsYixjLGQpe2RvIElrKCk7d2hpbGUobnVsbCE9PXhrKTtpZigwIT09KEsmNikpdGhyb3cgRXJyb3IocCgzMjcpKTtjPWEuZmluaXNoZWRXb3JrO3ZhciBlPWEuZmluaXNoZWRMYW5lcztpZihudWxsPT09YylyZXR1cm4gbnVsbDthLmZpbmlzaGVkV29yaz1udWxsO2EuZmluaXNoZWRMYW5lcz0wO2lmKGM9PT1hLmN1cnJlbnQpdGhyb3cgRXJyb3IocCgxNzcpKTthLmNhbGxiYWNrTm9kZT1udWxsO2EuY2FsbGJhY2tQcmlvcml0eT0wO3ZhciBmPWMubGFuZXN8Yy5jaGlsZExhbmVzO0JjKGEsZik7YT09PVImJihZPVI9bnVsbCxaPTApOzA9PT0oYy5zdWJ0cmVlRmxhZ3MmMjA2NCkmJjA9PT0oYy5mbGFncyYyMDY0KXx8d2t8fCh3az0hMCxHayhoYyxmdW5jdGlvbigpe0lrKCk7cmV0dXJuIG51bGx9KSk7Zj0wIT09KGMuZmxhZ3MmMTU5OTApO2lmKDAhPT0oYy5zdWJ0cmVlRmxhZ3MmMTU5OTApfHxmKXtmPXBrLnRyYW5zaXRpb247cGsudHJhbnNpdGlvbj1udWxsO1xudmFyIGc9QztDPTE7dmFyIGg9SztLfD00O29rLmN1cnJlbnQ9bnVsbDtQaihhLGMpO2VrKGMsYSk7T2UoRGYpO2RkPSEhQ2Y7RGY9Q2Y9bnVsbDthLmN1cnJlbnQ9YztpayhjLGEsZSk7ZGMoKTtLPWg7Qz1nO3BrLnRyYW5zaXRpb249Zn1lbHNlIGEuY3VycmVudD1jO3drJiYod2s9ITEseGs9YSx5az1lKTtmPWEucGVuZGluZ0xhbmVzOzA9PT1mJiYoU2k9bnVsbCk7bWMoYy5zdGF0ZU5vZGUsZCk7RWsoYSxCKCkpO2lmKG51bGwhPT1iKWZvcihkPWEub25SZWNvdmVyYWJsZUVycm9yLGM9MDtjPGIubGVuZ3RoO2MrKyllPWJbY10sZChlLnZhbHVlLHtjb21wb25lbnRTdGFjazplLnN0YWNrLGRpZ2VzdDplLmRpZ2VzdH0pO2lmKFBpKXRocm93IFBpPSExLGE9UWksUWk9bnVsbCxhOzAhPT0oeWsmMSkmJjAhPT1hLnRhZyYmSWsoKTtmPWEucGVuZGluZ0xhbmVzOzAhPT0oZiYxKT9hPT09QWs/emsrKzooems9MCxBaz1hKTp6az0wO2pnKCk7cmV0dXJuIG51bGx9XG5mdW5jdGlvbiBJaygpe2lmKG51bGwhPT14ayl7dmFyIGE9RGMoeWspLGI9cGsudHJhbnNpdGlvbixjPUM7dHJ5e3BrLnRyYW5zaXRpb249bnVsbDtDPTE2PmE/MTY6YTtpZihudWxsPT09eGspdmFyIGQ9ITE7ZWxzZXthPXhrO3hrPW51bGw7eWs9MDtpZigwIT09KEsmNikpdGhyb3cgRXJyb3IocCgzMzEpKTt2YXIgZT1LO0t8PTQ7Zm9yKFY9YS5jdXJyZW50O251bGwhPT1WOyl7dmFyIGY9VixnPWYuY2hpbGQ7aWYoMCE9PShWLmZsYWdzJjE2KSl7dmFyIGg9Zi5kZWxldGlvbnM7aWYobnVsbCE9PWgpe2Zvcih2YXIgaz0wO2s8aC5sZW5ndGg7aysrKXt2YXIgbD1oW2tdO2ZvcihWPWw7bnVsbCE9PVY7KXt2YXIgbT1WO3N3aXRjaChtLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNTpRaig4LG0sZil9dmFyIHE9bS5jaGlsZDtpZihudWxsIT09cSlxLnJldHVybj1tLFY9cTtlbHNlIGZvcig7bnVsbCE9PVY7KXttPVY7dmFyIHI9bS5zaWJsaW5nLHk9bS5yZXR1cm47VGoobSk7aWYobT09PVxubCl7Vj1udWxsO2JyZWFrfWlmKG51bGwhPT1yKXtyLnJldHVybj15O1Y9cjticmVha31WPXl9fX12YXIgbj1mLmFsdGVybmF0ZTtpZihudWxsIT09bil7dmFyIHQ9bi5jaGlsZDtpZihudWxsIT09dCl7bi5jaGlsZD1udWxsO2Rve3ZhciBKPXQuc2libGluZzt0LnNpYmxpbmc9bnVsbDt0PUp9d2hpbGUobnVsbCE9PXQpfX1WPWZ9fWlmKDAhPT0oZi5zdWJ0cmVlRmxhZ3MmMjA2NCkmJm51bGwhPT1nKWcucmV0dXJuPWYsVj1nO2Vsc2UgYjpmb3IoO251bGwhPT1WOyl7Zj1WO2lmKDAhPT0oZi5mbGFncyYyMDQ4KSlzd2l0Y2goZi50YWcpe2Nhc2UgMDpjYXNlIDExOmNhc2UgMTU6UWooOSxmLGYucmV0dXJuKX12YXIgeD1mLnNpYmxpbmc7aWYobnVsbCE9PXgpe3gucmV0dXJuPWYucmV0dXJuO1Y9eDticmVhayBifVY9Zi5yZXR1cm59fXZhciB3PWEuY3VycmVudDtmb3IoVj13O251bGwhPT1WOyl7Zz1WO3ZhciB1PWcuY2hpbGQ7aWYoMCE9PShnLnN1YnRyZWVGbGFncyYyMDY0KSYmbnVsbCE9PVxudSl1LnJldHVybj1nLFY9dTtlbHNlIGI6Zm9yKGc9dztudWxsIT09Vjspe2g9VjtpZigwIT09KGguZmxhZ3MmMjA0OCkpdHJ5e3N3aXRjaChoLnRhZyl7Y2FzZSAwOmNhc2UgMTE6Y2FzZSAxNTpSaig5LGgpfX1jYXRjaChuYSl7VyhoLGgucmV0dXJuLG5hKX1pZihoPT09Zyl7Vj1udWxsO2JyZWFrIGJ9dmFyIEY9aC5zaWJsaW5nO2lmKG51bGwhPT1GKXtGLnJldHVybj1oLnJldHVybjtWPUY7YnJlYWsgYn1WPWgucmV0dXJufX1LPWU7amcoKTtpZihsYyYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGxjLm9uUG9zdENvbW1pdEZpYmVyUm9vdCl0cnl7bGMub25Qb3N0Q29tbWl0RmliZXJSb290KGtjLGEpfWNhdGNoKG5hKXt9ZD0hMH1yZXR1cm4gZH1maW5hbGx5e0M9Yyxway50cmFuc2l0aW9uPWJ9fXJldHVybiExfWZ1bmN0aW9uIFlrKGEsYixjKXtiPUtpKGMsYik7Yj1PaShhLGIsMSk7YT1kaChhLGIsMSk7Yj1MKCk7bnVsbCE9PWEmJihBYyhhLDEsYiksRWsoYSxiKSl9XG5mdW5jdGlvbiBXKGEsYixjKXtpZigzPT09YS50YWcpWWsoYSxhLGMpO2Vsc2UgZm9yKDtudWxsIT09Yjspe2lmKDM9PT1iLnRhZyl7WWsoYixhLGMpO2JyZWFrfWVsc2UgaWYoMT09PWIudGFnKXt2YXIgZD1iLnN0YXRlTm9kZTtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYi50eXBlLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvcnx8XCJmdW5jdGlvblwiPT09dHlwZW9mIGQuY29tcG9uZW50RGlkQ2F0Y2gmJihudWxsPT09U2l8fCFTaS5oYXMoZCkpKXthPUtpKGMsYSk7YT1SaShiLGEsMSk7Yj1kaChiLGEsMSk7YT1MKCk7bnVsbCE9PWImJihBYyhiLDEsYSksRWsoYixhKSk7YnJlYWt9fWI9Yi5yZXR1cm59fVxuZnVuY3Rpb24gVWkoYSxiLGMpe3ZhciBkPWEucGluZ0NhY2hlO251bGwhPT1kJiZkLmRlbGV0ZShiKTtiPUwoKTthLnBpbmdlZExhbmVzfD1hLnN1c3BlbmRlZExhbmVzJmM7Uj09PWEmJihaJmMpPT09YyYmKDQ9PT1UfHwzPT09VCYmKFomMTMwMDIzNDI0KT09PVomJjUwMD5CKCktZ2s/TGsoYSwwKTpza3w9Yyk7RWsoYSxiKX1mdW5jdGlvbiBaayhhLGIpezA9PT1iJiYoMD09PShhLm1vZGUmMSk/Yj0xOihiPXNjLHNjPDw9MSwwPT09KHNjJjEzMDAyMzQyNCkmJihzYz00MTk0MzA0KSkpO3ZhciBjPUwoKTthPVpnKGEsYik7bnVsbCE9PWEmJihBYyhhLGIsYyksRWsoYSxjKSl9ZnVuY3Rpb24gdmooYSl7dmFyIGI9YS5tZW1vaXplZFN0YXRlLGM9MDtudWxsIT09YiYmKGM9Yi5yZXRyeUxhbmUpO1prKGEsYyl9XG5mdW5jdGlvbiBjayhhLGIpe3ZhciBjPTA7c3dpdGNoKGEudGFnKXtjYXNlIDEzOnZhciBkPWEuc3RhdGVOb2RlO3ZhciBlPWEubWVtb2l6ZWRTdGF0ZTtudWxsIT09ZSYmKGM9ZS5yZXRyeUxhbmUpO2JyZWFrO2Nhc2UgMTk6ZD1hLnN0YXRlTm9kZTticmVhaztkZWZhdWx0OnRocm93IEVycm9yKHAoMzE0KSk7fW51bGwhPT1kJiZkLmRlbGV0ZShiKTtaayhhLGMpfXZhciBXaztcbldrPWZ1bmN0aW9uKGEsYixjKXtpZihudWxsIT09YSlpZihhLm1lbW9pemVkUHJvcHMhPT1iLnBlbmRpbmdQcm9wc3x8V2YuY3VycmVudClVZz0hMDtlbHNle2lmKDA9PT0oYS5sYW5lcyZjKSYmMD09PShiLmZsYWdzJjEyOCkpcmV0dXJuIFVnPSExLHpqKGEsYixjKTtVZz0wIT09KGEuZmxhZ3MmMTMxMDcyKT8hMDohMX1lbHNlIFVnPSExLEkmJjAhPT0oYi5mbGFncyYxMDQ4NTc2KSYmdWcoYixuZyxiLmluZGV4KTtiLmxhbmVzPTA7c3dpdGNoKGIudGFnKXtjYXNlIDI6dmFyIGQ9Yi50eXBlO2pqKGEsYik7YT1iLnBlbmRpbmdQcm9wczt2YXIgZT1ZZihiLEguY3VycmVudCk7VGcoYixjKTtlPVhoKG51bGwsYixkLGEsZSxjKTt2YXIgZj1iaSgpO2IuZmxhZ3N8PTE7XCJvYmplY3RcIj09PXR5cGVvZiBlJiZudWxsIT09ZSYmXCJmdW5jdGlvblwiPT09dHlwZW9mIGUucmVuZGVyJiZ2b2lkIDA9PT1lLiQkdHlwZW9mPyhiLnRhZz0xLGIubWVtb2l6ZWRTdGF0ZT1udWxsLGIudXBkYXRlUXVldWU9XG5udWxsLFpmKGQpPyhmPSEwLGNnKGIpKTpmPSExLGIubWVtb2l6ZWRTdGF0ZT1udWxsIT09ZS5zdGF0ZSYmdm9pZCAwIT09ZS5zdGF0ZT9lLnN0YXRlOm51bGwsYWgoYiksZS51cGRhdGVyPW5oLGIuc3RhdGVOb2RlPWUsZS5fcmVhY3RJbnRlcm5hbHM9YixyaChiLGQsYSxjKSxiPWtqKG51bGwsYixkLCEwLGYsYykpOihiLnRhZz0wLEkmJmYmJnZnKGIpLFlpKG51bGwsYixlLGMpLGI9Yi5jaGlsZCk7cmV0dXJuIGI7Y2FzZSAxNjpkPWIuZWxlbWVudFR5cGU7YTp7amooYSxiKTthPWIucGVuZGluZ1Byb3BzO2U9ZC5faW5pdDtkPWUoZC5fcGF5bG9hZCk7Yi50eXBlPWQ7ZT1iLnRhZz0kayhkKTthPUxnKGQsYSk7c3dpdGNoKGUpe2Nhc2UgMDpiPWRqKG51bGwsYixkLGEsYyk7YnJlYWsgYTtjYXNlIDE6Yj1paihudWxsLGIsZCxhLGMpO2JyZWFrIGE7Y2FzZSAxMTpiPVppKG51bGwsYixkLGEsYyk7YnJlYWsgYTtjYXNlIDE0OmI9YWoobnVsbCxiLGQsTGcoZC50eXBlLGEpLGMpO2JyZWFrIGF9dGhyb3cgRXJyb3IocCgzMDYsXG5kLFwiXCIpKTt9cmV0dXJuIGI7Y2FzZSAwOnJldHVybiBkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGU9Yi5lbGVtZW50VHlwZT09PWQ/ZTpMZyhkLGUpLGRqKGEsYixkLGUsYyk7Y2FzZSAxOnJldHVybiBkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGU9Yi5lbGVtZW50VHlwZT09PWQ/ZTpMZyhkLGUpLGlqKGEsYixkLGUsYyk7Y2FzZSAzOmE6e2xqKGIpO2lmKG51bGw9PT1hKXRocm93IEVycm9yKHAoMzg3KSk7ZD1iLnBlbmRpbmdQcm9wcztmPWIubWVtb2l6ZWRTdGF0ZTtlPWYuZWxlbWVudDtiaChhLGIpO2doKGIsZCxudWxsLGMpO3ZhciBnPWIubWVtb2l6ZWRTdGF0ZTtkPWcuZWxlbWVudDtpZihmLmlzRGVoeWRyYXRlZClpZihmPXtlbGVtZW50OmQsaXNEZWh5ZHJhdGVkOiExLGNhY2hlOmcuY2FjaGUscGVuZGluZ1N1c3BlbnNlQm91bmRhcmllczpnLnBlbmRpbmdTdXNwZW5zZUJvdW5kYXJpZXMsdHJhbnNpdGlvbnM6Zy50cmFuc2l0aW9uc30sYi51cGRhdGVRdWV1ZS5iYXNlU3RhdGU9XG5mLGIubWVtb2l6ZWRTdGF0ZT1mLGIuZmxhZ3MmMjU2KXtlPUtpKEVycm9yKHAoNDIzKSksYik7Yj1taihhLGIsZCxjLGUpO2JyZWFrIGF9ZWxzZSBpZihkIT09ZSl7ZT1LaShFcnJvcihwKDQyNCkpLGIpO2I9bWooYSxiLGQsYyxlKTticmVhayBhfWVsc2UgZm9yKHlnPUxmKGIuc3RhdGVOb2RlLmNvbnRhaW5lckluZm8uZmlyc3RDaGlsZCkseGc9YixJPSEwLHpnPW51bGwsYz1DaChiLG51bGwsZCxjKSxiLmNoaWxkPWM7YzspYy5mbGFncz1jLmZsYWdzJi0zfDQwOTYsYz1jLnNpYmxpbmc7ZWxzZXtJZygpO2lmKGQ9PT1lKXtiPSRpKGEsYixjKTticmVhayBhfVlpKGEsYixkLGMpfWI9Yi5jaGlsZH1yZXR1cm4gYjtjYXNlIDU6cmV0dXJuIEtoKGIpLG51bGw9PT1hJiZFZyhiKSxkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGY9bnVsbCE9PWE/YS5tZW1vaXplZFByb3BzOm51bGwsZz1lLmNoaWxkcmVuLEVmKGQsZSk/Zz1udWxsOm51bGwhPT1mJiZFZihkLGYpJiYoYi5mbGFnc3w9MzIpLFxuaGooYSxiKSxZaShhLGIsZyxjKSxiLmNoaWxkO2Nhc2UgNjpyZXR1cm4gbnVsbD09PWEmJkVnKGIpLG51bGw7Y2FzZSAxMzpyZXR1cm4gcGooYSxiLGMpO2Nhc2UgNDpyZXR1cm4gSWgoYixiLnN0YXRlTm9kZS5jb250YWluZXJJbmZvKSxkPWIucGVuZGluZ1Byb3BzLG51bGw9PT1hP2IuY2hpbGQ9QmgoYixudWxsLGQsYyk6WWkoYSxiLGQsYyksYi5jaGlsZDtjYXNlIDExOnJldHVybiBkPWIudHlwZSxlPWIucGVuZGluZ1Byb3BzLGU9Yi5lbGVtZW50VHlwZT09PWQ/ZTpMZyhkLGUpLFppKGEsYixkLGUsYyk7Y2FzZSA3OnJldHVybiBZaShhLGIsYi5wZW5kaW5nUHJvcHMsYyksYi5jaGlsZDtjYXNlIDg6cmV0dXJuIFlpKGEsYixiLnBlbmRpbmdQcm9wcy5jaGlsZHJlbixjKSxiLmNoaWxkO2Nhc2UgMTI6cmV0dXJuIFlpKGEsYixiLnBlbmRpbmdQcm9wcy5jaGlsZHJlbixjKSxiLmNoaWxkO2Nhc2UgMTA6YTp7ZD1iLnR5cGUuX2NvbnRleHQ7ZT1iLnBlbmRpbmdQcm9wcztmPWIubWVtb2l6ZWRQcm9wcztcbmc9ZS52YWx1ZTtHKE1nLGQuX2N1cnJlbnRWYWx1ZSk7ZC5fY3VycmVudFZhbHVlPWc7aWYobnVsbCE9PWYpaWYoSGUoZi52YWx1ZSxnKSl7aWYoZi5jaGlsZHJlbj09PWUuY2hpbGRyZW4mJiFXZi5jdXJyZW50KXtiPSRpKGEsYixjKTticmVhayBhfX1lbHNlIGZvcihmPWIuY2hpbGQsbnVsbCE9PWYmJihmLnJldHVybj1iKTtudWxsIT09Zjspe3ZhciBoPWYuZGVwZW5kZW5jaWVzO2lmKG51bGwhPT1oKXtnPWYuY2hpbGQ7Zm9yKHZhciBrPWguZmlyc3RDb250ZXh0O251bGwhPT1rOyl7aWYoay5jb250ZXh0PT09ZCl7aWYoMT09PWYudGFnKXtrPWNoKC0xLGMmLWMpO2sudGFnPTI7dmFyIGw9Zi51cGRhdGVRdWV1ZTtpZihudWxsIT09bCl7bD1sLnNoYXJlZDt2YXIgbT1sLnBlbmRpbmc7bnVsbD09PW0/ay5uZXh0PWs6KGsubmV4dD1tLm5leHQsbS5uZXh0PWspO2wucGVuZGluZz1rfX1mLmxhbmVzfD1jO2s9Zi5hbHRlcm5hdGU7bnVsbCE9PWsmJihrLmxhbmVzfD1jKTtTZyhmLnJldHVybixcbmMsYik7aC5sYW5lc3w9YzticmVha31rPWsubmV4dH19ZWxzZSBpZigxMD09PWYudGFnKWc9Zi50eXBlPT09Yi50eXBlP251bGw6Zi5jaGlsZDtlbHNlIGlmKDE4PT09Zi50YWcpe2c9Zi5yZXR1cm47aWYobnVsbD09PWcpdGhyb3cgRXJyb3IocCgzNDEpKTtnLmxhbmVzfD1jO2g9Zy5hbHRlcm5hdGU7bnVsbCE9PWgmJihoLmxhbmVzfD1jKTtTZyhnLGMsYik7Zz1mLnNpYmxpbmd9ZWxzZSBnPWYuY2hpbGQ7aWYobnVsbCE9PWcpZy5yZXR1cm49ZjtlbHNlIGZvcihnPWY7bnVsbCE9PWc7KXtpZihnPT09Yil7Zz1udWxsO2JyZWFrfWY9Zy5zaWJsaW5nO2lmKG51bGwhPT1mKXtmLnJldHVybj1nLnJldHVybjtnPWY7YnJlYWt9Zz1nLnJldHVybn1mPWd9WWkoYSxiLGUuY2hpbGRyZW4sYyk7Yj1iLmNoaWxkfXJldHVybiBiO2Nhc2UgOTpyZXR1cm4gZT1iLnR5cGUsZD1iLnBlbmRpbmdQcm9wcy5jaGlsZHJlbixUZyhiLGMpLGU9VmcoZSksZD1kKGUpLGIuZmxhZ3N8PTEsWWkoYSxiLGQsYyksXG5iLmNoaWxkO2Nhc2UgMTQ6cmV0dXJuIGQ9Yi50eXBlLGU9TGcoZCxiLnBlbmRpbmdQcm9wcyksZT1MZyhkLnR5cGUsZSksYWooYSxiLGQsZSxjKTtjYXNlIDE1OnJldHVybiBjaihhLGIsYi50eXBlLGIucGVuZGluZ1Byb3BzLGMpO2Nhc2UgMTc6cmV0dXJuIGQ9Yi50eXBlLGU9Yi5wZW5kaW5nUHJvcHMsZT1iLmVsZW1lbnRUeXBlPT09ZD9lOkxnKGQsZSksamooYSxiKSxiLnRhZz0xLFpmKGQpPyhhPSEwLGNnKGIpKTphPSExLFRnKGIsYykscGgoYixkLGUpLHJoKGIsZCxlLGMpLGtqKG51bGwsYixkLCEwLGEsYyk7Y2FzZSAxOTpyZXR1cm4geWooYSxiLGMpO2Nhc2UgMjI6cmV0dXJuIGVqKGEsYixjKX10aHJvdyBFcnJvcihwKDE1NixiLnRhZykpO307ZnVuY3Rpb24gR2soYSxiKXtyZXR1cm4gYWMoYSxiKX1cbmZ1bmN0aW9uIGFsKGEsYixjLGQpe3RoaXMudGFnPWE7dGhpcy5rZXk9Yzt0aGlzLnNpYmxpbmc9dGhpcy5jaGlsZD10aGlzLnJldHVybj10aGlzLnN0YXRlTm9kZT10aGlzLnR5cGU9dGhpcy5lbGVtZW50VHlwZT1udWxsO3RoaXMuaW5kZXg9MDt0aGlzLnJlZj1udWxsO3RoaXMucGVuZGluZ1Byb3BzPWI7dGhpcy5kZXBlbmRlbmNpZXM9dGhpcy5tZW1vaXplZFN0YXRlPXRoaXMudXBkYXRlUXVldWU9dGhpcy5tZW1vaXplZFByb3BzPW51bGw7dGhpcy5tb2RlPWQ7dGhpcy5zdWJ0cmVlRmxhZ3M9dGhpcy5mbGFncz0wO3RoaXMuZGVsZXRpb25zPW51bGw7dGhpcy5jaGlsZExhbmVzPXRoaXMubGFuZXM9MDt0aGlzLmFsdGVybmF0ZT1udWxsfWZ1bmN0aW9uIEJnKGEsYixjLGQpe3JldHVybiBuZXcgYWwoYSxiLGMsZCl9ZnVuY3Rpb24gYmooYSl7YT1hLnByb3RvdHlwZTtyZXR1cm4hKCFhfHwhYS5pc1JlYWN0Q29tcG9uZW50KX1cbmZ1bmN0aW9uICRrKGEpe2lmKFwiZnVuY3Rpb25cIj09PXR5cGVvZiBhKXJldHVybiBiaihhKT8xOjA7aWYodm9pZCAwIT09YSYmbnVsbCE9PWEpe2E9YS4kJHR5cGVvZjtpZihhPT09RGEpcmV0dXJuIDExO2lmKGE9PT1HYSlyZXR1cm4gMTR9cmV0dXJuIDJ9XG5mdW5jdGlvbiB3aChhLGIpe3ZhciBjPWEuYWx0ZXJuYXRlO251bGw9PT1jPyhjPUJnKGEudGFnLGIsYS5rZXksYS5tb2RlKSxjLmVsZW1lbnRUeXBlPWEuZWxlbWVudFR5cGUsYy50eXBlPWEudHlwZSxjLnN0YXRlTm9kZT1hLnN0YXRlTm9kZSxjLmFsdGVybmF0ZT1hLGEuYWx0ZXJuYXRlPWMpOihjLnBlbmRpbmdQcm9wcz1iLGMudHlwZT1hLnR5cGUsYy5mbGFncz0wLGMuc3VidHJlZUZsYWdzPTAsYy5kZWxldGlvbnM9bnVsbCk7Yy5mbGFncz1hLmZsYWdzJjE0NjgwMDY0O2MuY2hpbGRMYW5lcz1hLmNoaWxkTGFuZXM7Yy5sYW5lcz1hLmxhbmVzO2MuY2hpbGQ9YS5jaGlsZDtjLm1lbW9pemVkUHJvcHM9YS5tZW1vaXplZFByb3BzO2MubWVtb2l6ZWRTdGF0ZT1hLm1lbW9pemVkU3RhdGU7Yy51cGRhdGVRdWV1ZT1hLnVwZGF0ZVF1ZXVlO2I9YS5kZXBlbmRlbmNpZXM7Yy5kZXBlbmRlbmNpZXM9bnVsbD09PWI/bnVsbDp7bGFuZXM6Yi5sYW5lcyxmaXJzdENvbnRleHQ6Yi5maXJzdENvbnRleHR9O1xuYy5zaWJsaW5nPWEuc2libGluZztjLmluZGV4PWEuaW5kZXg7Yy5yZWY9YS5yZWY7cmV0dXJuIGN9XG5mdW5jdGlvbiB5aChhLGIsYyxkLGUsZil7dmFyIGc9MjtkPWE7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGEpYmooYSkmJihnPTEpO2Vsc2UgaWYoXCJzdHJpbmdcIj09PXR5cGVvZiBhKWc9NTtlbHNlIGE6c3dpdGNoKGEpe2Nhc2UgeWE6cmV0dXJuIEFoKGMuY2hpbGRyZW4sZSxmLGIpO2Nhc2UgemE6Zz04O2V8PTg7YnJlYWs7Y2FzZSBBYTpyZXR1cm4gYT1CZygxMixjLGIsZXwyKSxhLmVsZW1lbnRUeXBlPUFhLGEubGFuZXM9ZixhO2Nhc2UgRWE6cmV0dXJuIGE9QmcoMTMsYyxiLGUpLGEuZWxlbWVudFR5cGU9RWEsYS5sYW5lcz1mLGE7Y2FzZSBGYTpyZXR1cm4gYT1CZygxOSxjLGIsZSksYS5lbGVtZW50VHlwZT1GYSxhLmxhbmVzPWYsYTtjYXNlIElhOnJldHVybiBxaihjLGUsZixiKTtkZWZhdWx0OmlmKFwib2JqZWN0XCI9PT10eXBlb2YgYSYmbnVsbCE9PWEpc3dpdGNoKGEuJCR0eXBlb2Ype2Nhc2UgQmE6Zz0xMDticmVhayBhO2Nhc2UgQ2E6Zz05O2JyZWFrIGE7Y2FzZSBEYTpnPTExO1xuYnJlYWsgYTtjYXNlIEdhOmc9MTQ7YnJlYWsgYTtjYXNlIEhhOmc9MTY7ZD1udWxsO2JyZWFrIGF9dGhyb3cgRXJyb3IocCgxMzAsbnVsbD09YT9hOnR5cGVvZiBhLFwiXCIpKTt9Yj1CZyhnLGMsYixlKTtiLmVsZW1lbnRUeXBlPWE7Yi50eXBlPWQ7Yi5sYW5lcz1mO3JldHVybiBifWZ1bmN0aW9uIEFoKGEsYixjLGQpe2E9QmcoNyxhLGQsYik7YS5sYW5lcz1jO3JldHVybiBhfWZ1bmN0aW9uIHFqKGEsYixjLGQpe2E9QmcoMjIsYSxkLGIpO2EuZWxlbWVudFR5cGU9SWE7YS5sYW5lcz1jO2Euc3RhdGVOb2RlPXtpc0hpZGRlbjohMX07cmV0dXJuIGF9ZnVuY3Rpb24geGgoYSxiLGMpe2E9QmcoNixhLG51bGwsYik7YS5sYW5lcz1jO3JldHVybiBhfVxuZnVuY3Rpb24gemgoYSxiLGMpe2I9QmcoNCxudWxsIT09YS5jaGlsZHJlbj9hLmNoaWxkcmVuOltdLGEua2V5LGIpO2IubGFuZXM9YztiLnN0YXRlTm9kZT17Y29udGFpbmVySW5mbzphLmNvbnRhaW5lckluZm8scGVuZGluZ0NoaWxkcmVuOm51bGwsaW1wbGVtZW50YXRpb246YS5pbXBsZW1lbnRhdGlvbn07cmV0dXJuIGJ9XG5mdW5jdGlvbiBibChhLGIsYyxkLGUpe3RoaXMudGFnPWI7dGhpcy5jb250YWluZXJJbmZvPWE7dGhpcy5maW5pc2hlZFdvcms9dGhpcy5waW5nQ2FjaGU9dGhpcy5jdXJyZW50PXRoaXMucGVuZGluZ0NoaWxkcmVuPW51bGw7dGhpcy50aW1lb3V0SGFuZGxlPS0xO3RoaXMuY2FsbGJhY2tOb2RlPXRoaXMucGVuZGluZ0NvbnRleHQ9dGhpcy5jb250ZXh0PW51bGw7dGhpcy5jYWxsYmFja1ByaW9yaXR5PTA7dGhpcy5ldmVudFRpbWVzPXpjKDApO3RoaXMuZXhwaXJhdGlvblRpbWVzPXpjKC0xKTt0aGlzLmVudGFuZ2xlZExhbmVzPXRoaXMuZmluaXNoZWRMYW5lcz10aGlzLm11dGFibGVSZWFkTGFuZXM9dGhpcy5leHBpcmVkTGFuZXM9dGhpcy5waW5nZWRMYW5lcz10aGlzLnN1c3BlbmRlZExhbmVzPXRoaXMucGVuZGluZ0xhbmVzPTA7dGhpcy5lbnRhbmdsZW1lbnRzPXpjKDApO3RoaXMuaWRlbnRpZmllclByZWZpeD1kO3RoaXMub25SZWNvdmVyYWJsZUVycm9yPWU7dGhpcy5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhPVxubnVsbH1mdW5jdGlvbiBjbChhLGIsYyxkLGUsZixnLGgsayl7YT1uZXcgYmwoYSxiLGMsaCxrKTsxPT09Yj8oYj0xLCEwPT09ZiYmKGJ8PTgpKTpiPTA7Zj1CZygzLG51bGwsbnVsbCxiKTthLmN1cnJlbnQ9ZjtmLnN0YXRlTm9kZT1hO2YubWVtb2l6ZWRTdGF0ZT17ZWxlbWVudDpkLGlzRGVoeWRyYXRlZDpjLGNhY2hlOm51bGwsdHJhbnNpdGlvbnM6bnVsbCxwZW5kaW5nU3VzcGVuc2VCb3VuZGFyaWVzOm51bGx9O2FoKGYpO3JldHVybiBhfWZ1bmN0aW9uIGRsKGEsYixjKXt2YXIgZD0zPGFyZ3VtZW50cy5sZW5ndGgmJnZvaWQgMCE9PWFyZ3VtZW50c1szXT9hcmd1bWVudHNbM106bnVsbDtyZXR1cm57JCR0eXBlb2Y6d2Esa2V5Om51bGw9PWQ/bnVsbDpcIlwiK2QsY2hpbGRyZW46YSxjb250YWluZXJJbmZvOmIsaW1wbGVtZW50YXRpb246Y319XG5mdW5jdGlvbiBlbChhKXtpZighYSlyZXR1cm4gVmY7YT1hLl9yZWFjdEludGVybmFsczthOntpZihWYihhKSE9PWF8fDEhPT1hLnRhZyl0aHJvdyBFcnJvcihwKDE3MCkpO3ZhciBiPWE7ZG97c3dpdGNoKGIudGFnKXtjYXNlIDM6Yj1iLnN0YXRlTm9kZS5jb250ZXh0O2JyZWFrIGE7Y2FzZSAxOmlmKFpmKGIudHlwZSkpe2I9Yi5zdGF0ZU5vZGUuX19yZWFjdEludGVybmFsTWVtb2l6ZWRNZXJnZWRDaGlsZENvbnRleHQ7YnJlYWsgYX19Yj1iLnJldHVybn13aGlsZShudWxsIT09Yik7dGhyb3cgRXJyb3IocCgxNzEpKTt9aWYoMT09PWEudGFnKXt2YXIgYz1hLnR5cGU7aWYoWmYoYykpcmV0dXJuIGJnKGEsYyxiKX1yZXR1cm4gYn1cbmZ1bmN0aW9uIGZsKGEsYixjLGQsZSxmLGcsaCxrKXthPWNsKGMsZCwhMCxhLGUsZixnLGgsayk7YS5jb250ZXh0PWVsKG51bGwpO2M9YS5jdXJyZW50O2Q9TCgpO2U9bGgoYyk7Zj1jaChkLGUpO2YuY2FsbGJhY2s9dm9pZCAwIT09YiYmbnVsbCE9PWI/YjpudWxsO2RoKGMsZixlKTthLmN1cnJlbnQubGFuZXM9ZTtBYyhhLGUsZCk7RWsoYSxkKTtyZXR1cm4gYX1mdW5jdGlvbiBnbChhLGIsYyxkKXt2YXIgZT1iLmN1cnJlbnQsZj1MKCksZz1saChlKTtjPWVsKGMpO251bGw9PT1iLmNvbnRleHQ/Yi5jb250ZXh0PWM6Yi5wZW5kaW5nQ29udGV4dD1jO2I9Y2goZixnKTtiLnBheWxvYWQ9e2VsZW1lbnQ6YX07ZD12b2lkIDA9PT1kP251bGw6ZDtudWxsIT09ZCYmKGIuY2FsbGJhY2s9ZCk7YT1kaChlLGIsZyk7bnVsbCE9PWEmJihtaChhLGUsZyxmKSxlaChhLGUsZykpO3JldHVybiBnfVxuZnVuY3Rpb24gaGwoYSl7YT1hLmN1cnJlbnQ7aWYoIWEuY2hpbGQpcmV0dXJuIG51bGw7c3dpdGNoKGEuY2hpbGQudGFnKXtjYXNlIDU6cmV0dXJuIGEuY2hpbGQuc3RhdGVOb2RlO2RlZmF1bHQ6cmV0dXJuIGEuY2hpbGQuc3RhdGVOb2RlfX1mdW5jdGlvbiBpbChhLGIpe2E9YS5tZW1vaXplZFN0YXRlO2lmKG51bGwhPT1hJiZudWxsIT09YS5kZWh5ZHJhdGVkKXt2YXIgYz1hLnJldHJ5TGFuZTthLnJldHJ5TGFuZT0wIT09YyYmYzxiP2M6Yn19ZnVuY3Rpb24gamwoYSxiKXtpbChhLGIpOyhhPWEuYWx0ZXJuYXRlKSYmaWwoYSxiKX1mdW5jdGlvbiBrbCgpe3JldHVybiBudWxsfXZhciBsbD1cImZ1bmN0aW9uXCI9PT10eXBlb2YgcmVwb3J0RXJyb3I/cmVwb3J0RXJyb3I6ZnVuY3Rpb24oYSl7Y29uc29sZS5lcnJvcihhKX07ZnVuY3Rpb24gbWwoYSl7dGhpcy5faW50ZXJuYWxSb290PWF9XG5ubC5wcm90b3R5cGUucmVuZGVyPW1sLnByb3RvdHlwZS5yZW5kZXI9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5faW50ZXJuYWxSb290O2lmKG51bGw9PT1iKXRocm93IEVycm9yKHAoNDA5KSk7Z2woYSxiLG51bGwsbnVsbCl9O25sLnByb3RvdHlwZS51bm1vdW50PW1sLnByb3RvdHlwZS51bm1vdW50PWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5faW50ZXJuYWxSb290O2lmKG51bGwhPT1hKXt0aGlzLl9pbnRlcm5hbFJvb3Q9bnVsbDt2YXIgYj1hLmNvbnRhaW5lckluZm87U2soZnVuY3Rpb24oKXtnbChudWxsLGEsbnVsbCxudWxsKX0pO2JbdWZdPW51bGx9fTtmdW5jdGlvbiBubChhKXt0aGlzLl9pbnRlcm5hbFJvb3Q9YX1cbm5sLnByb3RvdHlwZS51bnN0YWJsZV9zY2hlZHVsZUh5ZHJhdGlvbj1mdW5jdGlvbihhKXtpZihhKXt2YXIgYj1IYygpO2E9e2Jsb2NrZWRPbjpudWxsLHRhcmdldDphLHByaW9yaXR5OmJ9O2Zvcih2YXIgYz0wO2M8UWMubGVuZ3RoJiYwIT09YiYmYjxRY1tjXS5wcmlvcml0eTtjKyspO1FjLnNwbGljZShjLDAsYSk7MD09PWMmJlZjKGEpfX07ZnVuY3Rpb24gb2woYSl7cmV0dXJuISghYXx8MSE9PWEubm9kZVR5cGUmJjkhPT1hLm5vZGVUeXBlJiYxMSE9PWEubm9kZVR5cGUpfWZ1bmN0aW9uIHBsKGEpe3JldHVybiEoIWF8fDEhPT1hLm5vZGVUeXBlJiY5IT09YS5ub2RlVHlwZSYmMTEhPT1hLm5vZGVUeXBlJiYoOCE9PWEubm9kZVR5cGV8fFwiIHJlYWN0LW1vdW50LXBvaW50LXVuc3RhYmxlIFwiIT09YS5ub2RlVmFsdWUpKX1mdW5jdGlvbiBxbCgpe31cbmZ1bmN0aW9uIHJsKGEsYixjLGQsZSl7aWYoZSl7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGQpe3ZhciBmPWQ7ZD1mdW5jdGlvbigpe3ZhciBhPWhsKGcpO2YuY2FsbChhKX19dmFyIGc9ZmwoYixkLGEsMCxudWxsLCExLCExLFwiXCIscWwpO2EuX3JlYWN0Um9vdENvbnRhaW5lcj1nO2FbdWZdPWcuY3VycmVudDtzZig4PT09YS5ub2RlVHlwZT9hLnBhcmVudE5vZGU6YSk7U2soKTtyZXR1cm4gZ31mb3IoO2U9YS5sYXN0Q2hpbGQ7KWEucmVtb3ZlQ2hpbGQoZSk7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGQpe3ZhciBoPWQ7ZD1mdW5jdGlvbigpe3ZhciBhPWhsKGspO2guY2FsbChhKX19dmFyIGs9Y2woYSwwLCExLG51bGwsbnVsbCwhMSwhMSxcIlwiLHFsKTthLl9yZWFjdFJvb3RDb250YWluZXI9azthW3VmXT1rLmN1cnJlbnQ7c2YoOD09PWEubm9kZVR5cGU/YS5wYXJlbnROb2RlOmEpO1NrKGZ1bmN0aW9uKCl7Z2woYixrLGMsZCl9KTtyZXR1cm4ga31cbmZ1bmN0aW9uIHNsKGEsYixjLGQsZSl7dmFyIGY9Yy5fcmVhY3RSb290Q29udGFpbmVyO2lmKGYpe3ZhciBnPWY7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGUpe3ZhciBoPWU7ZT1mdW5jdGlvbigpe3ZhciBhPWhsKGcpO2guY2FsbChhKX19Z2woYixnLGEsZSl9ZWxzZSBnPXJsKGMsYixhLGUsZCk7cmV0dXJuIGhsKGcpfUVjPWZ1bmN0aW9uKGEpe3N3aXRjaChhLnRhZyl7Y2FzZSAzOnZhciBiPWEuc3RhdGVOb2RlO2lmKGIuY3VycmVudC5tZW1vaXplZFN0YXRlLmlzRGVoeWRyYXRlZCl7dmFyIGM9dGMoYi5wZW5kaW5nTGFuZXMpOzAhPT1jJiYoQ2MoYixjfDEpLEVrKGIsQigpKSwwPT09KEsmNikmJihIaj1CKCkrNTAwLGpnKCkpKX1icmVhaztjYXNlIDEzOlNrKGZ1bmN0aW9uKCl7dmFyIGI9WmcoYSwxKTtpZihudWxsIT09Yil7dmFyIGM9TCgpO21oKGIsYSwxLGMpfX0pLGpsKGEsMSl9fTtcbkZjPWZ1bmN0aW9uKGEpe2lmKDEzPT09YS50YWcpe3ZhciBiPVpnKGEsMTM0MjE3NzI4KTtpZihudWxsIT09Yil7dmFyIGM9TCgpO21oKGIsYSwxMzQyMTc3MjgsYyl9amwoYSwxMzQyMTc3MjgpfX07R2M9ZnVuY3Rpb24oYSl7aWYoMTM9PT1hLnRhZyl7dmFyIGI9bGgoYSksYz1aZyhhLGIpO2lmKG51bGwhPT1jKXt2YXIgZD1MKCk7bWgoYyxhLGIsZCl9amwoYSxiKX19O0hjPWZ1bmN0aW9uKCl7cmV0dXJuIEN9O0ljPWZ1bmN0aW9uKGEsYil7dmFyIGM9Qzt0cnl7cmV0dXJuIEM9YSxiKCl9ZmluYWxseXtDPWN9fTtcbnliPWZ1bmN0aW9uKGEsYixjKXtzd2l0Y2goYil7Y2FzZSBcImlucHV0XCI6YmIoYSxjKTtiPWMubmFtZTtpZihcInJhZGlvXCI9PT1jLnR5cGUmJm51bGwhPWIpe2ZvcihjPWE7Yy5wYXJlbnROb2RlOyljPWMucGFyZW50Tm9kZTtjPWMucXVlcnlTZWxlY3RvckFsbChcImlucHV0W25hbWU9XCIrSlNPTi5zdHJpbmdpZnkoXCJcIitiKSsnXVt0eXBlPVwicmFkaW9cIl0nKTtmb3IoYj0wO2I8Yy5sZW5ndGg7YisrKXt2YXIgZD1jW2JdO2lmKGQhPT1hJiZkLmZvcm09PT1hLmZvcm0pe3ZhciBlPURiKGQpO2lmKCFlKXRocm93IEVycm9yKHAoOTApKTtXYShkKTtiYihkLGUpfX19YnJlYWs7Y2FzZSBcInRleHRhcmVhXCI6aWIoYSxjKTticmVhaztjYXNlIFwic2VsZWN0XCI6Yj1jLnZhbHVlLG51bGwhPWImJmZiKGEsISFjLm11bHRpcGxlLGIsITEpfX07R2I9Ums7SGI9U2s7XG52YXIgdGw9e3VzaW5nQ2xpZW50RW50cnlQb2ludDohMSxFdmVudHM6W0NiLHVlLERiLEViLEZiLFJrXX0sdWw9e2ZpbmRGaWJlckJ5SG9zdEluc3RhbmNlOldjLGJ1bmRsZVR5cGU6MCx2ZXJzaW9uOlwiMTguMi4wXCIscmVuZGVyZXJQYWNrYWdlTmFtZTpcInJlYWN0LWRvbVwifTtcbnZhciB2bD17YnVuZGxlVHlwZTp1bC5idW5kbGVUeXBlLHZlcnNpb246dWwudmVyc2lvbixyZW5kZXJlclBhY2thZ2VOYW1lOnVsLnJlbmRlcmVyUGFja2FnZU5hbWUscmVuZGVyZXJDb25maWc6dWwucmVuZGVyZXJDb25maWcsb3ZlcnJpZGVIb29rU3RhdGU6bnVsbCxvdmVycmlkZUhvb2tTdGF0ZURlbGV0ZVBhdGg6bnVsbCxvdmVycmlkZUhvb2tTdGF0ZVJlbmFtZVBhdGg6bnVsbCxvdmVycmlkZVByb3BzOm51bGwsb3ZlcnJpZGVQcm9wc0RlbGV0ZVBhdGg6bnVsbCxvdmVycmlkZVByb3BzUmVuYW1lUGF0aDpudWxsLHNldEVycm9ySGFuZGxlcjpudWxsLHNldFN1c3BlbnNlSGFuZGxlcjpudWxsLHNjaGVkdWxlVXBkYXRlOm51bGwsY3VycmVudERpc3BhdGNoZXJSZWY6dWEuUmVhY3RDdXJyZW50RGlzcGF0Y2hlcixmaW5kSG9zdEluc3RhbmNlQnlGaWJlcjpmdW5jdGlvbihhKXthPVpiKGEpO3JldHVybiBudWxsPT09YT9udWxsOmEuc3RhdGVOb2RlfSxmaW5kRmliZXJCeUhvc3RJbnN0YW5jZTp1bC5maW5kRmliZXJCeUhvc3RJbnN0YW5jZXx8XG5rbCxmaW5kSG9zdEluc3RhbmNlc0ZvclJlZnJlc2g6bnVsbCxzY2hlZHVsZVJlZnJlc2g6bnVsbCxzY2hlZHVsZVJvb3Q6bnVsbCxzZXRSZWZyZXNoSGFuZGxlcjpudWxsLGdldEN1cnJlbnRGaWJlcjpudWxsLHJlY29uY2lsZXJWZXJzaW9uOlwiMTguMi4wLW5leHQtOWUzYjc3MmI4LTIwMjIwNjA4XCJ9O2lmKFwidW5kZWZpbmVkXCIhPT10eXBlb2YgX19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fKXt2YXIgd2w9X19SRUFDVF9ERVZUT09MU19HTE9CQUxfSE9PS19fO2lmKCF3bC5pc0Rpc2FibGVkJiZ3bC5zdXBwb3J0c0ZpYmVyKXRyeXtrYz13bC5pbmplY3QodmwpLGxjPXdsfWNhdGNoKGEpe319ZXhwb3J0cy5fX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRD10bDtcbmV4cG9ydHMuY3JlYXRlUG9ydGFsPWZ1bmN0aW9uKGEsYil7dmFyIGM9Mjxhcmd1bWVudHMubGVuZ3RoJiZ2b2lkIDAhPT1hcmd1bWVudHNbMl0/YXJndW1lbnRzWzJdOm51bGw7aWYoIW9sKGIpKXRocm93IEVycm9yKHAoMjAwKSk7cmV0dXJuIGRsKGEsYixudWxsLGMpfTtleHBvcnRzLmNyZWF0ZVJvb3Q9ZnVuY3Rpb24oYSxiKXtpZighb2woYSkpdGhyb3cgRXJyb3IocCgyOTkpKTt2YXIgYz0hMSxkPVwiXCIsZT1sbDtudWxsIT09YiYmdm9pZCAwIT09YiYmKCEwPT09Yi51bnN0YWJsZV9zdHJpY3RNb2RlJiYoYz0hMCksdm9pZCAwIT09Yi5pZGVudGlmaWVyUHJlZml4JiYoZD1iLmlkZW50aWZpZXJQcmVmaXgpLHZvaWQgMCE9PWIub25SZWNvdmVyYWJsZUVycm9yJiYoZT1iLm9uUmVjb3ZlcmFibGVFcnJvcikpO2I9Y2woYSwxLCExLG51bGwsbnVsbCxjLCExLGQsZSk7YVt1Zl09Yi5jdXJyZW50O3NmKDg9PT1hLm5vZGVUeXBlP2EucGFyZW50Tm9kZTphKTtyZXR1cm4gbmV3IG1sKGIpfTtcbmV4cG9ydHMuZmluZERPTU5vZGU9ZnVuY3Rpb24oYSl7aWYobnVsbD09YSlyZXR1cm4gbnVsbDtpZigxPT09YS5ub2RlVHlwZSlyZXR1cm4gYTt2YXIgYj1hLl9yZWFjdEludGVybmFscztpZih2b2lkIDA9PT1iKXtpZihcImZ1bmN0aW9uXCI9PT10eXBlb2YgYS5yZW5kZXIpdGhyb3cgRXJyb3IocCgxODgpKTthPU9iamVjdC5rZXlzKGEpLmpvaW4oXCIsXCIpO3Rocm93IEVycm9yKHAoMjY4LGEpKTt9YT1aYihiKTthPW51bGw9PT1hP251bGw6YS5zdGF0ZU5vZGU7cmV0dXJuIGF9O2V4cG9ydHMuZmx1c2hTeW5jPWZ1bmN0aW9uKGEpe3JldHVybiBTayhhKX07ZXhwb3J0cy5oeWRyYXRlPWZ1bmN0aW9uKGEsYixjKXtpZighcGwoYikpdGhyb3cgRXJyb3IocCgyMDApKTtyZXR1cm4gc2wobnVsbCxhLGIsITAsYyl9O1xuZXhwb3J0cy5oeWRyYXRlUm9vdD1mdW5jdGlvbihhLGIsYyl7aWYoIW9sKGEpKXRocm93IEVycm9yKHAoNDA1KSk7dmFyIGQ9bnVsbCE9YyYmYy5oeWRyYXRlZFNvdXJjZXN8fG51bGwsZT0hMSxmPVwiXCIsZz1sbDtudWxsIT09YyYmdm9pZCAwIT09YyYmKCEwPT09Yy51bnN0YWJsZV9zdHJpY3RNb2RlJiYoZT0hMCksdm9pZCAwIT09Yy5pZGVudGlmaWVyUHJlZml4JiYoZj1jLmlkZW50aWZpZXJQcmVmaXgpLHZvaWQgMCE9PWMub25SZWNvdmVyYWJsZUVycm9yJiYoZz1jLm9uUmVjb3ZlcmFibGVFcnJvcikpO2I9ZmwoYixudWxsLGEsMSxudWxsIT1jP2M6bnVsbCxlLCExLGYsZyk7YVt1Zl09Yi5jdXJyZW50O3NmKGEpO2lmKGQpZm9yKGE9MDthPGQubGVuZ3RoO2ErKyljPWRbYV0sZT1jLl9nZXRWZXJzaW9uLGU9ZShjLl9zb3VyY2UpLG51bGw9PWIubXV0YWJsZVNvdXJjZUVhZ2VySHlkcmF0aW9uRGF0YT9iLm11dGFibGVTb3VyY2VFYWdlckh5ZHJhdGlvbkRhdGE9W2MsZV06Yi5tdXRhYmxlU291cmNlRWFnZXJIeWRyYXRpb25EYXRhLnB1c2goYyxcbmUpO3JldHVybiBuZXcgbmwoYil9O2V4cG9ydHMucmVuZGVyPWZ1bmN0aW9uKGEsYixjKXtpZighcGwoYikpdGhyb3cgRXJyb3IocCgyMDApKTtyZXR1cm4gc2wobnVsbCxhLGIsITEsYyl9O2V4cG9ydHMudW5tb3VudENvbXBvbmVudEF0Tm9kZT1mdW5jdGlvbihhKXtpZighcGwoYSkpdGhyb3cgRXJyb3IocCg0MCkpO3JldHVybiBhLl9yZWFjdFJvb3RDb250YWluZXI/KFNrKGZ1bmN0aW9uKCl7c2wobnVsbCxudWxsLGEsITEsZnVuY3Rpb24oKXthLl9yZWFjdFJvb3RDb250YWluZXI9bnVsbDthW3VmXT1udWxsfSl9KSwhMCk6ITF9O2V4cG9ydHMudW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXM9Ums7XG5leHBvcnRzLnVuc3RhYmxlX3JlbmRlclN1YnRyZWVJbnRvQ29udGFpbmVyPWZ1bmN0aW9uKGEsYixjLGQpe2lmKCFwbChjKSl0aHJvdyBFcnJvcihwKDIwMCkpO2lmKG51bGw9PWF8fHZvaWQgMD09PWEuX3JlYWN0SW50ZXJuYWxzKXRocm93IEVycm9yKHAoMzgpKTtyZXR1cm4gc2woYSxiLGMsITEsZCl9O2V4cG9ydHMudmVyc2lvbj1cIjE4LjIuMC1uZXh0LTllM2I3NzJiOC0yMDIyMDYwOFwiO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///448\n')},745:(__unused_webpack_module,exports,__webpack_require__)=>{"use strict";eval("var __webpack_unused_export__;\n\n\nvar m = __webpack_require__(935);\nif (true) {\n exports.s = m.createRoot;\n __webpack_unused_export__ = m.hydrateRoot;\n} else { var i; }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzQ1LmpzIiwibWFwcGluZ3MiOiI7QUFBYTs7QUFFYixRQUFRLG1CQUFPLENBQUMsR0FBVztBQUMzQixJQUFJLElBQXFDO0FBQ3pDLEVBQUUsU0FBa0I7QUFDcEIsRUFBRSx5QkFBbUI7QUFDckIsRUFBRSxLQUFLLFVBa0JOIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9jbGllbnQuanM/MTFiMSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBtID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBtLmNyZWF0ZVJvb3Q7XG4gIGV4cG9ydHMuaHlkcmF0ZVJvb3QgPSBtLmh5ZHJhdGVSb290O1xufSBlbHNlIHtcbiAgdmFyIGkgPSBtLl9fU0VDUkVUX0lOVEVSTkFMU19ET19OT1RfVVNFX09SX1lPVV9XSUxMX0JFX0ZJUkVEO1xuICBleHBvcnRzLmNyZWF0ZVJvb3QgPSBmdW5jdGlvbihjLCBvKSB7XG4gICAgaS51c2luZ0NsaWVudEVudHJ5UG9pbnQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbS5jcmVhdGVSb290KGMsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbiAgZXhwb3J0cy5oeWRyYXRlUm9vdCA9IGZ1bmN0aW9uKGMsIGgsIG8pIHtcbiAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBtLmh5ZHJhdGVSb290KGMsIGgsIG8pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpLnVzaW5nQ2xpZW50RW50cnlQb2ludCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///745\n")},935:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nfunction checkDCE() {\n /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\n if (\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'\n ) {\n return;\n }\n if (false) {}\n try {\n // Verify that the code above has been dead code eliminated (DCE'd).\n __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);\n } catch (err) {\n // DevTools shouldn't crash React, no matter what.\n // We should still report in case we break this code.\n console.error(err);\n }\n}\n\nif (true) {\n // DCE check should happen before ReactDOM bundle executes so that\n // DevTools can report bad minification during injection.\n checkDCE();\n module.exports = __webpack_require__(448);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOTM1LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLEtBQXFDLEVBQUUsRUFTMUM7QUFDSDtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJLElBQXFDO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBLEVBQUUseUNBQTZEO0FBQy9ELEVBQUUsS0FBSyxFQUVOIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3JlYWN0LWRvbS9pbmRleC5qcz84YmM4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gY2hlY2tEQ0UoKSB7XG4gIC8qIGdsb2JhbCBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gKi9cbiAgaWYgKFxuICAgIHR5cGVvZiBfX1JFQUNUX0RFVlRPT0xTX0dMT0JBTF9IT09LX18gPT09ICd1bmRlZmluZWQnIHx8XG4gICAgdHlwZW9mIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRSAhPT0gJ2Z1bmN0aW9uJ1xuICApIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgICAvLyBUaGlzIGJyYW5jaCBpcyB1bnJlYWNoYWJsZSBiZWNhdXNlIHRoaXMgZnVuY3Rpb24gaXMgb25seSBjYWxsZWRcbiAgICAvLyBpbiBwcm9kdWN0aW9uLCBidXQgdGhlIGNvbmRpdGlvbiBpcyB0cnVlIG9ubHkgaW4gZGV2ZWxvcG1lbnQuXG4gICAgLy8gVGhlcmVmb3JlIGlmIHRoZSBicmFuY2ggaXMgc3RpbGwgaGVyZSwgZGVhZCBjb2RlIGVsaW1pbmF0aW9uIHdhc24ndFxuICAgIC8vIHByb3Blcmx5IGFwcGxpZWQuXG4gICAgLy8gRG9uJ3QgY2hhbmdlIHRoZSBtZXNzYWdlLiBSZWFjdCBEZXZUb29scyByZWxpZXMgb24gaXQuIEFsc28gbWFrZSBzdXJlXG4gICAgLy8gdGhpcyBtZXNzYWdlIGRvZXNuJ3Qgb2NjdXIgZWxzZXdoZXJlIGluIHRoaXMgZnVuY3Rpb24sIG9yIGl0IHdpbGwgY2F1c2VcbiAgICAvLyBhIGZhbHNlIHBvc2l0aXZlLlxuICAgIHRocm93IG5ldyBFcnJvcignXl9eJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICAvLyBWZXJpZnkgdGhhdCB0aGUgY29kZSBhYm92ZSBoYXMgYmVlbiBkZWFkIGNvZGUgZWxpbWluYXRlZCAoRENFJ2QpLlxuICAgIF9fUkVBQ1RfREVWVE9PTFNfR0xPQkFMX0hPT0tfXy5jaGVja0RDRShjaGVja0RDRSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIC8vIERldlRvb2xzIHNob3VsZG4ndCBjcmFzaCBSZWFjdCwgbm8gbWF0dGVyIHdoYXQuXG4gICAgLy8gV2Ugc2hvdWxkIHN0aWxsIHJlcG9ydCBpbiBjYXNlIHdlIGJyZWFrIHRoaXMgY29kZS5cbiAgICBjb25zb2xlLmVycm9yKGVycik7XG4gIH1cbn1cblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSAncHJvZHVjdGlvbicpIHtcbiAgLy8gRENFIGNoZWNrIHNob3VsZCBoYXBwZW4gYmVmb3JlIFJlYWN0RE9NIGJ1bmRsZSBleGVjdXRlcyBzbyB0aGF0XG4gIC8vIERldlRvb2xzIGNhbiByZXBvcnQgYmFkIG1pbmlmaWNhdGlvbiBkdXJpbmcgaW5qZWN0aW9uLlxuICBjaGVja0RDRSgpO1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3JlYWN0LWRvbS5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9yZWFjdC1kb20uZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///935\n")},408:(__unused_webpack_module,exports)=>{"use strict";eval('/**\n * @license React\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nvar l=Symbol.for("react.element"),n=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),q=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),t=Symbol.for("react.provider"),u=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),z=Symbol.iterator;function A(a){if(null===a||"object"!==typeof a)return null;a=z&&a[z]||a["@@iterator"];return"function"===typeof a?a:null}\nvar B={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}E.prototype.isReactComponent={};\nE.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState")};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B}var H=G.prototype=new F;\nH.constructor=G;C(H,E.prototype);H.isPureReactComponent=!0;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:!0,ref:!0,__self:!0,__source:!0};\nfunction M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f}if(a&&a.defaultProps)for(d in g=a.defaultProps,g)void 0===c[d]&&(c[d]=g[d]);return{$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}\nfunction N(a,b){return{$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return"object"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={"=":"=0",":":"=2"};return"$"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\\/+/g;function Q(a,b){return"object"===typeof a&&null!==a&&null!=a.key?escape(""+a.key):b.toString(36)}\nfunction R(a,b,e,d,c){var k=typeof a;if("undefined"===k||"boolean"===k)a=null;var h=!1;if(null===a)h=!0;else switch(k){case "string":case "number":h=!0;break;case "object":switch(a.$$typeof){case l:case n:h=!0}}if(h)return h=a,c=c(h),a=""===d?"."+Q(h,0):d,I(c)?(e="",null!=a&&(e=a.replace(P,"$&/")+"/"),R(c,b,e,"",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?"":(""+c.key).replace(P,"$&/")+"/")+a)),b.push(c)),1;h=0;d=""===d?".":d+":";if(I(a))for(var g=0;g<a.length;g++){k=\na[g];var f=d+Q(k,g);h+=R(k,b,e,f,c)}else if(f=A(a),"function"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if("object"===k)throw b=String(a),Error("Objects are not valid as a React child (found: "+("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}\nfunction S(a,b,e){if(null==a)return a;var d=[],c=0;R(a,d,"","",function(a){return b.call(e,a,c++)});return d}function T(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b});-1===a._status&&(a._status=0,a._result=b)}if(1===a._status)return a._result.default;throw a._result;}\nvar U={current:null},V={transition:null},W={ReactCurrentDispatcher:U,ReactCurrentBatchConfig:V,ReactCurrentOwner:K};exports.Children={map:S,forEach:function(a,b,e){S(a,function(){b.apply(this,arguments)},e)},count:function(a){var b=0;S(a,function(){b++});return b},toArray:function(a){return S(a,function(a){return a})||[]},only:function(a){if(!O(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};exports.Component=E;exports.Fragment=p;\nexports.Profiler=r;exports.PureComponent=G;exports.StrictMode=q;exports.Suspense=w;exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=W;\nexports.cloneElement=function(a,b,e){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var d=C({},a.props),c=a.key,k=a.ref,h=a._owner;if(null!=b){void 0!==b.ref&&(k=b.ref,h=K.current);void 0!==b.key&&(c=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)J.call(b,f)&&!L.hasOwnProperty(f)&&(d[f]=void 0===b[f]&&void 0!==g?g[f]:b[f])}var f=arguments.length-2;if(1===f)d.children=e;else if(1<f){g=Array(f);\nfor(var m=0;m<f;m++)g[m]=arguments[m+2];d.children=g}return{$$typeof:l,type:a.type,key:c,ref:k,props:d,_owner:h}};exports.createContext=function(a){a={$$typeof:u,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:t,_context:a};return a.Consumer=a};exports.createElement=M;exports.createFactory=function(a){var b=M.bind(null,a);b.type=a;return b};exports.createRef=function(){return{current:null}};\nexports.forwardRef=function(a){return{$$typeof:v,render:a}};exports.isValidElement=O;exports.lazy=function(a){return{$$typeof:y,_payload:{_status:-1,_result:a},_init:T}};exports.memo=function(a,b){return{$$typeof:x,type:a,compare:void 0===b?null:b}};exports.startTransition=function(a){var b=V.transition;V.transition={};try{a()}finally{V.transition=b}};exports.unstable_act=function(){throw Error("act(...) is not supported in production builds of React.");};\nexports.useCallback=function(a,b){return U.current.useCallback(a,b)};exports.useContext=function(a){return U.current.useContext(a)};exports.useDebugValue=function(){};exports.useDeferredValue=function(a){return U.current.useDeferredValue(a)};exports.useEffect=function(a,b){return U.current.useEffect(a,b)};exports.useId=function(){return U.current.useId()};exports.useImperativeHandle=function(a,b,e){return U.current.useImperativeHandle(a,b,e)};\nexports.useInsertionEffect=function(a,b){return U.current.useInsertionEffect(a,b)};exports.useLayoutEffect=function(a,b){return U.current.useLayoutEffect(a,b)};exports.useMemo=function(a,b){return U.current.useMemo(a,b)};exports.useReducer=function(a,b,e){return U.current.useReducer(a,b,e)};exports.useRef=function(a){return U.current.useRef(a)};exports.useState=function(a){return U.current.useState(a)};exports.useSyncExternalStore=function(a,b,e){return U.current.useSyncExternalStore(a,b,e)};\nexports.useTransition=function(){return U.current.useTransition()};exports.version="18.2.0";\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDA4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNhLHFXQUFxVyxjQUFjLDZDQUE2QywyQkFBMkI7QUFDeGMsT0FBTyxxQkFBcUIsU0FBUyxnQ0FBZ0MsaUNBQWlDLDhCQUE4QixzQkFBc0Isa0JBQWtCLGFBQWEsZUFBZSxZQUFZLGtCQUFrQjtBQUN0TyxtQ0FBbUMsNExBQTRMLG1EQUFtRCxvQ0FBb0MsdURBQXVELGNBQWMsd0JBQXdCLGtCQUFrQixhQUFhLGVBQWUsWUFBWSxrQkFBa0I7QUFDL2QsZ0JBQWdCLGlCQUFpQiwwQkFBMEIseURBQXlELGFBQWEsSUFBSTtBQUNySSxrQkFBa0IsVUFBVSxlQUFlLDRIQUE0SCx5QkFBeUIsc0JBQXNCLGFBQWEsdUJBQXVCLElBQUksd0JBQXdCLGFBQWEsNEVBQTRFLE9BQU87QUFDdFgsZ0JBQWdCLE9BQU8sc0VBQXNFLGNBQWMsb0RBQW9ELG1CQUFtQixPQUFPLG1CQUFtQix3Q0FBd0MsWUFBWSxFQUFFLGFBQWEsZ0JBQWdCO0FBQy9SLHNCQUFzQixlQUFlLHlDQUF5QyxTQUFTLGlCQUFpQixlQUFlLGlDQUFpQyxNQUFNLGlDQUFpQyxvQkFBb0IsbUhBQW1ILFNBQVMsMkdBQTJHLElBQUksbUJBQW1CLG9CQUFvQixXQUFXLEtBQUs7QUFDcmYsS0FBSyxlQUFlLGdCQUFnQix5REFBeUQsbUJBQW1CLHdDQUF3Qyx5SUFBeUksOEJBQThCLGtGQUFrRjtBQUNqWixrQkFBa0Isb0JBQW9CLGFBQWEsd0JBQXdCLHVCQUF1QixFQUFFLFNBQVMsY0FBYyxtQkFBbUIsZ0JBQWdCLE1BQU0sbUJBQW1CLHlEQUF5RCxhQUFhLHlEQUF5RCxFQUFFLDBDQUEwQywwQ0FBMEM7QUFDNVksT0FBTyxhQUFhLElBQUksZ0JBQWdCLElBQUksd0VBQXdFLGdCQUFnQixFQUFFLDhCQUE4QixlQUFlLHdCQUF3QixJQUFJLG1CQUFtQixRQUFRLGVBQWUsSUFBSSxFQUFFLFNBQVMscUJBQXFCLHVCQUF1QixTQUFTLE1BQU0sa0JBQWtCLDhGQUE4RixXQUFXLGlCQUFpQixHQUFHLGdCQUFnQjtBQUNsZSxnQkFBZ0IsR0FBRyxxQkFBcUIsR0FBRyxrQkFBa0IsR0FBRyxnQkFBZ0IsR0FBRywwREFBMEQ7QUFDN0ksb0JBQW9CLGlCQUFpQiw0SEFBNEgsVUFBVSxxQ0FBcUMsWUFBWSxzQ0FBc0MsNkJBQTZCLHlEQUF5RCx5RkFBeUYseUJBQXlCLHNCQUFzQixhQUFhO0FBQzdlLFlBQVksSUFBSSx3QkFBd0IsYUFBYSxPQUFPLHNEQUFzRCxxQkFBcUIsYUFBYSxHQUFHLDRIQUE0SCxZQUFZLHVCQUF1QixxQkFBcUIscUJBQXFCLEdBQUcscUJBQXFCLGFBQWEscUJBQXFCLFNBQVMsVUFBVSxpQkFBaUIsWUFBWSxPQUFPO0FBQ2pkLGtCQUFrQixhQUFhLE9BQU8sc0JBQXNCLHNCQUFzQixHQUFHLFlBQVksYUFBYSxPQUFPLHFCQUFxQixxQkFBcUIsV0FBVyxZQUFZLGVBQWUsT0FBTyw4Q0FBOEMsdUJBQXVCLGFBQWEsbUJBQW1CLGdCQUFnQixJQUFJLElBQUksUUFBUSxpQkFBaUIsb0JBQW9CLFlBQVk7QUFDbFksbUJBQW1CLGVBQWUsbUNBQW1DLGtCQUFrQixhQUFhLGdDQUFnQyxxQkFBcUIsY0FBYyx3QkFBd0IsYUFBYSxzQ0FBc0MsaUJBQWlCLGVBQWUsaUNBQWlDLGFBQWEsWUFBWSwwQkFBMEIsMkJBQTJCLGlCQUFpQjtBQUNsWiwwQkFBMEIsZUFBZSwwQ0FBMEMsdUJBQXVCLGVBQWUsdUNBQXVDLGVBQWUsZUFBZSwrQkFBK0Isa0JBQWtCLGlCQUFpQixvQ0FBb0MsY0FBYyxhQUFhLDRCQUE0QixnQkFBZ0IsYUFBYSw4QkFBOEIsNEJBQTRCLGlCQUFpQjtBQUNuYyxxQkFBcUIsWUFBWSxrQ0FBa0MsZUFBZSIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9yZWFjdC9janMvcmVhY3QucHJvZHVjdGlvbi5taW4uanM/YmUyNCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlIFJlYWN0XG4gKiByZWFjdC5wcm9kdWN0aW9uLm1pbi5qc1xuICpcbiAqIENvcHlyaWdodCAoYykgRmFjZWJvb2ssIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLlxuICovXG4ndXNlIHN0cmljdCc7dmFyIGw9U3ltYm9sLmZvcihcInJlYWN0LmVsZW1lbnRcIiksbj1TeW1ib2wuZm9yKFwicmVhY3QucG9ydGFsXCIpLHA9U3ltYm9sLmZvcihcInJlYWN0LmZyYWdtZW50XCIpLHE9U3ltYm9sLmZvcihcInJlYWN0LnN0cmljdF9tb2RlXCIpLHI9U3ltYm9sLmZvcihcInJlYWN0LnByb2ZpbGVyXCIpLHQ9U3ltYm9sLmZvcihcInJlYWN0LnByb3ZpZGVyXCIpLHU9U3ltYm9sLmZvcihcInJlYWN0LmNvbnRleHRcIiksdj1TeW1ib2wuZm9yKFwicmVhY3QuZm9yd2FyZF9yZWZcIiksdz1TeW1ib2wuZm9yKFwicmVhY3Quc3VzcGVuc2VcIikseD1TeW1ib2wuZm9yKFwicmVhY3QubWVtb1wiKSx5PVN5bWJvbC5mb3IoXCJyZWFjdC5sYXp5XCIpLHo9U3ltYm9sLml0ZXJhdG9yO2Z1bmN0aW9uIEEoYSl7aWYobnVsbD09PWF8fFwib2JqZWN0XCIhPT10eXBlb2YgYSlyZXR1cm4gbnVsbDthPXomJmFbel18fGFbXCJAQGl0ZXJhdG9yXCJdO3JldHVyblwiZnVuY3Rpb25cIj09PXR5cGVvZiBhP2E6bnVsbH1cbnZhciBCPXtpc01vdW50ZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hMX0sZW5xdWV1ZUZvcmNlVXBkYXRlOmZ1bmN0aW9uKCl7fSxlbnF1ZXVlUmVwbGFjZVN0YXRlOmZ1bmN0aW9uKCl7fSxlbnF1ZXVlU2V0U3RhdGU6ZnVuY3Rpb24oKXt9fSxDPU9iamVjdC5hc3NpZ24sRD17fTtmdW5jdGlvbiBFKGEsYixlKXt0aGlzLnByb3BzPWE7dGhpcy5jb250ZXh0PWI7dGhpcy5yZWZzPUQ7dGhpcy51cGRhdGVyPWV8fEJ9RS5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudD17fTtcbkUucHJvdG90eXBlLnNldFN0YXRlPWZ1bmN0aW9uKGEsYil7aWYoXCJvYmplY3RcIiE9PXR5cGVvZiBhJiZcImZ1bmN0aW9uXCIhPT10eXBlb2YgYSYmbnVsbCE9YSl0aHJvdyBFcnJvcihcInNldFN0YXRlKC4uLik6IHRha2VzIGFuIG9iamVjdCBvZiBzdGF0ZSB2YXJpYWJsZXMgdG8gdXBkYXRlIG9yIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhbiBvYmplY3Qgb2Ygc3RhdGUgdmFyaWFibGVzLlwiKTt0aGlzLnVwZGF0ZXIuZW5xdWV1ZVNldFN0YXRlKHRoaXMsYSxiLFwic2V0U3RhdGVcIil9O0UucHJvdG90eXBlLmZvcmNlVXBkYXRlPWZ1bmN0aW9uKGEpe3RoaXMudXBkYXRlci5lbnF1ZXVlRm9yY2VVcGRhdGUodGhpcyxhLFwiZm9yY2VVcGRhdGVcIil9O2Z1bmN0aW9uIEYoKXt9Ri5wcm90b3R5cGU9RS5wcm90b3R5cGU7ZnVuY3Rpb24gRyhhLGIsZSl7dGhpcy5wcm9wcz1hO3RoaXMuY29udGV4dD1iO3RoaXMucmVmcz1EO3RoaXMudXBkYXRlcj1lfHxCfXZhciBIPUcucHJvdG90eXBlPW5ldyBGO1xuSC5jb25zdHJ1Y3Rvcj1HO0MoSCxFLnByb3RvdHlwZSk7SC5pc1B1cmVSZWFjdENvbXBvbmVudD0hMDt2YXIgST1BcnJheS5pc0FycmF5LEo9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxLPXtjdXJyZW50Om51bGx9LEw9e2tleTohMCxyZWY6ITAsX19zZWxmOiEwLF9fc291cmNlOiEwfTtcbmZ1bmN0aW9uIE0oYSxiLGUpe3ZhciBkLGM9e30saz1udWxsLGg9bnVsbDtpZihudWxsIT1iKWZvcihkIGluIHZvaWQgMCE9PWIucmVmJiYoaD1iLnJlZiksdm9pZCAwIT09Yi5rZXkmJihrPVwiXCIrYi5rZXkpLGIpSi5jYWxsKGIsZCkmJiFMLmhhc093blByb3BlcnR5KGQpJiYoY1tkXT1iW2RdKTt2YXIgZz1hcmd1bWVudHMubGVuZ3RoLTI7aWYoMT09PWcpYy5jaGlsZHJlbj1lO2Vsc2UgaWYoMTxnKXtmb3IodmFyIGY9QXJyYXkoZyksbT0wO208ZzttKyspZlttXT1hcmd1bWVudHNbbSsyXTtjLmNoaWxkcmVuPWZ9aWYoYSYmYS5kZWZhdWx0UHJvcHMpZm9yKGQgaW4gZz1hLmRlZmF1bHRQcm9wcyxnKXZvaWQgMD09PWNbZF0mJihjW2RdPWdbZF0pO3JldHVybnskJHR5cGVvZjpsLHR5cGU6YSxrZXk6ayxyZWY6aCxwcm9wczpjLF9vd25lcjpLLmN1cnJlbnR9fVxuZnVuY3Rpb24gTihhLGIpe3JldHVybnskJHR5cGVvZjpsLHR5cGU6YS50eXBlLGtleTpiLHJlZjphLnJlZixwcm9wczphLnByb3BzLF9vd25lcjphLl9vd25lcn19ZnVuY3Rpb24gTyhhKXtyZXR1cm5cIm9iamVjdFwiPT09dHlwZW9mIGEmJm51bGwhPT1hJiZhLiQkdHlwZW9mPT09bH1mdW5jdGlvbiBlc2NhcGUoYSl7dmFyIGI9e1wiPVwiOlwiPTBcIixcIjpcIjpcIj0yXCJ9O3JldHVyblwiJFwiK2EucmVwbGFjZSgvWz06XS9nLGZ1bmN0aW9uKGEpe3JldHVybiBiW2FdfSl9dmFyIFA9L1xcLysvZztmdW5jdGlvbiBRKGEsYil7cmV0dXJuXCJvYmplY3RcIj09PXR5cGVvZiBhJiZudWxsIT09YSYmbnVsbCE9YS5rZXk/ZXNjYXBlKFwiXCIrYS5rZXkpOmIudG9TdHJpbmcoMzYpfVxuZnVuY3Rpb24gUihhLGIsZSxkLGMpe3ZhciBrPXR5cGVvZiBhO2lmKFwidW5kZWZpbmVkXCI9PT1rfHxcImJvb2xlYW5cIj09PWspYT1udWxsO3ZhciBoPSExO2lmKG51bGw9PT1hKWg9ITA7ZWxzZSBzd2l0Y2goayl7Y2FzZSBcInN0cmluZ1wiOmNhc2UgXCJudW1iZXJcIjpoPSEwO2JyZWFrO2Nhc2UgXCJvYmplY3RcIjpzd2l0Y2goYS4kJHR5cGVvZil7Y2FzZSBsOmNhc2UgbjpoPSEwfX1pZihoKXJldHVybiBoPWEsYz1jKGgpLGE9XCJcIj09PWQ/XCIuXCIrUShoLDApOmQsSShjKT8oZT1cIlwiLG51bGwhPWEmJihlPWEucmVwbGFjZShQLFwiJCYvXCIpK1wiL1wiKSxSKGMsYixlLFwiXCIsZnVuY3Rpb24oYSl7cmV0dXJuIGF9KSk6bnVsbCE9YyYmKE8oYykmJihjPU4oYyxlKyghYy5rZXl8fGgmJmgua2V5PT09Yy5rZXk/XCJcIjooXCJcIitjLmtleSkucmVwbGFjZShQLFwiJCYvXCIpK1wiL1wiKSthKSksYi5wdXNoKGMpKSwxO2g9MDtkPVwiXCI9PT1kP1wiLlwiOmQrXCI6XCI7aWYoSShhKSlmb3IodmFyIGc9MDtnPGEubGVuZ3RoO2crKyl7az1cbmFbZ107dmFyIGY9ZCtRKGssZyk7aCs9UihrLGIsZSxmLGMpfWVsc2UgaWYoZj1BKGEpLFwiZnVuY3Rpb25cIj09PXR5cGVvZiBmKWZvcihhPWYuY2FsbChhKSxnPTA7IShrPWEubmV4dCgpKS5kb25lOylrPWsudmFsdWUsZj1kK1EoayxnKyspLGgrPVIoayxiLGUsZixjKTtlbHNlIGlmKFwib2JqZWN0XCI9PT1rKXRocm93IGI9U3RyaW5nKGEpLEVycm9yKFwiT2JqZWN0cyBhcmUgbm90IHZhbGlkIGFzIGEgUmVhY3QgY2hpbGQgKGZvdW5kOiBcIisoXCJbb2JqZWN0IE9iamVjdF1cIj09PWI/XCJvYmplY3Qgd2l0aCBrZXlzIHtcIitPYmplY3Qua2V5cyhhKS5qb2luKFwiLCBcIikrXCJ9XCI6YikrXCIpLiBJZiB5b3UgbWVhbnQgdG8gcmVuZGVyIGEgY29sbGVjdGlvbiBvZiBjaGlsZHJlbiwgdXNlIGFuIGFycmF5IGluc3RlYWQuXCIpO3JldHVybiBofVxuZnVuY3Rpb24gUyhhLGIsZSl7aWYobnVsbD09YSlyZXR1cm4gYTt2YXIgZD1bXSxjPTA7UihhLGQsXCJcIixcIlwiLGZ1bmN0aW9uKGEpe3JldHVybiBiLmNhbGwoZSxhLGMrKyl9KTtyZXR1cm4gZH1mdW5jdGlvbiBUKGEpe2lmKC0xPT09YS5fc3RhdHVzKXt2YXIgYj1hLl9yZXN1bHQ7Yj1iKCk7Yi50aGVuKGZ1bmN0aW9uKGIpe2lmKDA9PT1hLl9zdGF0dXN8fC0xPT09YS5fc3RhdHVzKWEuX3N0YXR1cz0xLGEuX3Jlc3VsdD1ifSxmdW5jdGlvbihiKXtpZigwPT09YS5fc3RhdHVzfHwtMT09PWEuX3N0YXR1cylhLl9zdGF0dXM9MixhLl9yZXN1bHQ9Yn0pOy0xPT09YS5fc3RhdHVzJiYoYS5fc3RhdHVzPTAsYS5fcmVzdWx0PWIpfWlmKDE9PT1hLl9zdGF0dXMpcmV0dXJuIGEuX3Jlc3VsdC5kZWZhdWx0O3Rocm93IGEuX3Jlc3VsdDt9XG52YXIgVT17Y3VycmVudDpudWxsfSxWPXt0cmFuc2l0aW9uOm51bGx9LFc9e1JlYWN0Q3VycmVudERpc3BhdGNoZXI6VSxSZWFjdEN1cnJlbnRCYXRjaENvbmZpZzpWLFJlYWN0Q3VycmVudE93bmVyOkt9O2V4cG9ydHMuQ2hpbGRyZW49e21hcDpTLGZvckVhY2g6ZnVuY3Rpb24oYSxiLGUpe1MoYSxmdW5jdGlvbigpe2IuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxlKX0sY291bnQ6ZnVuY3Rpb24oYSl7dmFyIGI9MDtTKGEsZnVuY3Rpb24oKXtiKyt9KTtyZXR1cm4gYn0sdG9BcnJheTpmdW5jdGlvbihhKXtyZXR1cm4gUyhhLGZ1bmN0aW9uKGEpe3JldHVybiBhfSl8fFtdfSxvbmx5OmZ1bmN0aW9uKGEpe2lmKCFPKGEpKXRocm93IEVycm9yKFwiUmVhY3QuQ2hpbGRyZW4ub25seSBleHBlY3RlZCB0byByZWNlaXZlIGEgc2luZ2xlIFJlYWN0IGVsZW1lbnQgY2hpbGQuXCIpO3JldHVybiBhfX07ZXhwb3J0cy5Db21wb25lbnQ9RTtleHBvcnRzLkZyYWdtZW50PXA7XG5leHBvcnRzLlByb2ZpbGVyPXI7ZXhwb3J0cy5QdXJlQ29tcG9uZW50PUc7ZXhwb3J0cy5TdHJpY3RNb2RlPXE7ZXhwb3J0cy5TdXNwZW5zZT13O2V4cG9ydHMuX19TRUNSRVRfSU5URVJOQUxTX0RPX05PVF9VU0VfT1JfWU9VX1dJTExfQkVfRklSRUQ9VztcbmV4cG9ydHMuY2xvbmVFbGVtZW50PWZ1bmN0aW9uKGEsYixlKXtpZihudWxsPT09YXx8dm9pZCAwPT09YSl0aHJvdyBFcnJvcihcIlJlYWN0LmNsb25lRWxlbWVudCguLi4pOiBUaGUgYXJndW1lbnQgbXVzdCBiZSBhIFJlYWN0IGVsZW1lbnQsIGJ1dCB5b3UgcGFzc2VkIFwiK2ErXCIuXCIpO3ZhciBkPUMoe30sYS5wcm9wcyksYz1hLmtleSxrPWEucmVmLGg9YS5fb3duZXI7aWYobnVsbCE9Yil7dm9pZCAwIT09Yi5yZWYmJihrPWIucmVmLGg9Sy5jdXJyZW50KTt2b2lkIDAhPT1iLmtleSYmKGM9XCJcIitiLmtleSk7aWYoYS50eXBlJiZhLnR5cGUuZGVmYXVsdFByb3BzKXZhciBnPWEudHlwZS5kZWZhdWx0UHJvcHM7Zm9yKGYgaW4gYilKLmNhbGwoYixmKSYmIUwuaGFzT3duUHJvcGVydHkoZikmJihkW2ZdPXZvaWQgMD09PWJbZl0mJnZvaWQgMCE9PWc/Z1tmXTpiW2ZdKX12YXIgZj1hcmd1bWVudHMubGVuZ3RoLTI7aWYoMT09PWYpZC5jaGlsZHJlbj1lO2Vsc2UgaWYoMTxmKXtnPUFycmF5KGYpO1xuZm9yKHZhciBtPTA7bTxmO20rKylnW21dPWFyZ3VtZW50c1ttKzJdO2QuY2hpbGRyZW49Z31yZXR1cm57JCR0eXBlb2Y6bCx0eXBlOmEudHlwZSxrZXk6YyxyZWY6ayxwcm9wczpkLF9vd25lcjpofX07ZXhwb3J0cy5jcmVhdGVDb250ZXh0PWZ1bmN0aW9uKGEpe2E9eyQkdHlwZW9mOnUsX2N1cnJlbnRWYWx1ZTphLF9jdXJyZW50VmFsdWUyOmEsX3RocmVhZENvdW50OjAsUHJvdmlkZXI6bnVsbCxDb25zdW1lcjpudWxsLF9kZWZhdWx0VmFsdWU6bnVsbCxfZ2xvYmFsTmFtZTpudWxsfTthLlByb3ZpZGVyPXskJHR5cGVvZjp0LF9jb250ZXh0OmF9O3JldHVybiBhLkNvbnN1bWVyPWF9O2V4cG9ydHMuY3JlYXRlRWxlbWVudD1NO2V4cG9ydHMuY3JlYXRlRmFjdG9yeT1mdW5jdGlvbihhKXt2YXIgYj1NLmJpbmQobnVsbCxhKTtiLnR5cGU9YTtyZXR1cm4gYn07ZXhwb3J0cy5jcmVhdGVSZWY9ZnVuY3Rpb24oKXtyZXR1cm57Y3VycmVudDpudWxsfX07XG5leHBvcnRzLmZvcndhcmRSZWY9ZnVuY3Rpb24oYSl7cmV0dXJueyQkdHlwZW9mOnYscmVuZGVyOmF9fTtleHBvcnRzLmlzVmFsaWRFbGVtZW50PU87ZXhwb3J0cy5sYXp5PWZ1bmN0aW9uKGEpe3JldHVybnskJHR5cGVvZjp5LF9wYXlsb2FkOntfc3RhdHVzOi0xLF9yZXN1bHQ6YX0sX2luaXQ6VH19O2V4cG9ydHMubWVtbz1mdW5jdGlvbihhLGIpe3JldHVybnskJHR5cGVvZjp4LHR5cGU6YSxjb21wYXJlOnZvaWQgMD09PWI/bnVsbDpifX07ZXhwb3J0cy5zdGFydFRyYW5zaXRpb249ZnVuY3Rpb24oYSl7dmFyIGI9Vi50cmFuc2l0aW9uO1YudHJhbnNpdGlvbj17fTt0cnl7YSgpfWZpbmFsbHl7Vi50cmFuc2l0aW9uPWJ9fTtleHBvcnRzLnVuc3RhYmxlX2FjdD1mdW5jdGlvbigpe3Rocm93IEVycm9yKFwiYWN0KC4uLikgaXMgbm90IHN1cHBvcnRlZCBpbiBwcm9kdWN0aW9uIGJ1aWxkcyBvZiBSZWFjdC5cIik7fTtcbmV4cG9ydHMudXNlQ2FsbGJhY2s9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVS5jdXJyZW50LnVzZUNhbGxiYWNrKGEsYil9O2V4cG9ydHMudXNlQ29udGV4dD1mdW5jdGlvbihhKXtyZXR1cm4gVS5jdXJyZW50LnVzZUNvbnRleHQoYSl9O2V4cG9ydHMudXNlRGVidWdWYWx1ZT1mdW5jdGlvbigpe307ZXhwb3J0cy51c2VEZWZlcnJlZFZhbHVlPWZ1bmN0aW9uKGEpe3JldHVybiBVLmN1cnJlbnQudXNlRGVmZXJyZWRWYWx1ZShhKX07ZXhwb3J0cy51c2VFZmZlY3Q9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVS5jdXJyZW50LnVzZUVmZmVjdChhLGIpfTtleHBvcnRzLnVzZUlkPWZ1bmN0aW9uKCl7cmV0dXJuIFUuY3VycmVudC51c2VJZCgpfTtleHBvcnRzLnVzZUltcGVyYXRpdmVIYW5kbGU9ZnVuY3Rpb24oYSxiLGUpe3JldHVybiBVLmN1cnJlbnQudXNlSW1wZXJhdGl2ZUhhbmRsZShhLGIsZSl9O1xuZXhwb3J0cy51c2VJbnNlcnRpb25FZmZlY3Q9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gVS5jdXJyZW50LnVzZUluc2VydGlvbkVmZmVjdChhLGIpfTtleHBvcnRzLnVzZUxheW91dEVmZmVjdD1mdW5jdGlvbihhLGIpe3JldHVybiBVLmN1cnJlbnQudXNlTGF5b3V0RWZmZWN0KGEsYil9O2V4cG9ydHMudXNlTWVtbz1mdW5jdGlvbihhLGIpe3JldHVybiBVLmN1cnJlbnQudXNlTWVtbyhhLGIpfTtleHBvcnRzLnVzZVJlZHVjZXI9ZnVuY3Rpb24oYSxiLGUpe3JldHVybiBVLmN1cnJlbnQudXNlUmVkdWNlcihhLGIsZSl9O2V4cG9ydHMudXNlUmVmPWZ1bmN0aW9uKGEpe3JldHVybiBVLmN1cnJlbnQudXNlUmVmKGEpfTtleHBvcnRzLnVzZVN0YXRlPWZ1bmN0aW9uKGEpe3JldHVybiBVLmN1cnJlbnQudXNlU3RhdGUoYSl9O2V4cG9ydHMudXNlU3luY0V4dGVybmFsU3RvcmU9ZnVuY3Rpb24oYSxiLGUpe3JldHVybiBVLmN1cnJlbnQudXNlU3luY0V4dGVybmFsU3RvcmUoYSxiLGUpfTtcbmV4cG9ydHMudXNlVHJhbnNpdGlvbj1mdW5jdGlvbigpe3JldHVybiBVLmN1cnJlbnQudXNlVHJhbnNpdGlvbigpfTtleHBvcnRzLnZlcnNpb249XCIxOC4yLjBcIjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///408\n')},294:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(408);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjk0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLElBQUksSUFBcUM7QUFDekMsRUFBRSx5Q0FBeUQ7QUFDM0QsRUFBRSxLQUFLLEVBRU4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvcmVhY3QvaW5kZXguanM/YWI1YiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Byb2R1Y3Rpb24nKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QucHJvZHVjdGlvbi5taW4uanMnKTtcbn0gZWxzZSB7XG4gIG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9janMvcmVhY3QuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///294\n")},53:(__unused_webpack_module,exports)=>{"use strict";eval('/**\n * @license React\n * scheduler.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nfunction f(a,b){var c=a.length;a.push(b);a:for(;0<c;){var d=c-1>>>1,e=a[d];if(0<g(e,b))a[d]=b,a[c]=e,c=d;else break a}}function h(a){return 0===a.length?null:a[0]}function k(a){if(0===a.length)return null;var b=a[0],c=a.pop();if(c!==b){a[0]=c;a:for(var d=0,e=a.length,w=e>>>1;d<w;){var m=2*(d+1)-1,C=a[m],n=m+1,x=a[n];if(0>g(C,c))n<e&&0>g(x,C)?(a[d]=x,a[n]=c,d=n):(a[d]=C,a[m]=c,d=m);else if(n<e&&0>g(x,c))a[d]=x,a[n]=c,d=n;else break a}}return b}\nfunction g(a,b){var c=a.sortIndex-b.sortIndex;return 0!==c?c:a.id-b.id}if("object"===typeof performance&&"function"===typeof performance.now){var l=performance;exports.unstable_now=function(){return l.now()}}else{var p=Date,q=p.now();exports.unstable_now=function(){return p.now()-q}}var r=[],t=[],u=1,v=null,y=3,z=!1,A=!1,B=!1,D="function"===typeof setTimeout?setTimeout:null,E="function"===typeof clearTimeout?clearTimeout:null,F="undefined"!==typeof setImmediate?setImmediate:null;\n"undefined"!==typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function G(a){for(var b=h(t);null!==b;){if(null===b.callback)k(t);else if(b.startTime<=a)k(t),b.sortIndex=b.expirationTime,f(r,b);else break;b=h(t)}}function H(a){B=!1;G(a);if(!A)if(null!==h(r))A=!0,I(J);else{var b=h(t);null!==b&&K(H,b.startTime-a)}}\nfunction J(a,b){A=!1;B&&(B=!1,E(L),L=-1);z=!0;var c=y;try{G(b);for(v=h(r);null!==v&&(!(v.expirationTime>b)||a&&!M());){var d=v.callback;if("function"===typeof d){v.callback=null;y=v.priorityLevel;var e=d(v.expirationTime<=b);b=exports.unstable_now();"function"===typeof e?v.callback=e:v===h(r)&&k(r);G(b)}else k(r);v=h(r)}if(null!==v)var w=!0;else{var m=h(t);null!==m&&K(H,m.startTime-b);w=!1}return w}finally{v=null,y=c,z=!1}}var N=!1,O=null,L=-1,P=5,Q=-1;\nfunction M(){return exports.unstable_now()-Q<P?!1:!0}function R(){if(null!==O){var a=exports.unstable_now();Q=a;var b=!0;try{b=O(!0,a)}finally{b?S():(N=!1,O=null)}}else N=!1}var S;if("function"===typeof F)S=function(){F(R)};else if("undefined"!==typeof MessageChannel){var T=new MessageChannel,U=T.port2;T.port1.onmessage=R;S=function(){U.postMessage(null)}}else S=function(){D(R,0)};function I(a){O=a;N||(N=!0,S())}function K(a,b){L=D(function(){a(exports.unstable_now())},b)}\nexports.unstable_IdlePriority=5;exports.unstable_ImmediatePriority=1;exports.unstable_LowPriority=4;exports.unstable_NormalPriority=3;exports.unstable_Profiling=null;exports.unstable_UserBlockingPriority=2;exports.unstable_cancelCallback=function(a){a.callback=null};exports.unstable_continueExecution=function(){A||z||(A=!0,I(J))};\nexports.unstable_forceFrameRate=function(a){0>a||125<a?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):P=0<a?Math.floor(1E3/a):5};exports.unstable_getCurrentPriorityLevel=function(){return y};exports.unstable_getFirstCallbackNode=function(){return h(r)};exports.unstable_next=function(a){switch(y){case 1:case 2:case 3:var b=3;break;default:b=y}var c=y;y=b;try{return a()}finally{y=c}};exports.unstable_pauseExecution=function(){};\nexports.unstable_requestPaint=function(){};exports.unstable_runWithPriority=function(a,b){switch(a){case 1:case 2:case 3:case 4:case 5:break;default:a=3}var c=y;y=a;try{return b()}finally{y=c}};\nexports.unstable_scheduleCallback=function(a,b,c){var d=exports.unstable_now();"object"===typeof c&&null!==c?(c=c.delay,c="number"===typeof c&&0<c?d+c:d):c=d;switch(a){case 1:var e=-1;break;case 2:e=250;break;case 5:e=1073741823;break;case 4:e=1E4;break;default:e=5E3}e=c+e;a={id:u++,callback:b,priorityLevel:a,startTime:c,expirationTime:e,sortIndex:-1};c>d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNTMuanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2EsZ0JBQWdCLGVBQWUsVUFBVSxPQUFPLElBQUksRUFBRSxxQkFBcUIsOEJBQThCLGNBQWMsY0FBYyw4QkFBOEIsY0FBYyw0QkFBNEIscUJBQXFCLFVBQVUsT0FBTyxpQ0FBaUMsSUFBSSxFQUFFLG9DQUFvQyxrRUFBa0Usd0NBQXdDLGNBQWM7QUFDbmMsZ0JBQWdCLDhCQUE4Qix5QkFBeUIsdUVBQXVFLGtCQUFrQixvQkFBb0IsWUFBWSxnQkFBZ0IsS0FBSyxxQkFBcUIsb0JBQW9CLFlBQVksa0JBQWtCO0FBQzVSLDRLQUE0SyxjQUFjLGVBQWUsU0FBUyxFQUFFLDBCQUEwQixnRUFBZ0UsV0FBVyxRQUFRLGNBQWMsS0FBSyxLQUFLLCtCQUErQixLQUFLLFdBQVc7QUFDeFksZ0JBQWdCLEtBQUssb0JBQW9CLEtBQUssUUFBUSxJQUFJLEtBQUssV0FBVywyQ0FBMkMsRUFBRSxpQkFBaUIsMEJBQTBCLGdCQUFnQixrQkFBa0IsNkJBQTZCLHlCQUF5QixrREFBa0QsS0FBSyxVQUFVLE9BQU8scUJBQXFCLEtBQUssV0FBVyw2QkFBNkIsS0FBSyxTQUFTLFFBQVEsaUJBQWlCO0FBQzNhLGFBQWEsd0NBQXdDLGFBQWEsYUFBYSw2QkFBNkIsSUFBSSxTQUFTLElBQUksVUFBVSxRQUFRLHFCQUFxQixVQUFVLE1BQU0sc0NBQXNDLE1BQU0sNkNBQTZDLG1DQUFtQyxvQkFBb0IsYUFBYSxxQkFBcUIsa0JBQWtCLFFBQVEsY0FBYyxJQUFJLGNBQWMsZ0JBQWdCLGVBQWUsMEJBQTBCO0FBQ3pkLDZCQUE2QixHQUFHLGtDQUFrQyxHQUFHLDRCQUE0QixHQUFHLCtCQUErQixHQUFHLDBCQUEwQixNQUFNLHFDQUFxQyxHQUFHLCtCQUErQixhQUFhLGlCQUFpQixrQ0FBa0MsWUFBWTtBQUN6VCwrQkFBK0IsYUFBYSx1S0FBdUssd0NBQXdDLFlBQVksVUFBVSxxQ0FBcUMsWUFBWSxhQUFhLHFCQUFxQixhQUFhLFVBQVUsNkJBQTZCLE1BQU0sWUFBWSxRQUFRLElBQUksSUFBSSxXQUFXLFFBQVEsTUFBTSwrQkFBK0I7QUFDbGYsNkJBQTZCLGNBQWMsZ0NBQWdDLGVBQWUsVUFBVSx5Q0FBeUMsWUFBWSxRQUFRLElBQUksSUFBSSxXQUFXLFFBQVE7QUFDNUwsaUNBQWlDLGlCQUFpQiw2QkFBNkIsK0VBQStFLFVBQVUsZ0JBQWdCLE1BQU0sYUFBYSxNQUFNLG9CQUFvQixNQUFNLGFBQWEsTUFBTSxjQUFjLE1BQU0sR0FBRyw2RUFBNkUseUhBQXlIO0FBQzNkLDRCQUE0QixHQUFHLDZCQUE2QixhQUFhLFFBQVEsa0JBQWtCLFFBQVEsSUFBSSxJQUFJLCtCQUErQixRQUFRIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3NjaGVkdWxlci9janMvc2NoZWR1bGVyLnByb2R1Y3Rpb24ubWluLmpzP2ZiMDciXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZSBSZWFjdFxuICogc2NoZWR1bGVyLnByb2R1Y3Rpb24ubWluLmpzXG4gKlxuICogQ29weXJpZ2h0IChjKSBGYWNlYm9vaywgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuXG4gKi9cbid1c2Ugc3RyaWN0JztmdW5jdGlvbiBmKGEsYil7dmFyIGM9YS5sZW5ndGg7YS5wdXNoKGIpO2E6Zm9yKDswPGM7KXt2YXIgZD1jLTE+Pj4xLGU9YVtkXTtpZigwPGcoZSxiKSlhW2RdPWIsYVtjXT1lLGM9ZDtlbHNlIGJyZWFrIGF9fWZ1bmN0aW9uIGgoYSl7cmV0dXJuIDA9PT1hLmxlbmd0aD9udWxsOmFbMF19ZnVuY3Rpb24gayhhKXtpZigwPT09YS5sZW5ndGgpcmV0dXJuIG51bGw7dmFyIGI9YVswXSxjPWEucG9wKCk7aWYoYyE9PWIpe2FbMF09YzthOmZvcih2YXIgZD0wLGU9YS5sZW5ndGgsdz1lPj4+MTtkPHc7KXt2YXIgbT0yKihkKzEpLTEsQz1hW21dLG49bSsxLHg9YVtuXTtpZigwPmcoQyxjKSluPGUmJjA+Zyh4LEMpPyhhW2RdPXgsYVtuXT1jLGQ9bik6KGFbZF09QyxhW21dPWMsZD1tKTtlbHNlIGlmKG48ZSYmMD5nKHgsYykpYVtkXT14LGFbbl09YyxkPW47ZWxzZSBicmVhayBhfX1yZXR1cm4gYn1cbmZ1bmN0aW9uIGcoYSxiKXt2YXIgYz1hLnNvcnRJbmRleC1iLnNvcnRJbmRleDtyZXR1cm4gMCE9PWM/YzphLmlkLWIuaWR9aWYoXCJvYmplY3RcIj09PXR5cGVvZiBwZXJmb3JtYW5jZSYmXCJmdW5jdGlvblwiPT09dHlwZW9mIHBlcmZvcm1hbmNlLm5vdyl7dmFyIGw9cGVyZm9ybWFuY2U7ZXhwb3J0cy51bnN0YWJsZV9ub3c9ZnVuY3Rpb24oKXtyZXR1cm4gbC5ub3coKX19ZWxzZXt2YXIgcD1EYXRlLHE9cC5ub3coKTtleHBvcnRzLnVuc3RhYmxlX25vdz1mdW5jdGlvbigpe3JldHVybiBwLm5vdygpLXF9fXZhciByPVtdLHQ9W10sdT0xLHY9bnVsbCx5PTMsej0hMSxBPSExLEI9ITEsRD1cImZ1bmN0aW9uXCI9PT10eXBlb2Ygc2V0VGltZW91dD9zZXRUaW1lb3V0Om51bGwsRT1cImZ1bmN0aW9uXCI9PT10eXBlb2YgY2xlYXJUaW1lb3V0P2NsZWFyVGltZW91dDpudWxsLEY9XCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBzZXRJbW1lZGlhdGU/c2V0SW1tZWRpYXRlOm51bGw7XG5cInVuZGVmaW5lZFwiIT09dHlwZW9mIG5hdmlnYXRvciYmdm9pZCAwIT09bmF2aWdhdG9yLnNjaGVkdWxpbmcmJnZvaWQgMCE9PW5hdmlnYXRvci5zY2hlZHVsaW5nLmlzSW5wdXRQZW5kaW5nJiZuYXZpZ2F0b3Iuc2NoZWR1bGluZy5pc0lucHV0UGVuZGluZy5iaW5kKG5hdmlnYXRvci5zY2hlZHVsaW5nKTtmdW5jdGlvbiBHKGEpe2Zvcih2YXIgYj1oKHQpO251bGwhPT1iOyl7aWYobnVsbD09PWIuY2FsbGJhY2spayh0KTtlbHNlIGlmKGIuc3RhcnRUaW1lPD1hKWsodCksYi5zb3J0SW5kZXg9Yi5leHBpcmF0aW9uVGltZSxmKHIsYik7ZWxzZSBicmVhaztiPWgodCl9fWZ1bmN0aW9uIEgoYSl7Qj0hMTtHKGEpO2lmKCFBKWlmKG51bGwhPT1oKHIpKUE9ITAsSShKKTtlbHNle3ZhciBiPWgodCk7bnVsbCE9PWImJksoSCxiLnN0YXJ0VGltZS1hKX19XG5mdW5jdGlvbiBKKGEsYil7QT0hMTtCJiYoQj0hMSxFKEwpLEw9LTEpO3o9ITA7dmFyIGM9eTt0cnl7RyhiKTtmb3Iodj1oKHIpO251bGwhPT12JiYoISh2LmV4cGlyYXRpb25UaW1lPmIpfHxhJiYhTSgpKTspe3ZhciBkPXYuY2FsbGJhY2s7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIGQpe3YuY2FsbGJhY2s9bnVsbDt5PXYucHJpb3JpdHlMZXZlbDt2YXIgZT1kKHYuZXhwaXJhdGlvblRpbWU8PWIpO2I9ZXhwb3J0cy51bnN0YWJsZV9ub3coKTtcImZ1bmN0aW9uXCI9PT10eXBlb2YgZT92LmNhbGxiYWNrPWU6dj09PWgocikmJmsocik7RyhiKX1lbHNlIGsocik7dj1oKHIpfWlmKG51bGwhPT12KXZhciB3PSEwO2Vsc2V7dmFyIG09aCh0KTtudWxsIT09bSYmSyhILG0uc3RhcnRUaW1lLWIpO3c9ITF9cmV0dXJuIHd9ZmluYWxseXt2PW51bGwseT1jLHo9ITF9fXZhciBOPSExLE89bnVsbCxMPS0xLFA9NSxRPS0xO1xuZnVuY3Rpb24gTSgpe3JldHVybiBleHBvcnRzLnVuc3RhYmxlX25vdygpLVE8UD8hMTohMH1mdW5jdGlvbiBSKCl7aWYobnVsbCE9PU8pe3ZhciBhPWV4cG9ydHMudW5zdGFibGVfbm93KCk7UT1hO3ZhciBiPSEwO3RyeXtiPU8oITAsYSl9ZmluYWxseXtiP1MoKTooTj0hMSxPPW51bGwpfX1lbHNlIE49ITF9dmFyIFM7aWYoXCJmdW5jdGlvblwiPT09dHlwZW9mIEYpUz1mdW5jdGlvbigpe0YoUil9O2Vsc2UgaWYoXCJ1bmRlZmluZWRcIiE9PXR5cGVvZiBNZXNzYWdlQ2hhbm5lbCl7dmFyIFQ9bmV3IE1lc3NhZ2VDaGFubmVsLFU9VC5wb3J0MjtULnBvcnQxLm9ubWVzc2FnZT1SO1M9ZnVuY3Rpb24oKXtVLnBvc3RNZXNzYWdlKG51bGwpfX1lbHNlIFM9ZnVuY3Rpb24oKXtEKFIsMCl9O2Z1bmN0aW9uIEkoYSl7Tz1hO058fChOPSEwLFMoKSl9ZnVuY3Rpb24gSyhhLGIpe0w9RChmdW5jdGlvbigpe2EoZXhwb3J0cy51bnN0YWJsZV9ub3coKSl9LGIpfVxuZXhwb3J0cy51bnN0YWJsZV9JZGxlUHJpb3JpdHk9NTtleHBvcnRzLnVuc3RhYmxlX0ltbWVkaWF0ZVByaW9yaXR5PTE7ZXhwb3J0cy51bnN0YWJsZV9Mb3dQcmlvcml0eT00O2V4cG9ydHMudW5zdGFibGVfTm9ybWFsUHJpb3JpdHk9MztleHBvcnRzLnVuc3RhYmxlX1Byb2ZpbGluZz1udWxsO2V4cG9ydHMudW5zdGFibGVfVXNlckJsb2NraW5nUHJpb3JpdHk9MjtleHBvcnRzLnVuc3RhYmxlX2NhbmNlbENhbGxiYWNrPWZ1bmN0aW9uKGEpe2EuY2FsbGJhY2s9bnVsbH07ZXhwb3J0cy51bnN0YWJsZV9jb250aW51ZUV4ZWN1dGlvbj1mdW5jdGlvbigpe0F8fHp8fChBPSEwLEkoSikpfTtcbmV4cG9ydHMudW5zdGFibGVfZm9yY2VGcmFtZVJhdGU9ZnVuY3Rpb24oYSl7MD5hfHwxMjU8YT9jb25zb2xlLmVycm9yKFwiZm9yY2VGcmFtZVJhdGUgdGFrZXMgYSBwb3NpdGl2ZSBpbnQgYmV0d2VlbiAwIGFuZCAxMjUsIGZvcmNpbmcgZnJhbWUgcmF0ZXMgaGlnaGVyIHRoYW4gMTI1IGZwcyBpcyBub3Qgc3VwcG9ydGVkXCIpOlA9MDxhP01hdGguZmxvb3IoMUUzL2EpOjV9O2V4cG9ydHMudW5zdGFibGVfZ2V0Q3VycmVudFByaW9yaXR5TGV2ZWw9ZnVuY3Rpb24oKXtyZXR1cm4geX07ZXhwb3J0cy51bnN0YWJsZV9nZXRGaXJzdENhbGxiYWNrTm9kZT1mdW5jdGlvbigpe3JldHVybiBoKHIpfTtleHBvcnRzLnVuc3RhYmxlX25leHQ9ZnVuY3Rpb24oYSl7c3dpdGNoKHkpe2Nhc2UgMTpjYXNlIDI6Y2FzZSAzOnZhciBiPTM7YnJlYWs7ZGVmYXVsdDpiPXl9dmFyIGM9eTt5PWI7dHJ5e3JldHVybiBhKCl9ZmluYWxseXt5PWN9fTtleHBvcnRzLnVuc3RhYmxlX3BhdXNlRXhlY3V0aW9uPWZ1bmN0aW9uKCl7fTtcbmV4cG9ydHMudW5zdGFibGVfcmVxdWVzdFBhaW50PWZ1bmN0aW9uKCl7fTtleHBvcnRzLnVuc3RhYmxlX3J1bldpdGhQcmlvcml0eT1mdW5jdGlvbihhLGIpe3N3aXRjaChhKXtjYXNlIDE6Y2FzZSAyOmNhc2UgMzpjYXNlIDQ6Y2FzZSA1OmJyZWFrO2RlZmF1bHQ6YT0zfXZhciBjPXk7eT1hO3RyeXtyZXR1cm4gYigpfWZpbmFsbHl7eT1jfX07XG5leHBvcnRzLnVuc3RhYmxlX3NjaGVkdWxlQ2FsbGJhY2s9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPWV4cG9ydHMudW5zdGFibGVfbm93KCk7XCJvYmplY3RcIj09PXR5cGVvZiBjJiZudWxsIT09Yz8oYz1jLmRlbGF5LGM9XCJudW1iZXJcIj09PXR5cGVvZiBjJiYwPGM/ZCtjOmQpOmM9ZDtzd2l0Y2goYSl7Y2FzZSAxOnZhciBlPS0xO2JyZWFrO2Nhc2UgMjplPTI1MDticmVhaztjYXNlIDU6ZT0xMDczNzQxODIzO2JyZWFrO2Nhc2UgNDplPTFFNDticmVhaztkZWZhdWx0OmU9NUUzfWU9YytlO2E9e2lkOnUrKyxjYWxsYmFjazpiLHByaW9yaXR5TGV2ZWw6YSxzdGFydFRpbWU6YyxleHBpcmF0aW9uVGltZTplLHNvcnRJbmRleDotMX07Yz5kPyhhLnNvcnRJbmRleD1jLGYodCxhKSxudWxsPT09aChyKSYmYT09PWgodCkmJihCPyhFKEwpLEw9LTEpOkI9ITAsSyhILGMtZCkpKTooYS5zb3J0SW5kZXg9ZSxmKHIsYSksQXx8enx8KEE9ITAsSShKKSkpO3JldHVybiBhfTtcbmV4cG9ydHMudW5zdGFibGVfc2hvdWxkWWllbGQ9TTtleHBvcnRzLnVuc3RhYmxlX3dyYXBDYWxsYmFjaz1mdW5jdGlvbihhKXt2YXIgYj15O3JldHVybiBmdW5jdGlvbigpe3ZhciBjPXk7eT1iO3RyeXtyZXR1cm4gYS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9ZmluYWxseXt5PWN9fX07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///53\n')},840:(module,__unused_webpack_exports,__webpack_require__)=>{"use strict";eval("\n\nif (true) {\n module.exports = __webpack_require__(53);\n} else {}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODQwLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLElBQUksSUFBcUM7QUFDekMsRUFBRSx3Q0FBNkQ7QUFDL0QsRUFBRSxLQUFLLEVBRU4iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc2NoZWR1bGVyL2luZGV4LmpzPzQwMjkiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5pZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICdwcm9kdWN0aW9uJykge1xuICBtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vY2pzL3NjaGVkdWxlci5wcm9kdWN0aW9uLm1pbi5qcycpO1xufSBlbHNlIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2Nqcy9zY2hlZHVsZXIuZGV2ZWxvcG1lbnQuanMnKTtcbn1cbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///840\n")},897:module=>{eval('function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}\nmodule.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODk3LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQSx5Q0FBeUMsU0FBUztBQUNsRDtBQUNBO0FBQ0Esb0NBQW9DLHlCQUF5QixTQUFTLHlCQUF5QiIsInNvdXJjZXMiOlsid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2FycmF5TGlrZVRvQXJyYXkuanM/NGViYyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfYXJyYXlMaWtlVG9BcnJheShhcnIsIGxlbikge1xuICBpZiAobGVuID09IG51bGwgfHwgbGVuID4gYXJyLmxlbmd0aCkgbGVuID0gYXJyLmxlbmd0aDtcbiAgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBuZXcgQXJyYXkobGVuKTsgaSA8IGxlbjsgaSsrKSBhcnIyW2ldID0gYXJyW2ldO1xuICByZXR1cm4gYXJyMjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2FycmF5TGlrZVRvQXJyYXksIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///897\n')},372:module=>{eval('function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\nmodule.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzcyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcnJheVdpdGhIb2xlcy5qcz83NjNmIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9hcnJheVdpdGhIb2xlcyhhcnIpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgcmV0dXJuIGFycjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2FycmF5V2l0aEhvbGVzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///372\n')},690:module=>{eval('function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError("Cannot call a class as a function");\n }\n}\nmodule.exports = _classCallCheck, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjkwLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2suanM/OTRkYyJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7XG4gIGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKTtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfY2xhc3NDYWxsQ2hlY2ssIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///690\n')},728:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var toPropertyKey = __webpack_require__(62);\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if ("value" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, toPropertyKey(descriptor.key), descriptor);\n }\n}\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, "prototype", {\n writable: false\n });\n return Constructor;\n}\nmodule.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzI4LmpzIiwibWFwcGluZ3MiOiJBQUFBLG9CQUFvQixtQkFBTyxDQUFDLEVBQW9CO0FBQ2hEO0FBQ0Esa0JBQWtCLGtCQUFrQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLCtCQUErQix5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcy5qcz83YjBmIl0sInNvdXJjZXNDb250ZW50IjpbInZhciB0b1Byb3BlcnR5S2V5ID0gcmVxdWlyZShcIi4vdG9Qcm9wZXJ0eUtleS5qc1wiKTtcbmZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHRvUHJvcGVydHlLZXkoZGVzY3JpcHRvci5rZXkpLCBkZXNjcmlwdG9yKTtcbiAgfVxufVxuZnVuY3Rpb24gX2NyZWF0ZUNsYXNzKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykge1xuICBpZiAocHJvdG9Qcm9wcykgX2RlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTtcbiAgaWYgKHN0YXRpY1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29uc3RydWN0b3IsIFwicHJvdG90eXBlXCIsIHtcbiAgICB3cml0YWJsZTogZmFsc2VcbiAgfSk7XG4gIHJldHVybiBDb25zdHJ1Y3Rvcjtcbn1cbm1vZHVsZS5leHBvcnRzID0gX2NyZWF0ZUNsYXNzLCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///728\n')},872:module=>{eval('function _iterableToArrayLimit(arr, i) {\n var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"];\n if (null != _i) {\n var _s,\n _e,\n _x,\n _r,\n _arr = [],\n _n = !0,\n _d = !1;\n try {\n if (_x = (_i = _i.call(arr)).next, 0 === i) {\n if (Object(_i) !== _i) return;\n _n = !1;\n } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0);\n } catch (err) {\n _d = !0, _e = err;\n } finally {\n try {\n if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return;\n } finally {\n if (_d) throw _e;\n }\n }\n return _arr;\n }\n}\nmodule.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODcyLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFlBQVksNkVBQTZFO0FBQ2pHLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qcz8wZGFlIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHtcbiAgdmFyIF9pID0gbnVsbCA9PSBhcnIgPyBudWxsIDogXCJ1bmRlZmluZWRcIiAhPSB0eXBlb2YgU3ltYm9sICYmIGFycltTeW1ib2wuaXRlcmF0b3JdIHx8IGFycltcIkBAaXRlcmF0b3JcIl07XG4gIGlmIChudWxsICE9IF9pKSB7XG4gICAgdmFyIF9zLFxuICAgICAgX2UsXG4gICAgICBfeCxcbiAgICAgIF9yLFxuICAgICAgX2FyciA9IFtdLFxuICAgICAgX24gPSAhMCxcbiAgICAgIF9kID0gITE7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChfeCA9IChfaSA9IF9pLmNhbGwoYXJyKSkubmV4dCwgMCA9PT0gaSkge1xuICAgICAgICBpZiAoT2JqZWN0KF9pKSAhPT0gX2kpIHJldHVybjtcbiAgICAgICAgX24gPSAhMTtcbiAgICAgIH0gZWxzZSBmb3IgKDsgIShfbiA9IChfcyA9IF94LmNhbGwoX2kpKS5kb25lKSAmJiAoX2Fyci5wdXNoKF9zLnZhbHVlKSwgX2Fyci5sZW5ndGggIT09IGkpOyBfbiA9ICEwKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIF9kID0gITAsIF9lID0gZXJyO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoIV9uICYmIG51bGwgIT0gX2lbXCJyZXR1cm5cIl0gJiYgKF9yID0gX2lbXCJyZXR1cm5cIl0oKSwgT2JqZWN0KF9yKSAhPT0gX3IpKSByZXR1cm47XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoX2QpIHRocm93IF9lO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gX2FycjtcbiAgfVxufVxubW9kdWxlLmV4cG9ydHMgPSBfaXRlcmFibGVUb0FycmF5TGltaXQsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///872\n')},218:module=>{eval('function _nonIterableRest() {\n throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");\n}\nmodule.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMjE4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9ub25JdGVyYWJsZVJlc3QuanM/N2RkZiJdLCJzb3VyY2VzQ29udGVudCI6WyJmdW5jdGlvbiBfbm9uSXRlcmFibGVSZXN0KCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIGRlc3RydWN0dXJlIG5vbi1pdGVyYWJsZSBpbnN0YW5jZS5cXG5JbiBvcmRlciB0byBiZSBpdGVyYWJsZSwgbm9uLWFycmF5IG9iamVjdHMgbXVzdCBoYXZlIGEgW1N5bWJvbC5pdGVyYXRvcl0oKSBtZXRob2QuXCIpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfbm9uSXRlcmFibGVSZXN0LCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///218\n')},424:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var arrayWithHoles = __webpack_require__(372);\nvar iterableToArrayLimit = __webpack_require__(872);\nvar unsupportedIterableToArray = __webpack_require__(116);\nvar nonIterableRest = __webpack_require__(218);\nfunction _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}\nmodule.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDI0LmpzIiwibWFwcGluZ3MiOiJBQUFBLHFCQUFxQixtQkFBTyxDQUFDLEdBQXFCO0FBQ2xELDJCQUEyQixtQkFBTyxDQUFDLEdBQTJCO0FBQzlELGlDQUFpQyxtQkFBTyxDQUFDLEdBQWlDO0FBQzFFLHNCQUFzQixtQkFBTyxDQUFDLEdBQXNCO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQyx5QkFBeUIsU0FBUyx5QkFBeUIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5LmpzPzMyODAiXSwic291cmNlc0NvbnRlbnQiOlsidmFyIGFycmF5V2l0aEhvbGVzID0gcmVxdWlyZShcIi4vYXJyYXlXaXRoSG9sZXMuanNcIik7XG52YXIgaXRlcmFibGVUb0FycmF5TGltaXQgPSByZXF1aXJlKFwiLi9pdGVyYWJsZVRvQXJyYXlMaW1pdC5qc1wiKTtcbnZhciB1bnN1cHBvcnRlZEl0ZXJhYmxlVG9BcnJheSA9IHJlcXVpcmUoXCIuL3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5LmpzXCIpO1xudmFyIG5vbkl0ZXJhYmxlUmVzdCA9IHJlcXVpcmUoXCIuL25vbkl0ZXJhYmxlUmVzdC5qc1wiKTtcbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IHVuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5KGFyciwgaSkgfHwgbm9uSXRlcmFibGVSZXN0KCk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF9zbGljZWRUb0FycmF5LCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///424\n')},36:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var _typeof = (__webpack_require__(698)["default"]);\nfunction _toPrimitive(input, hint) {\n if (_typeof(input) !== "object" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || "default");\n if (_typeof(res) !== "object") return res;\n throw new TypeError("@@toPrimitive must return a primitive value.");\n }\n return (hint === "string" ? String : Number)(input);\n}\nmodule.exports = _toPrimitive, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYuanMiLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxxQ0FBaUM7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9QcmltaXRpdmUuanM/MzgzMSJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgX3R5cGVvZiA9IHJlcXVpcmUoXCIuL3R5cGVvZi5qc1wiKVtcImRlZmF1bHRcIl07XG5mdW5jdGlvbiBfdG9QcmltaXRpdmUoaW5wdXQsIGhpbnQpIHtcbiAgaWYgKF90eXBlb2YoaW5wdXQpICE9PSBcIm9iamVjdFwiIHx8IGlucHV0ID09PSBudWxsKSByZXR1cm4gaW5wdXQ7XG4gIHZhciBwcmltID0gaW5wdXRbU3ltYm9sLnRvUHJpbWl0aXZlXTtcbiAgaWYgKHByaW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHZhciByZXMgPSBwcmltLmNhbGwoaW5wdXQsIGhpbnQgfHwgXCJkZWZhdWx0XCIpO1xuICAgIGlmIChfdHlwZW9mKHJlcykgIT09IFwib2JqZWN0XCIpIHJldHVybiByZXM7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkBAdG9QcmltaXRpdmUgbXVzdCByZXR1cm4gYSBwcmltaXRpdmUgdmFsdWUuXCIpO1xuICB9XG4gIHJldHVybiAoaGludCA9PT0gXCJzdHJpbmdcIiA/IFN0cmluZyA6IE51bWJlcikoaW5wdXQpO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfdG9QcmltaXRpdmUsIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///36\n')},62:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var _typeof = (__webpack_require__(698)["default"]);\nvar toPrimitive = __webpack_require__(36);\nfunction _toPropertyKey(arg) {\n var key = toPrimitive(arg, "string");\n return _typeof(key) === "symbol" ? key : String(key);\n}\nmodule.exports = _toPropertyKey, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjIuanMiLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxxQ0FBaUM7QUFDL0Msa0JBQWtCLG1CQUFPLENBQUMsRUFBa0I7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Qcm9wZXJ0eUtleS5qcz9jNGU0Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBfdHlwZW9mID0gcmVxdWlyZShcIi4vdHlwZW9mLmpzXCIpW1wiZGVmYXVsdFwiXTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoXCIuL3RvUHJpbWl0aXZlLmpzXCIpO1xuZnVuY3Rpb24gX3RvUHJvcGVydHlLZXkoYXJnKSB7XG4gIHZhciBrZXkgPSB0b1ByaW1pdGl2ZShhcmcsIFwic3RyaW5nXCIpO1xuICByZXR1cm4gX3R5cGVvZihrZXkpID09PSBcInN5bWJvbFwiID8ga2V5IDogU3RyaW5nKGtleSk7XG59XG5tb2R1bGUuZXhwb3J0cyA9IF90b1Byb3BlcnR5S2V5LCBtb2R1bGUuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZSwgbW9kdWxlLmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gbW9kdWxlLmV4cG9ydHM7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///62\n')},698:module=>{eval('function _typeof(obj) {\n "@babel/helpers - typeof";\n\n return (module.exports = _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;\n }, module.exports.__esModule = true, module.exports["default"] = module.exports), _typeof(obj);\n}\nmodule.exports = _typeof, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNjk4LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEdBQUcsRUFBRSx5QkFBeUIsU0FBUyx5QkFBeUI7QUFDaEU7QUFDQSwwQkFBMEIseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdHlwZW9mLmpzP2Q4Y2QiXSwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gX3R5cGVvZihvYmopIHtcbiAgXCJAYmFiZWwvaGVscGVycyAtIHR5cGVvZlwiO1xuXG4gIHJldHVybiAobW9kdWxlLmV4cG9ydHMgPSBfdHlwZW9mID0gXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgXCJzeW1ib2xcIiA9PSB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID8gZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqO1xuICB9IDogZnVuY3Rpb24gKG9iaikge1xuICAgIHJldHVybiBvYmogJiYgXCJmdW5jdGlvblwiID09IHR5cGVvZiBTeW1ib2wgJiYgb2JqLmNvbnN0cnVjdG9yID09PSBTeW1ib2wgJiYgb2JqICE9PSBTeW1ib2wucHJvdG90eXBlID8gXCJzeW1ib2xcIiA6IHR5cGVvZiBvYmo7XG4gIH0sIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0cyksIF90eXBlb2Yob2JqKTtcbn1cbm1vZHVsZS5leHBvcnRzID0gX3R5cGVvZiwgbW9kdWxlLmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWUsIG1vZHVsZS5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IG1vZHVsZS5leHBvcnRzOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///698\n')},116:(module,__unused_webpack_exports,__webpack_require__)=>{eval('var arrayLikeToArray = __webpack_require__(897);\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === "string") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === "Object" && o.constructor) n = o.constructor.name;\n if (n === "Map" || n === "Set") return Array.from(o);\n if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}\nmodule.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTE2LmpzIiwibWFwcGluZ3MiOiJBQUFBLHVCQUF1QixtQkFBTyxDQUFDLEdBQXVCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMseUJBQXlCLFNBQVMseUJBQXlCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkuanM/MjQ4NyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgYXJyYXlMaWtlVG9BcnJheSA9IHJlcXVpcmUoXCIuL2FycmF5TGlrZVRvQXJyYXkuanNcIik7XG5mdW5jdGlvbiBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkobywgbWluTGVuKSB7XG4gIGlmICghbykgcmV0dXJuO1xuICBpZiAodHlwZW9mIG8gPT09IFwic3RyaW5nXCIpIHJldHVybiBhcnJheUxpa2VUb0FycmF5KG8sIG1pbkxlbik7XG4gIHZhciBuID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG8pLnNsaWNlKDgsIC0xKTtcbiAgaWYgKG4gPT09IFwiT2JqZWN0XCIgJiYgby5jb25zdHJ1Y3RvcikgbiA9IG8uY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKG4gPT09IFwiTWFwXCIgfHwgbiA9PT0gXCJTZXRcIikgcmV0dXJuIEFycmF5LmZyb20obyk7XG4gIGlmIChuID09PSBcIkFyZ3VtZW50c1wiIHx8IC9eKD86VWl8SSludCg/Ojh8MTZ8MzIpKD86Q2xhbXBlZCk/QXJyYXkkLy50ZXN0KG4pKSByZXR1cm4gYXJyYXlMaWtlVG9BcnJheShvLCBtaW5MZW4pO1xufVxubW9kdWxlLmV4cG9ydHMgPSBfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXksIG1vZHVsZS5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlLCBtb2R1bGUuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBtb2R1bGUuZXhwb3J0czsiXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///116\n')}},__webpack_module_cache__={};function __webpack_require__(I){var g=__webpack_module_cache__[I];if(void 0!==g)return g.exports;var n=__webpack_module_cache__[I]={exports:{}};return __webpack_modules__[I].call(n.exports,n,n.exports,__webpack_require__),n.exports}__webpack_require__.n=I=>{var g=I&&I.__esModule?()=>I.default:()=>I;return __webpack_require__.d(g,{a:g}),g},__webpack_require__.d=(I,g)=>{for(var n in g)__webpack_require__.o(g,n)&&!__webpack_require__.o(I,n)&&Object.defineProperty(I,n,{enumerable:!0,get:g[n]})},__webpack_require__.o=(I,g)=>Object.prototype.hasOwnProperty.call(I,g);var __webpack_exports__=__webpack_require__(209)})(); \ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..d4ddd6c
--- /dev/null
+++ b/index.html
@@ -0,0 +1,26 @@
+<html>
+ <head>
+ <title>relabi</title>
+ <meta
+ name="viewport"
+ content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=no;"
+ />
+ <style>
+ html,
+ body {
+ overflow: hidden;
+ }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica,
+ Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
+ "Segoe UI Symbol";
+ color: white;
+ text-shadow: 0 0 1px #000;
+ transition: background-color 100ms;
+ user-select: none;
+ }
+ </style>
+ </head>
+ <body></body>
+ <script src="dist/main.js"></script>
+</html>
diff --git a/package.json b/package.json
index 57a18c8..ec2e90c 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "relabi",
"version": "1.0.0",
"description": "relabi generator",
- "main": "src/index.js",
+ "main": "./src/index.jsx",
"author": "jules <jules@asdf.us>",
"license": "UNLICENSED",
"private": true,
@@ -11,6 +11,16 @@
"build": "npx webpack build --mode production"
},
"dependencies": {
+ "@babel/core": "^7.21.8",
+ "@babel/preset-env": "^7.21.5",
+ "@babel/preset-react": "^7.18.6",
+ "babel-loader": "^9.1.2",
+ "babel-plugin-transform-class-properties": "^6.24.1",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
+ "html-webpack-plugin": "^5.5.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "tone": "^14.7.77",
"webpack": "^5.82.0",
"webpack-cli": "^5.1.0"
},
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index 702f428..0000000
--- a/src/index.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log("hello");
diff --git a/src/index.jsx b/src/index.jsx
new file mode 100644
index 0000000..e752c5a
--- /dev/null
+++ b/src/index.jsx
@@ -0,0 +1,16 @@
+import * as React from "react";
+import { createRoot } from "react-dom/client";
+import { requestAudioContext } from "./lib/util";
+import Relabi from "./relabi";
+
+document.body.style.backgroundColor = "#111";
+document.body.style.color = "#fff";
+
+requestAudioContext(() => {
+ document.body.innerHTML = '<div id="app"></div>';
+ const relabi = new Relabi();
+ relabi.start();
+
+ const root = createRoot(document.getElementById("app"));
+ root.render(<h1>Relabi generator</h1>);
+});
diff --git a/src/lib/kalimba.js b/src/lib/kalimba.js
new file mode 100644
index 0000000..a8e0c0e
--- /dev/null
+++ b/src/lib/kalimba.js
@@ -0,0 +1,49 @@
+import * as Tone from "tone";
+import { choice } from "./util";
+import output from "./output";
+
+const player_count = 4;
+let player_index = 0;
+
+const samples = [
+ { root: 226, fn: "samples/380737__cabled-mess__sansula-01-a-raw.mp3" },
+ { root: 267, fn: "samples/380736__cabled-mess__sansula-02-c-raw.mp3" },
+ { root: 340, fn: "samples/380735__cabled-mess__sansula-03-e-raw.mp3" },
+ { root: 452, fn: "samples/380733__cabled-mess__sansula-06-a-02-raw.mp3" },
+ // { root: 507, fn: 'samples/380734__cabled-mess__sansula-07-b-h-raw.wav', },
+ // { root: 535, fn: 'samples/380731__cabled-mess__sansula-08-c-raw.wav', },
+ // { root: 671, fn: 'samples/380732__cabled-mess__sansula-09-e-raw.wav', },
+];
+
+samples.forEach((sample) => {
+ sample.players = [];
+ sample.index = -1;
+ for (let i = 0; i < player_count; i++) {
+ let fn = sample.fn;
+ if (window.location.href.match(/asdf.us/)) {
+ fn = "//asdf.us/kalimba/" + fn;
+ }
+ let player = new Tone.Player({
+ url: fn,
+ retrigger: true,
+ playbackRate: 1,
+ });
+ player.connect(output);
+ sample.players.push(player);
+ }
+});
+
+function play(freq, time) {
+ const best = choice(samples);
+ best.index = (best.index + 1) % player_count;
+
+ const player = best.players[best.index];
+ player.playbackRate = freq / best.root;
+ player.start(time || 0);
+}
+
+function pause() {
+ // no-op
+}
+
+export default { play, pause };
diff --git a/src/lib/output.js b/src/lib/output.js
new file mode 100644
index 0000000..88bee5d
--- /dev/null
+++ b/src/lib/output.js
@@ -0,0 +1,8 @@
+import * as Tone from "tone";
+
+const compressor = new Tone.Compressor(-30, 3);
+const gain = new Tone.Gain(0.3);
+compressor.connect(gain);
+gain.toDestination();
+
+export default compressor;
diff --git a/src/lib/startAudioContext.js b/src/lib/startAudioContext.js
new file mode 100644
index 0000000..5a339a2
--- /dev/null
+++ b/src/lib/startAudioContext.js
@@ -0,0 +1,180 @@
+/**
+ * StartAudioContext.js
+ * @author Yotam Mann
+ * @license http://opensource.org/licenses/MIT MIT License
+ * @copyright 2016 Yotam Mann
+ */
+
+(function (root, factory) {
+ if (typeof define === "function" && define.amd) {
+ define([], factory);
+ } else if (typeof module === "object" && module.exports) {
+ module.exports = factory();
+ } else {
+ root.StartAudioContext = factory();
+ }
+})(this, function () {
+ /**
+ * The StartAudioContext object
+ */
+ var StartAudioContext = {
+ /**
+ * The audio context passed in by the user
+ * @type {AudioContext}
+ */
+ context: null,
+ /**
+ * The TapListeners bound to the elements
+ * @type {Array}
+ * @private
+ */
+ _tapListeners: [],
+ /**
+ * Callbacks to invoke when the audio context is started
+ * @type {Array}
+ * @private
+ */
+ _onStarted: [],
+ };
+
+ /**
+ * Set the context
+ * @param {AudioContext} ctx
+ * @returns {StartAudioContext}
+ */
+ StartAudioContext.setContext = function (ctx) {
+ StartAudioContext.context = ctx;
+ return StartAudioContext;
+ };
+
+ /**
+ * Add a tap listener to the audio context
+ * @param {Array|Element|String|jQuery} element
+ * @returns {StartAudioContext}
+ */
+ StartAudioContext.on = function (element) {
+ if (Array.isArray(element) || (NodeList && element instanceof NodeList)) {
+ for (var i = 0; i < element.length; i++) {
+ StartAudioContext.on(element[i]);
+ }
+ } else if (typeof element === "string") {
+ StartAudioContext.on(document.querySelectorAll(element));
+ } else if (element.jquery && typeof element.toArray === "function") {
+ StartAudioContext.on(element.toArray());
+ } else if (Element && element instanceof Element) {
+ //if it's an element, create a TapListener
+ var tap = new TapListener(element, onTap);
+ StartAudioContext._tapListeners.push(tap);
+ }
+ return StartAudioContext;
+ };
+
+ /**
+ * Bind a callback to when the audio context is started.
+ * @param {Function} cb
+ * @return {StartAudioContext}
+ */
+ StartAudioContext.onStarted = function (cb) {
+ //if it's already started, invoke the callback
+ if (StartAudioContext.isStarted()) {
+ cb();
+ } else {
+ StartAudioContext._onStarted.push(cb);
+ }
+ return StartAudioContext;
+ };
+
+ /**
+ * returns true if the context is started
+ * @return {Boolean}
+ */
+ StartAudioContext.isStarted = function () {
+ return (
+ StartAudioContext.context !== null &&
+ StartAudioContext.context.state === "running"
+ );
+ };
+
+ /**
+ * @class Listens for non-dragging tap ends on the given element
+ * @param {Element} element
+ * @internal
+ */
+ var TapListener = function (element) {
+ this._dragged = false;
+
+ this._element = element;
+
+ this._bindedMove = this._moved.bind(this);
+ this._bindedEnd = this._ended.bind(this);
+
+ element.addEventListener("touchmove", this._bindedMove);
+ element.addEventListener("touchend", this._bindedEnd);
+ element.addEventListener("mouseup", this._bindedEnd);
+ };
+
+ /**
+ * drag move event
+ */
+ TapListener.prototype._moved = function (e) {
+ this._dragged = true;
+ };
+
+ /**
+ * tap ended listener
+ */
+ TapListener.prototype._ended = function (e) {
+ if (!this._dragged) {
+ onTap();
+ }
+ this._dragged = false;
+ };
+
+ /**
+ * remove all the bound events
+ */
+ TapListener.prototype.dispose = function () {
+ this._element.removeEventListener("touchmove", this._bindedMove);
+ this._element.removeEventListener("touchend", this._bindedEnd);
+ this._element.removeEventListener("mouseup", this._bindedEnd);
+ this._bindedMove = null;
+ this._bindedEnd = null;
+ this._element = null;
+ };
+
+ /**
+ * Invoked the first time of the elements is tapped.
+ * Creates a silent oscillator when a non-dragging touchend
+ * event has been triggered.
+ */
+ function onTap() {
+ //start the audio context with a silent oscillator
+ if (StartAudioContext.context && !StartAudioContext.isStarted()) {
+ var osc = StartAudioContext.context.createOscillator();
+ var silent = StartAudioContext.context.createGain();
+ silent.gain.value = 0;
+ osc.connect(silent);
+ silent.connect(StartAudioContext.context.destination);
+ var now = StartAudioContext.context.currentTime;
+ osc.start(now);
+ osc.stop(now + 0.5);
+ }
+
+ //dispose all the tap listeners
+ if (StartAudioContext._tapListeners) {
+ for (var i = 0; i < StartAudioContext._tapListeners.length; i++) {
+ StartAudioContext._tapListeners[i].dispose();
+ }
+ StartAudioContext._tapListeners = null;
+ }
+ //the onstarted callbacks
+ if (StartAudioContext._onStarted) {
+ for (var j = 0; j < StartAudioContext._onStarted.length; j++) {
+ StartAudioContext._onStarted[j]();
+ }
+ StartAudioContext._onStarted = null;
+ }
+ }
+
+ return StartAudioContext;
+});
diff --git a/src/lib/util.js b/src/lib/util.js
new file mode 100644
index 0000000..750c5b7
--- /dev/null
+++ b/src/lib/util.js
@@ -0,0 +1,63 @@
+import * as Tone from "tone";
+import StartAudioContext from "./startAudioContext";
+
+const isIphone =
+ navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i);
+const isIpad = navigator.userAgent.match(/iPad/i);
+const isAndroid = navigator.userAgent.match(/Android/i);
+const isMobile = isIphone || isIpad || isAndroid;
+const isDesktop = !isMobile;
+
+document.body.classList.add(isMobile ? "mobile" : "desktop");
+
+export const browser = { isIphone, isIpad, isMobile, isDesktop };
+export const choice = (a) => a[Math.floor(Math.random() * a.length)];
+export const mod = (n, m) => n - m * Math.floor(n / m);
+export const random = () => Math.random();
+export const rand = (n) => Math.random() * n;
+export const randint = (n) => rand(n) | 0;
+export const randrange = (a, b) => a + rand(b - a);
+export const randsign = () => (random() >= 0.5 ? -1 : 1);
+export const randnullsign = () => {
+ var r = random();
+ return r < 0.333 ? -1 : r < 0.666 ? 0 : 1;
+};
+
+export function requestAudioContext(fn) {
+ const container = document.createElement("div");
+ const button = document.createElement("div");
+ button.innerHTML = "Tap to start - please unmute your phone";
+ Object.assign(container.style, {
+ display: "block",
+ position: "absolute",
+ width: "100%",
+ height: "100%",
+ zIndex: "10000",
+ top: "0px",
+ left: "0px",
+ backgroundColor: "rgba(0, 0, 0, 0.8)",
+ });
+ Object.assign(button.style, {
+ display: "block",
+ position: "absolute",
+ left: "50%",
+ top: "50%",
+ padding: "20px",
+ backgroundColor: "#7F33ED",
+ color: "white",
+ fontFamily: "monospace",
+ borderRadius: "3px",
+ transform: "translate3D(-50%,-50%,0)",
+ textAlign: "center",
+ lineHeight: "1.5",
+ width: "150px",
+ });
+ container.appendChild(button);
+ document.body.appendChild(container);
+ StartAudioContext.setContext(Tone.context);
+ StartAudioContext.on(button);
+ StartAudioContext.onStarted((_) => {
+ container.remove();
+ fn();
+ });
+}
diff --git a/src/relabi/index.js b/src/relabi/index.js
new file mode 100644
index 0000000..867bc0d
--- /dev/null
+++ b/src/relabi/index.js
@@ -0,0 +1,121 @@
+import * as Tone from "tone";
+import kalimba from "../lib/kalimba";
+import { randrange } from "../lib/util";
+
+const TWO_PI = 2 * Math.PI;
+
+/**
+ * Wave functions
+ */
+const WAVE_FUNCTIONS = {
+ sine: Math.cos,
+ triangle: (time) =>
+ (4 / TWO_PI) *
+ Math.abs(
+ ((((time - TWO_PI / 4) % TWO_PI) + TWO_PI) % TWO_PI) - TWO_PI / 2
+ ) -
+ 1,
+ square: (time) => (time % TWO_PI < Math.PI ? 1 : -1),
+ saw: (time) => ((time % TWO_PI) - Math.PI) / Math.PI,
+};
+
+class Relabi {
+ /**
+ * Initialize relabi generator
+ */
+ constructor() {
+ this.updateTime = 1.0;
+ this.steps = 100;
+ this.waves = [
+ { type: "sine", frequency: randrange(0.5, 2) },
+ { type: "sine", frequency: randrange(0.5, 2) },
+ { type: "sine", frequency: randrange(1, 10) },
+ { type: "sine", frequency: randrange(5, 10) },
+ ];
+ this.bounds = [-0.5, 0.5];
+ this.frequencies = [220, (220 * 3) / 2, 440, (440 * 3) / 2];
+ }
+
+ /**
+ * Start the generator
+ */
+ start() {
+ console.log("Start Relabi");
+ this.stop();
+ this.clock = new Tone.Clock((time) => this.step(time), this.updateTime);
+ this.clock.start();
+ }
+
+ /**
+ * Stop the generator and reset it
+ */
+ stop() {
+ if (this.clock) {
+ this.clock.stop();
+ this.clock.dispose();
+ }
+ }
+
+ /**
+ * Generate relabi events
+ */
+ step(time) {
+ const waveCount = this.waves.length;
+ const boundsCount = this.bounds.length;
+ let previousValue = this.previousValue;
+ let index;
+ let step;
+ let value;
+ let noteCount = 0;
+
+ // Generate several events per second
+ for (step = 0; step < this.steps; step += 1) {
+ // Time offset for this event
+ const offset = time + (step * this.updateTime) / this.steps;
+
+ // Initialize value
+ value = 0;
+
+ // Compute the wave functions for this event
+ for (index = 0; index < waveCount; index += 1) {
+ const wave = this.waves[index];
+ value += WAVE_FUNCTIONS[wave.type](offset * wave.frequency);
+ }
+
+ // Scale to [-1, 1]
+ value /= waveCount / Math.PI;
+
+ // Compute whether we crossed a boundary, and which direction
+ for (index = 0; index < boundsCount; index += 1) {
+ const bound = this.bounds[index];
+ if (value < bound && bound < previousValue) {
+ // Going down
+ this.trigger(offset, index * 2);
+ noteCount += 1;
+ } else if (value > bound && bound > previousValue) {
+ // Going up
+ this.trigger(offset, index * 2 + 1);
+ noteCount += 1;
+ }
+ }
+
+ // Update the previous value
+ previousValue = value;
+ }
+
+ // Store the latest value
+ this.previousValue = value;
+
+ console.log(`Tick ${Math.floor(time)}, played ${noteCount} notes`);
+ }
+
+ /**
+ * Trigger an event
+ */
+ trigger(time, index) {
+ // console.log("trigger index", index, time);
+ kalimba.play(this.frequencies[index], time);
+ }
+}
+
+export default Relabi;
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..77a732a
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,22 @@
+const path = require("path");
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+
+module.exports = {
+ mode: "production",
+ entry: "./src/index.jsx",
+ devtool: 'eval-source-map',
+ module: {
+ rules: [
+ {
+ test: /\.(js|jsx)$/,
+ exclude: /node_modules/,
+ loader: "babel-loader",
+ },
+ ],
+ },
+ performance: {
+ hints: false,
+ maxEntrypointSize: 512000,
+ maxAssetSize: 512000,
+ },
+};
diff --git a/yarn.lock b/yarn.lock
index 52f0347..87b2b03 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,12 +2,974 @@
# yarn lockfile v1
+"@ampproject/remapping@^2.2.0":
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630"
+ integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.0"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4":
+ version "7.21.4"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39"
+ integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==
+ dependencies:
+ "@babel/highlight" "^7.18.6"
+
+"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5":
+ version "7.21.7"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.7.tgz#61caffb60776e49a57ba61a88f02bedd8714f6bc"
+ integrity sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==
+
+"@babel/core@^7.21.8":
+ version "7.21.8"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.8.tgz#2a8c7f0f53d60100ba4c32470ba0281c92aa9aa4"
+ integrity sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==
+ dependencies:
+ "@ampproject/remapping" "^2.2.0"
+ "@babel/code-frame" "^7.21.4"
+ "@babel/generator" "^7.21.5"
+ "@babel/helper-compilation-targets" "^7.21.5"
+ "@babel/helper-module-transforms" "^7.21.5"
+ "@babel/helpers" "^7.21.5"
+ "@babel/parser" "^7.21.8"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.21.5"
+ "@babel/types" "^7.21.5"
+ convert-source-map "^1.7.0"
+ debug "^4.1.0"
+ gensync "^1.0.0-beta.2"
+ json5 "^2.2.2"
+ semver "^6.3.0"
+
+"@babel/generator@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.5.tgz#c0c0e5449504c7b7de8236d99338c3e2a340745f"
+ integrity sha512-SrKK/sRv8GesIW1bDagf9cCG38IOMYZusoe1dfg0D8aiUe3Amvoj1QtjTPAWcfrZFvIwlleLb0gxzQidL9w14w==
+ dependencies:
+ "@babel/types" "^7.21.5"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ "@jridgewell/trace-mapping" "^0.3.17"
+ jsesc "^2.5.1"
+
+"@babel/helper-annotate-as-pure@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
+ integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz#817f73b6c59726ab39f6ba18c234268a519e5abb"
+ integrity sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==
+ dependencies:
+ "@babel/types" "^7.21.5"
+
+"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz#631e6cc784c7b660417421349aac304c94115366"
+ integrity sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==
+ dependencies:
+ "@babel/compat-data" "^7.21.5"
+ "@babel/helper-validator-option" "^7.21.0"
+ browserslist "^4.21.3"
+ lru-cache "^5.1.1"
+ semver "^6.3.0"
+
+"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0":
+ version "7.21.8"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz#205b26330258625ef8869672ebca1e0dee5a0f02"
+ integrity sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-environment-visitor" "^7.21.5"
+ "@babel/helper-function-name" "^7.21.0"
+ "@babel/helper-member-expression-to-functions" "^7.21.5"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/helper-replace-supers" "^7.21.5"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ semver "^6.3.0"
+
+"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5":
+ version "7.21.8"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz#a7886f61c2e29e21fd4aaeaf1e473deba6b571dc"
+ integrity sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ regexpu-core "^5.3.1"
+ semver "^6.3.0"
+
+"@babel/helper-define-polyfill-provider@^0.3.3":
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a"
+ integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==
+ dependencies:
+ "@babel/helper-compilation-targets" "^7.17.7"
+ "@babel/helper-plugin-utils" "^7.16.7"
+ debug "^4.1.1"
+ lodash.debounce "^4.0.8"
+ resolve "^1.14.2"
+ semver "^6.1.2"
+
+"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz#c769afefd41d171836f7cb63e295bedf689d48ba"
+ integrity sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==
+
+"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4"
+ integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==
+ dependencies:
+ "@babel/template" "^7.20.7"
+ "@babel/types" "^7.21.0"
+
+"@babel/helper-hoist-variables@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
+ integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-member-expression-to-functions@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz#3b1a009af932e586af77c1030fba9ee0bde396c0"
+ integrity sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==
+ dependencies:
+ "@babel/types" "^7.21.5"
+
+"@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4":
+ version "7.21.4"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af"
+ integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==
+ dependencies:
+ "@babel/types" "^7.21.4"
+
+"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz#d937c82e9af68d31ab49039136a222b17ac0b420"
+ integrity sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.21.5"
+ "@babel/helper-module-imports" "^7.21.4"
+ "@babel/helper-simple-access" "^7.21.5"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.21.5"
+ "@babel/types" "^7.21.5"
+
+"@babel/helper-optimise-call-expression@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe"
+ integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.21.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz#345f2377d05a720a4e5ecfa39cbf4474a4daed56"
+ integrity sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==
+
+"@babel/helper-remap-async-to-generator@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
+ integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-wrap-function" "^7.18.9"
+ "@babel/types" "^7.18.9"
+
+"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7", "@babel/helper-replace-supers@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz#a6ad005ba1c7d9bc2973dfde05a1bba7065dde3c"
+ integrity sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.21.5"
+ "@babel/helper-member-expression-to-functions" "^7.21.5"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.21.5"
+ "@babel/types" "^7.21.5"
+
+"@babel/helper-simple-access@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz#d697a7971a5c39eac32c7e63c0921c06c8a249ee"
+ integrity sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==
+ dependencies:
+ "@babel/types" "^7.21.5"
+
+"@babel/helper-skip-transparent-expression-wrappers@^7.20.0":
+ version "7.20.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684"
+ integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==
+ dependencies:
+ "@babel/types" "^7.20.0"
+
+"@babel/helper-split-export-declaration@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
+ integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-string-parser@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz#2b3eea65443c6bdc31c22d037c65f6d323b6b2bd"
+ integrity sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==
+
+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
+ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+
+"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180"
+ integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==
+
+"@babel/helper-wrap-function@^7.18.9":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3"
+ integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==
+ dependencies:
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.20.5"
+ "@babel/types" "^7.20.5"
+
+"@babel/helpers@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.5.tgz#5bac66e084d7a4d2d9696bdf0175a93f7fb63c08"
+ integrity sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==
+ dependencies:
+ "@babel/template" "^7.20.7"
+ "@babel/traverse" "^7.21.5"
+ "@babel/types" "^7.21.5"
+
+"@babel/highlight@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
+ integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.18.6"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
+"@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8":
+ version "7.21.8"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8"
+ integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==
+
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
+ integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz#d9c85589258539a22a901033853101a6198d4ef1"
+ integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+ "@babel/plugin-proposal-optional-chaining" "^7.20.7"
+
+"@babel/plugin-proposal-async-generator-functions@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326"
+ integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-remap-async-to-generator" "^7.18.9"
+ "@babel/plugin-syntax-async-generators" "^7.8.4"
+
+"@babel/plugin-proposal-class-properties@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3"
+ integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-proposal-class-static-block@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz#77bdd66fb7b605f3a61302d224bdfacf5547977d"
+ integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.21.0"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-class-static-block" "^7.14.5"
+
+"@babel/plugin-proposal-dynamic-import@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94"
+ integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+
+"@babel/plugin-proposal-export-namespace-from@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203"
+ integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+ "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
+
+"@babel/plugin-proposal-json-strings@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b"
+ integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-json-strings" "^7.8.3"
+
+"@babel/plugin-proposal-logical-assignment-operators@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz#dfbcaa8f7b4d37b51e8bfb46d94a5aea2bb89d83"
+ integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
+
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1"
+ integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+
+"@babel/plugin-proposal-numeric-separator@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75"
+ integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-numeric-separator" "^7.10.4"
+
+"@babel/plugin-proposal-object-rest-spread@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a"
+ integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==
+ dependencies:
+ "@babel/compat-data" "^7.20.5"
+ "@babel/helper-compilation-targets" "^7.20.7"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+ "@babel/plugin-transform-parameters" "^7.20.7"
+
+"@babel/plugin-proposal-optional-catch-binding@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb"
+ integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+
+"@babel/plugin-proposal-optional-chaining@^7.20.7", "@babel/plugin-proposal-optional-chaining@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea"
+ integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+ "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+
+"@babel/plugin-proposal-private-methods@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea"
+ integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==
+ dependencies:
+ "@babel/helper-create-class-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-proposal-private-property-in-object@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz#19496bd9883dd83c23c7d7fc45dcd9ad02dfa1dc"
+ integrity sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-create-class-features-plugin" "^7.21.0"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
+
+"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e"
+ integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-syntax-async-generators@^7.8.4":
+ version "7.8.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
+ integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-class-properties@^7.12.13":
+ version "7.12.13"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
+ integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.12.13"
+
+"@babel/plugin-syntax-class-static-block@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406"
+ integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-syntax-dynamic-import@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
+ integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-export-namespace-from@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a"
+ integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.3"
+
+"@babel/plugin-syntax-import-assertions@^7.20.0":
+ version "7.20.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4"
+ integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.19.0"
+
+"@babel/plugin-syntax-import-meta@^7.10.4":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
+ integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-json-strings@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
+ integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-jsx@^7.21.4":
+ version "7.21.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2"
+ integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
+ integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9"
+ integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-numeric-separator@^7.10.4":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97"
+ integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-object-rest-spread@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
+ integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-optional-catch-binding@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1"
+ integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-optional-chaining@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a"
+ integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-private-property-in-object@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad"
+ integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-syntax-top-level-await@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c"
+ integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-transform-arrow-functions@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz#9bb42a53de447936a57ba256fbf537fc312b6929"
+ integrity sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.21.5"
+
+"@babel/plugin-transform-async-to-generator@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354"
+ integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==
+ dependencies:
+ "@babel/helper-module-imports" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-remap-async-to-generator" "^7.18.9"
+
+"@babel/plugin-transform-block-scoped-functions@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8"
+ integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-block-scoping@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02"
+ integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-classes@^7.21.0":
+ version "7.21.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665"
+ integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-compilation-targets" "^7.20.7"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.21.0"
+ "@babel/helper-optimise-call-expression" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-replace-supers" "^7.20.7"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ globals "^11.1.0"
+
+"@babel/plugin-transform-computed-properties@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz#3a2d8bb771cd2ef1cd736435f6552fe502e11b44"
+ integrity sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.21.5"
+ "@babel/template" "^7.20.7"
+
+"@babel/plugin-transform-destructuring@^7.21.3":
+ version "7.21.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401"
+ integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8"
+ integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-duplicate-keys@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e"
+ integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-exponentiation-operator@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd"
+ integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==
+ dependencies:
+ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-for-of@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz#e890032b535f5a2e237a18535f56a9fdaa7b83fc"
+ integrity sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.21.5"
+
+"@babel/plugin-transform-function-name@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0"
+ integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==
+ dependencies:
+ "@babel/helper-compilation-targets" "^7.18.9"
+ "@babel/helper-function-name" "^7.18.9"
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-literals@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc"
+ integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-member-expression-literals@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e"
+ integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-modules-amd@^7.20.11":
+ version "7.20.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz#3daccca8e4cc309f03c3a0c4b41dc4b26f55214a"
+ integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==
+ dependencies:
+ "@babel/helper-module-transforms" "^7.20.11"
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-modules-commonjs@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz#d69fb947eed51af91de82e4708f676864e5e47bc"
+ integrity sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==
+ dependencies:
+ "@babel/helper-module-transforms" "^7.21.5"
+ "@babel/helper-plugin-utils" "^7.21.5"
+ "@babel/helper-simple-access" "^7.21.5"
+
+"@babel/plugin-transform-modules-systemjs@^7.20.11":
+ version "7.20.11"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz#467ec6bba6b6a50634eea61c9c232654d8a4696e"
+ integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==
+ dependencies:
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-module-transforms" "^7.20.11"
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-validator-identifier" "^7.19.1"
+
+"@babel/plugin-transform-modules-umd@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9"
+ integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==
+ dependencies:
+ "@babel/helper-module-transforms" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-named-capturing-groups-regex@^7.20.5":
+ version "7.20.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8"
+ integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.20.5"
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-new-target@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8"
+ integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-object-super@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c"
+ integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/helper-replace-supers" "^7.18.6"
+
+"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3":
+ version "7.21.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db"
+ integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+
+"@babel/plugin-transform-property-literals@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3"
+ integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-react-display-name@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415"
+ integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-react-jsx-development@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5"
+ integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==
+ dependencies:
+ "@babel/plugin-transform-react-jsx" "^7.18.6"
+
+"@babel/plugin-transform-react-jsx@^7.18.6":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz#bd98f3b429688243e4fa131fe1cbb2ef31ce6f38"
+ integrity sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-module-imports" "^7.21.4"
+ "@babel/helper-plugin-utils" "^7.21.5"
+ "@babel/plugin-syntax-jsx" "^7.21.4"
+ "@babel/types" "^7.21.5"
+
+"@babel/plugin-transform-react-pure-annotations@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844"
+ integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-regenerator@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz#576c62f9923f94bcb1c855adc53561fd7913724e"
+ integrity sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.21.5"
+ regenerator-transform "^0.15.1"
+
+"@babel/plugin-transform-reserved-words@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a"
+ integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-shorthand-properties@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9"
+ integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-spread@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e"
+ integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.20.2"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0"
+
+"@babel/plugin-transform-sticky-regex@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc"
+ integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-template-literals@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e"
+ integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-typeof-symbol@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0"
+ integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.9"
+
+"@babel/plugin-transform-unicode-escapes@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz#1e55ed6195259b0e9061d81f5ef45a9b009fb7f2"
+ integrity sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.21.5"
+
+"@babel/plugin-transform-unicode-regex@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca"
+ integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+ "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/preset-env@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.5.tgz#db2089d99efd2297716f018aeead815ac3decffb"
+ integrity sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==
+ dependencies:
+ "@babel/compat-data" "^7.21.5"
+ "@babel/helper-compilation-targets" "^7.21.5"
+ "@babel/helper-plugin-utils" "^7.21.5"
+ "@babel/helper-validator-option" "^7.21.0"
+ "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6"
+ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.20.7"
+ "@babel/plugin-proposal-async-generator-functions" "^7.20.7"
+ "@babel/plugin-proposal-class-properties" "^7.18.6"
+ "@babel/plugin-proposal-class-static-block" "^7.21.0"
+ "@babel/plugin-proposal-dynamic-import" "^7.18.6"
+ "@babel/plugin-proposal-export-namespace-from" "^7.18.9"
+ "@babel/plugin-proposal-json-strings" "^7.18.6"
+ "@babel/plugin-proposal-logical-assignment-operators" "^7.20.7"
+ "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6"
+ "@babel/plugin-proposal-numeric-separator" "^7.18.6"
+ "@babel/plugin-proposal-object-rest-spread" "^7.20.7"
+ "@babel/plugin-proposal-optional-catch-binding" "^7.18.6"
+ "@babel/plugin-proposal-optional-chaining" "^7.21.0"
+ "@babel/plugin-proposal-private-methods" "^7.18.6"
+ "@babel/plugin-proposal-private-property-in-object" "^7.21.0"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.18.6"
+ "@babel/plugin-syntax-async-generators" "^7.8.4"
+ "@babel/plugin-syntax-class-properties" "^7.12.13"
+ "@babel/plugin-syntax-class-static-block" "^7.14.5"
+ "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+ "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
+ "@babel/plugin-syntax-import-assertions" "^7.20.0"
+ "@babel/plugin-syntax-import-meta" "^7.10.4"
+ "@babel/plugin-syntax-json-strings" "^7.8.3"
+ "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
+ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+ "@babel/plugin-syntax-numeric-separator" "^7.10.4"
+ "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+ "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+ "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+ "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
+ "@babel/plugin-syntax-top-level-await" "^7.14.5"
+ "@babel/plugin-transform-arrow-functions" "^7.21.5"
+ "@babel/plugin-transform-async-to-generator" "^7.20.7"
+ "@babel/plugin-transform-block-scoped-functions" "^7.18.6"
+ "@babel/plugin-transform-block-scoping" "^7.21.0"
+ "@babel/plugin-transform-classes" "^7.21.0"
+ "@babel/plugin-transform-computed-properties" "^7.21.5"
+ "@babel/plugin-transform-destructuring" "^7.21.3"
+ "@babel/plugin-transform-dotall-regex" "^7.18.6"
+ "@babel/plugin-transform-duplicate-keys" "^7.18.9"
+ "@babel/plugin-transform-exponentiation-operator" "^7.18.6"
+ "@babel/plugin-transform-for-of" "^7.21.5"
+ "@babel/plugin-transform-function-name" "^7.18.9"
+ "@babel/plugin-transform-literals" "^7.18.9"
+ "@babel/plugin-transform-member-expression-literals" "^7.18.6"
+ "@babel/plugin-transform-modules-amd" "^7.20.11"
+ "@babel/plugin-transform-modules-commonjs" "^7.21.5"
+ "@babel/plugin-transform-modules-systemjs" "^7.20.11"
+ "@babel/plugin-transform-modules-umd" "^7.18.6"
+ "@babel/plugin-transform-named-capturing-groups-regex" "^7.20.5"
+ "@babel/plugin-transform-new-target" "^7.18.6"
+ "@babel/plugin-transform-object-super" "^7.18.6"
+ "@babel/plugin-transform-parameters" "^7.21.3"
+ "@babel/plugin-transform-property-literals" "^7.18.6"
+ "@babel/plugin-transform-regenerator" "^7.21.5"
+ "@babel/plugin-transform-reserved-words" "^7.18.6"
+ "@babel/plugin-transform-shorthand-properties" "^7.18.6"
+ "@babel/plugin-transform-spread" "^7.20.7"
+ "@babel/plugin-transform-sticky-regex" "^7.18.6"
+ "@babel/plugin-transform-template-literals" "^7.18.9"
+ "@babel/plugin-transform-typeof-symbol" "^7.18.9"
+ "@babel/plugin-transform-unicode-escapes" "^7.21.5"
+ "@babel/plugin-transform-unicode-regex" "^7.18.6"
+ "@babel/preset-modules" "^0.1.5"
+ "@babel/types" "^7.21.5"
+ babel-plugin-polyfill-corejs2 "^0.3.3"
+ babel-plugin-polyfill-corejs3 "^0.6.0"
+ babel-plugin-polyfill-regenerator "^0.4.1"
+ core-js-compat "^3.25.1"
+ semver "^6.3.0"
+
+"@babel/preset-modules@^0.1.5":
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9"
+ integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
+ "@babel/plugin-transform-dotall-regex" "^7.4.4"
+ "@babel/types" "^7.4.4"
+ esutils "^2.0.2"
+
+"@babel/preset-react@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d"
+ integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.18.6"
+ "@babel/helper-validator-option" "^7.18.6"
+ "@babel/plugin-transform-react-display-name" "^7.18.6"
+ "@babel/plugin-transform-react-jsx" "^7.18.6"
+ "@babel/plugin-transform-react-jsx-development" "^7.18.6"
+ "@babel/plugin-transform-react-pure-annotations" "^7.18.6"
+
+"@babel/regjsgen@^0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310"
+ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==
+
+"@babel/runtime@^7.21.5", "@babel/runtime@^7.8.4":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
+ integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
+ dependencies:
+ regenerator-runtime "^0.13.11"
+
+"@babel/template@^7.18.10", "@babel/template@^7.20.7":
+ version "7.20.7"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
+ integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/parser" "^7.20.7"
+ "@babel/types" "^7.20.7"
+
+"@babel/traverse@^7.20.5", "@babel/traverse@^7.21.5":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.5.tgz#ad22361d352a5154b498299d523cf72998a4b133"
+ integrity sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==
+ dependencies:
+ "@babel/code-frame" "^7.21.4"
+ "@babel/generator" "^7.21.5"
+ "@babel/helper-environment-visitor" "^7.21.5"
+ "@babel/helper-function-name" "^7.21.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.21.5"
+ "@babel/types" "^7.21.5"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
+"@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.4", "@babel/types@^7.21.5", "@babel/types@^7.4.4":
+ version "7.21.5"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.5.tgz#18dfbd47c39d3904d5db3d3dc2cc80bedb60e5b6"
+ integrity sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==
+ dependencies:
+ "@babel/helper-string-parser" "^7.21.5"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ to-fast-properties "^2.0.0"
+
"@discoveryjs/json-ext@^0.5.0":
version "0.5.7"
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
-"@jridgewell/gen-mapping@^0.3.0":
+"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==
@@ -128,6 +1090,11 @@
"@types/qs" "*"
"@types/serve-static" "*"
+"@types/html-minifier-terser@^6.0.0":
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
+ integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==
+
"@types/http-proxy@^1.17.8":
version "1.17.11"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.11.tgz#0ca21949a5588d55ac2b659b69035c84bd5da293"
@@ -415,6 +1382,28 @@ ansi-html-community@^0.0.8:
resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41"
integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==
+ansi-regex@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+ integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+ integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==
+
+ansi-styles@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+ integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+ dependencies:
+ color-convert "^1.9.0"
+
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@@ -433,6 +1422,163 @@ array-flatten@^2.1.2:
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==
+automation-events@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/automation-events/-/automation-events-6.0.1.tgz#2c645461907d6e6de834a6c4f3345a7172de7cfb"
+ integrity sha512-AHpETuZtlDy9/lupkn7GZIpUxgAlx7AjVGU6uh04wrrMawNf9Zjr6Erl/QoHRhQvIGMdFrs+6B2ngkh50lNJ9w==
+ dependencies:
+ "@babel/runtime" "^7.21.5"
+ tslib "^2.5.0"
+
+babel-code-frame@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
+ integrity sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==
+ dependencies:
+ chalk "^1.1.3"
+ esutils "^2.0.2"
+ js-tokens "^3.0.2"
+
+babel-helper-function-name@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
+ integrity sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==
+ dependencies:
+ babel-helper-get-function-arity "^6.24.1"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+ babel-traverse "^6.24.1"
+ babel-types "^6.24.1"
+
+babel-helper-get-function-arity@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
+ integrity sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-loader@^9.1.2:
+ version "9.1.2"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.2.tgz#a16a080de52d08854ee14570469905a5fc00d39c"
+ integrity sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA==
+ dependencies:
+ find-cache-dir "^3.3.2"
+ schema-utils "^4.0.0"
+
+babel-messages@^6.23.0:
+ version "6.23.0"
+ resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
+ integrity sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==
+ dependencies:
+ babel-runtime "^6.22.0"
+
+babel-plugin-polyfill-corejs2@^0.3.3:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122"
+ integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==
+ dependencies:
+ "@babel/compat-data" "^7.17.7"
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+ semver "^6.1.1"
+
+babel-plugin-polyfill-corejs3@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a"
+ integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==
+ dependencies:
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+ core-js-compat "^3.25.1"
+
+babel-plugin-polyfill-regenerator@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747"
+ integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==
+ dependencies:
+ "@babel/helper-define-polyfill-provider" "^0.3.3"
+
+babel-plugin-syntax-class-properties@^6.8.0:
+ version "6.13.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
+ integrity sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==
+
+babel-plugin-transform-class-properties@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac"
+ integrity sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==
+ dependencies:
+ babel-helper-function-name "^6.24.1"
+ babel-plugin-syntax-class-properties "^6.8.0"
+ babel-runtime "^6.22.0"
+ babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-modules-commonjs@^6.26.2:
+ version "6.26.2"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3"
+ integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==
+ dependencies:
+ babel-plugin-transform-strict-mode "^6.24.1"
+ babel-runtime "^6.26.0"
+ babel-template "^6.26.0"
+ babel-types "^6.26.0"
+
+babel-plugin-transform-strict-mode@^6.24.1:
+ version "6.24.1"
+ resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
+ integrity sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==
+ dependencies:
+ babel-runtime "^6.22.0"
+ babel-types "^6.24.1"
+
+babel-runtime@^6.22.0, babel-runtime@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+ integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.11.0"
+
+babel-template@^6.24.1, babel-template@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02"
+ integrity sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==
+ dependencies:
+ babel-runtime "^6.26.0"
+ babel-traverse "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ lodash "^4.17.4"
+
+babel-traverse@^6.24.1, babel-traverse@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee"
+ integrity sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==
+ dependencies:
+ babel-code-frame "^6.26.0"
+ babel-messages "^6.23.0"
+ babel-runtime "^6.26.0"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+ debug "^2.6.8"
+ globals "^9.18.0"
+ invariant "^2.2.2"
+ lodash "^4.17.4"
+
+babel-types@^6.24.1, babel-types@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
+ integrity sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==
+ dependencies:
+ babel-runtime "^6.26.0"
+ esutils "^2.0.2"
+ lodash "^4.17.4"
+ to-fast-properties "^1.0.3"
+
+babylon@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
+ integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
+
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -476,6 +1622,11 @@ bonjour-service@^1.0.11:
fast-deep-equal "^3.1.3"
multicast-dns "^7.2.5"
+boolbase@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+ integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -491,7 +1642,7 @@ braces@^3.0.2, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
-browserslist@^4.14.5:
+browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.5:
version "4.21.5"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7"
integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==
@@ -524,11 +1675,39 @@ call-bind@^1.0.0:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
+camel-case@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
+ integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
+ dependencies:
+ pascal-case "^3.1.2"
+ tslib "^2.0.3"
+
caniuse-lite@^1.0.30001449:
version "1.0.30001486"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz#56a08885228edf62cbe1ac8980f2b5dae159997e"
integrity sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==
+chalk@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+ integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==
+ dependencies:
+ ansi-styles "^2.2.1"
+ escape-string-regexp "^1.0.2"
+ has-ansi "^2.0.0"
+ strip-ansi "^3.0.0"
+ supports-color "^2.0.0"
+
+chalk@^2.0.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+ dependencies:
+ ansi-styles "^3.2.1"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.3.0"
+
chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@@ -549,6 +1728,13 @@ chrome-trace-event@^1.0.2:
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
+clean-css@^5.2.2:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224"
+ integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==
+ dependencies:
+ source-map "~0.6.0"
+
clone-deep@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
@@ -558,6 +1744,18 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
+color-convert@^1.9.0:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+ integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+ dependencies:
+ color-name "1.1.3"
+
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+ integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+
colorette@^2.0.10, colorette@^2.0.14:
version "2.0.20"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
@@ -573,6 +1771,16 @@ commander@^2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+commander@^8.3.0:
+ version "8.3.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
+ integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
+
+commondir@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
+ integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
+
compressible@~2.0.16:
version "2.0.18"
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
@@ -615,6 +1823,11 @@ content-type@~1.0.4:
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
+convert-source-map@^1.7.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
+ integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
+
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@@ -625,6 +1838,18 @@ cookie@0.5.0:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
+core-js-compat@^3.25.1:
+ version "3.30.2"
+ resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.30.2.tgz#83f136e375babdb8c80ad3c22d67c69098c1dd8b"
+ integrity sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==
+ dependencies:
+ browserslist "^4.21.5"
+
+core-js@^2.4.0:
+ version "2.6.12"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
+ integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
+
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@@ -639,14 +1864,30 @@ cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
-debug@2.6.9:
+css-select@^4.1.3:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
+ integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
+ dependencies:
+ boolbase "^1.0.0"
+ css-what "^6.0.1"
+ domhandler "^4.3.1"
+ domutils "^2.8.0"
+ nth-check "^2.0.1"
+
+css-what@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
+ integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
+
+debug@2.6.9, debug@^2.6.8:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
-debug@^4.1.0:
+debug@^4.1.0, debug@^4.1.1:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -697,6 +1938,51 @@ dns-packet@^5.2.2:
dependencies:
"@leichtgewicht/ip-codec" "^2.0.1"
+dom-converter@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
+ integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==
+ dependencies:
+ utila "~0.4"
+
+dom-serializer@^1.0.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
+ integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.2.0"
+ entities "^2.0.0"
+
+domelementtype@^2.0.1, domelementtype@^2.2.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
+ integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
+
+domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
+ integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
+ dependencies:
+ domelementtype "^2.2.0"
+
+domutils@^2.5.2, domutils@^2.8.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
+ integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
+ dependencies:
+ dom-serializer "^1.0.1"
+ domelementtype "^2.2.0"
+ domhandler "^4.2.0"
+
+dot-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
+ integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
+ dependencies:
+ no-case "^3.0.4"
+ tslib "^2.0.3"
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -720,6 +2006,11 @@ enhanced-resolve@^5.13.0:
graceful-fs "^4.2.4"
tapable "^2.2.0"
+entities@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
+ integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
+
envinfo@^7.7.3:
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@@ -740,6 +2031,11 @@ escape-html@~1.0.3:
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+ integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
+
eslint-scope@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
@@ -765,6 +2061,11 @@ estraverse@^5.2.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+esutils@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
+ integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
@@ -874,6 +2175,15 @@ finalhandler@1.2.0:
statuses "2.0.1"
unpipe "~1.0.0"
+find-cache-dir@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b"
+ integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==
+ dependencies:
+ commondir "^1.0.1"
+ make-dir "^3.0.2"
+ pkg-dir "^4.1.0"
+
find-up@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
@@ -917,6 +2227,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+gensync@^1.0.0-beta.2:
+ version "1.0.0-beta.2"
+ resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
+ integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
+
get-intrinsic@^1.0.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f"
@@ -955,6 +2270,16 @@ glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
+globals@^11.1.0:
+ version "11.12.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
+ integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+
+globals@^9.18.0:
+ version "9.18.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
+ integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
+
graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
@@ -965,6 +2290,18 @@ handle-thing@^2.0.0:
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
+has-ansi@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+ integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==
+ dependencies:
+ ansi-regex "^2.0.0"
+
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+ integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
+
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
@@ -982,6 +2319,11 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+he@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
+ integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+
hpack.js@^2.1.6:
version "2.1.6"
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
@@ -997,6 +2339,40 @@ html-entities@^2.3.2:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46"
integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==
+html-minifier-terser@^6.0.2:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab"
+ integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==
+ dependencies:
+ camel-case "^4.1.2"
+ clean-css "^5.2.2"
+ commander "^8.3.0"
+ he "^1.2.0"
+ param-case "^3.0.4"
+ relateurl "^0.2.7"
+ terser "^5.10.0"
+
+html-webpack-plugin@^5.5.1:
+ version "5.5.1"
+ resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz#826838e31b427f5f7f30971f8d8fa2422dfa6763"
+ integrity sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==
+ dependencies:
+ "@types/html-minifier-terser" "^6.0.0"
+ html-minifier-terser "^6.0.2"
+ lodash "^4.17.21"
+ pretty-error "^4.0.0"
+ tapable "^2.0.0"
+
+htmlparser2@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
+ integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^4.0.0"
+ domutils "^2.5.2"
+ entities "^2.0.0"
+
http-deceiver@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@@ -1091,6 +2467,13 @@ interpret@^3.1.1:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
+invariant@^2.2.2:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
+ integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
+ dependencies:
+ loose-envify "^1.0.0"
+
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
@@ -1185,6 +2568,26 @@ jest-worker@^27.4.5:
merge-stream "^2.0.0"
supports-color "^8.0.0"
+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+js-tokens@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
+ integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==
+
+jsesc@^2.5.1:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
+ integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+
+jsesc@~0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
+ integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==
+
json-parse-even-better-errors@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
@@ -1200,6 +2603,11 @@ json-schema-traverse@^1.0.0:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+json5@^2.2.2:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
+ integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+
kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
@@ -1225,6 +2633,44 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
+lodash.debounce@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
+ integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
+
+lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+
+loose-envify@^1.0.0, loose-envify@^1.1.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
+lower-case@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
+ integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
+ dependencies:
+ tslib "^2.0.3"
+
+lru-cache@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
+ integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
+ dependencies:
+ yallist "^3.0.2"
+
+make-dir@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
+ integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
+ dependencies:
+ semver "^6.0.0"
+
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
@@ -1327,6 +2773,14 @@ neo-async@^2.6.2:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+no-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
+ integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
+ dependencies:
+ lower-case "^2.0.2"
+ tslib "^2.0.3"
+
node-forge@^1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
@@ -1349,6 +2803,13 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
+nth-check@^2.0.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
+ integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
+ dependencies:
+ boolbase "^1.0.0"
+
object-inspect@^1.9.0:
version "1.12.3"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
@@ -1421,11 +2882,27 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+param-case@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
+ integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
+ dependencies:
+ dot-case "^3.0.4"
+ tslib "^2.0.3"
+
parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
+pascal-case@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb"
+ integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==
+ dependencies:
+ no-case "^3.0.4"
+ tslib "^2.0.3"
+
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
@@ -1461,13 +2938,21 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-pkg-dir@^4.2.0:
+pkg-dir@^4.1.0, pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==
dependencies:
find-up "^4.0.0"
+pretty-error@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6"
+ integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==
+ dependencies:
+ lodash "^4.17.20"
+ renderkid "^3.0.0"
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -1515,6 +3000,21 @@ raw-body@2.5.1:
iconv-lite "0.4.24"
unpipe "1.0.0"
+react-dom@^18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
+ integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
+ dependencies:
+ loose-envify "^1.1.0"
+ scheduler "^0.23.0"
+
+react@^18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
+ integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
+ dependencies:
+ loose-envify "^1.1.0"
+
readable-stream@^2.0.1:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
@@ -1551,6 +3051,70 @@ rechoir@^0.8.0:
dependencies:
resolve "^1.20.0"
+regenerate-unicode-properties@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
+ integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==
+ dependencies:
+ regenerate "^1.4.2"
+
+regenerate@^1.4.2:
+ version "1.4.2"
+ resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
+ integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
+
+regenerator-runtime@^0.11.0:
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+ integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
+
+regenerator-runtime@^0.13.11:
+ version "0.13.11"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
+ integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
+
+regenerator-transform@^0.15.1:
+ version "0.15.1"
+ resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56"
+ integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==
+ dependencies:
+ "@babel/runtime" "^7.8.4"
+
+regexpu-core@^5.3.1:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b"
+ integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==
+ dependencies:
+ "@babel/regjsgen" "^0.8.0"
+ regenerate "^1.4.2"
+ regenerate-unicode-properties "^10.1.0"
+ regjsparser "^0.9.1"
+ unicode-match-property-ecmascript "^2.0.0"
+ unicode-match-property-value-ecmascript "^2.1.0"
+
+regjsparser@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709"
+ integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==
+ dependencies:
+ jsesc "~0.5.0"
+
+relateurl@^0.2.7:
+ version "0.2.7"
+ resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
+ integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==
+
+renderkid@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a"
+ integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==
+ dependencies:
+ css-select "^4.1.3"
+ dom-converter "^0.2.0"
+ htmlparser2 "^6.1.0"
+ lodash "^4.17.21"
+ strip-ansi "^6.0.1"
+
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
@@ -1573,7 +3137,7 @@ resolve-from@^5.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
-resolve@^1.20.0:
+resolve@^1.14.2, resolve@^1.20.0:
version "1.22.2"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f"
integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==
@@ -1609,6 +3173,13 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+scheduler@^0.23.0:
+ version "0.23.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
+ integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
+ dependencies:
+ loose-envify "^1.1.0"
+
schema-utils@^3.1.1, schema-utils@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.2.tgz#36c10abca6f7577aeae136c804b0c741edeadc99"
@@ -1640,6 +3211,11 @@ selfsigned@^2.1.1:
dependencies:
node-forge "^1"
+semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
send@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
@@ -1754,7 +3330,7 @@ source-map-support@~0.5.20:
buffer-from "^1.0.0"
source-map "^0.6.0"
-source-map@^0.6.0:
+source-map@^0.6.0, source-map@~0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@@ -1782,6 +3358,15 @@ spdy@^4.0.2:
select-hose "^2.0.0"
spdy-transport "^3.0.0"
+standardized-audio-context@^25.1.8:
+ version "25.3.46"
+ resolved "https://registry.yarnpkg.com/standardized-audio-context/-/standardized-audio-context-25.3.46.tgz#08e55d5305c2d3f614f90f19ad47c6686457ae68"
+ integrity sha512-kI7oM1IrGUawaBgCizRnVuS/+xSwRzwEDSqDkvJASAh+0IwuxUBYJFG4JSuaD6OkLQVg5i8oCf5aLOBX4dfVPw==
+ dependencies:
+ "@babel/runtime" "^7.21.5"
+ automation-events "^6.0.1"
+ tslib "^2.5.0"
+
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
@@ -1806,11 +3391,37 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
+strip-ansi@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+ integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
+ dependencies:
+ ansi-regex "^2.0.0"
+
+strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
strip-final-newline@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+supports-color@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+ integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==
+
+supports-color@^5.3.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+ dependencies:
+ has-flag "^3.0.0"
+
supports-color@^8.0.0:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
@@ -1823,7 +3434,7 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
-tapable@^2.1.1, tapable@^2.2.0:
+tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
@@ -1839,7 +3450,7 @@ terser-webpack-plugin@^5.3.7:
serialize-javascript "^6.0.1"
terser "^5.16.8"
-terser@^5.16.8:
+terser@^5.10.0, terser@^5.16.8:
version "5.17.2"
resolved "https://registry.yarnpkg.com/terser/-/terser-5.17.2.tgz#06c9818ae998066234b985abeb57bb7bff29d449"
integrity sha512-1D1aGbOF1Mnayq5PvfMc0amAR1y5Z1nrZaGCvI5xsdEfZEVte8okonk02OiaK5fw5hG1GWuuVsakOnpZW8y25A==
@@ -1854,6 +3465,16 @@ thunky@^1.0.2:
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
+to-fast-properties@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
+ integrity sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==
+
+to-fast-properties@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
+ integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
+
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
@@ -1866,6 +3487,19 @@ toidentifier@1.0.1:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
+tone@^14.7.77:
+ version "14.7.77"
+ resolved "https://registry.yarnpkg.com/tone/-/tone-14.7.77.tgz#12a2a9f033952ccdb552275a6384ca5d36d4b5ed"
+ integrity sha512-tCfK73IkLHyzoKUvGq47gyDyxiKLFvKiVCOobynGgBB9Dl0NkxTM2p+eRJXyCYrjJwy9Y0XCMqD3uOYsYt2Fdg==
+ dependencies:
+ standardized-audio-context "^25.1.8"
+ tslib "^2.0.1"
+
+tslib@^2.0.1, tslib@^2.0.3, tslib@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
+ integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
+
type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
@@ -1874,6 +3508,29 @@ type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
+unicode-canonical-property-names-ecmascript@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
+ integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==
+
+unicode-match-property-ecmascript@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3"
+ integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==
+ dependencies:
+ unicode-canonical-property-names-ecmascript "^2.0.0"
+ unicode-property-aliases-ecmascript "^2.0.0"
+
+unicode-match-property-value-ecmascript@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0"
+ integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==
+
+unicode-property-aliases-ecmascript@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"
+ integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==
+
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
@@ -1899,6 +3556,11 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+utila@~0.4:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
+ integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==
+
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
@@ -2073,3 +3735,8 @@ ws@^8.13.0:
version "8.13.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
+
+yallist@^3.0.2:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
+ integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==