diff options
Diffstat (limited to 'dist')
| -rw-r--r-- | dist/main.js | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/dist/main.js b/dist/main.js index 93ab7d6..d724eab 100644 --- a/dist/main.js +++ b/dist/main.js @@ -1 +1 @@ -(()=>{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")},441:(__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 util_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/relabi/canvas.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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\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 * Relabi waveform display\n * @module src/relabi/canvas.js;\n */\nvar RelabiCanvas = /*#__PURE__*/function () {\n /**\n * Initialize relabi wave renderer\n */\n function RelabiCanvas(_ref) {\n var relabi = _ref.relabi,\n parent = _ref.parent;\n _classCallCheck(this, RelabiCanvas);\n this.relabi = relabi;\n this.height = 400;\n this.lastFrame = 0;\n this.lastAppendTime = 0;\n this.lastAppendFrame = 0;\n\n // Speed of the wave in pixels per second\n this.speed = 1 / 5;\n\n // Attach to the DOM\n this.parent = parent = document.body;\n this.canvas = document.createElement("canvas");\n this.ctx = this.canvas.getContext("2d");\n this.parent.appendChild(this.canvas);\n\n // Initialize array\n this.values = new Array(window.innerWidth).fill(0);\n this.append([]);\n\n // Clear the canvas\n this.resize();\n\n // Start drawing\n this.requestAnimationFrame(0);\n }\n\n /**\n * Draw the next frame\n */\n _createClass(RelabiCanvas, [{\n key: "requestAnimationFrame",\n value: function (_requestAnimationFrame) {\n function requestAnimationFrame(_x) {\n return _requestAnimationFrame.apply(this, arguments);\n }\n requestAnimationFrame.toString = function () {\n return _requestAnimationFrame.toString();\n };\n return requestAnimationFrame;\n }(function (frame) {\n var _this = this;\n requestAnimationFrame(function (frame) {\n _this.requestAnimationFrame(frame);\n });\n this.paint(frame);\n this.lastFrame = frame;\n }\n\n /**\n * Handle window resize\n */)\n }, {\n key: "resize",\n value: function resize() {\n this.canvas.width = window.innerWidth;\n this.canvas.height = this.height;\n }\n\n /**\n * Clear the canvas\n */\n }, {\n key: "clear",\n value: function clear() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n /**\n * Append values\n */\n }, {\n key: "append",\n value: function append(time, values) {\n this.lastAppendTime = time;\n this.lastAppendFrame = this.lastFrame;\n this.values = this.values.concat(values).slice(-this.canvas.width);\n }\n\n /**\n * Paint the canvas\n */\n }, {\n key: "paint",\n value: function paint(frame) {\n this.clear();\n this.drawRelabiWave(frame);\n this.drawBounds();\n }\n\n /**\n * Draw the bounds\n */\n }, {\n key: "drawBounds",\n value: function drawBounds() {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n\n // Draw dashed lines for all bounds\n var _iterator = _createForOfIteratorHelper(this.relabi.bounds),\n _step;\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var bound = _step.value;\n var y = getWaveHeight(bound.level, height);\n ctx.beginPath();\n ctx.setLineDash([10, 5]);\n ctx.strokeStyle = bound.color || "#888";\n ctx.moveTo(0, y);\n ctx.lineTo(width, y);\n ctx.stroke();\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n }\n\n /**\n * Draw the relabi wave\n */\n }, {\n key: "drawRelabiWave",\n value: function drawRelabiWave(frame) {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n var pointCount = this.values.length;\n var index = 0;\n\n // Start the path\n ctx.beginPath();\n ctx.strokeStyle = "white";\n ctx.setLineDash([]);\n\n // This is the offset in seconds from the last frame we computed\n var frameOffset = (frame - this.lastAppendFrame) / 1000;\n\n // Make a path connecting all values\n var _iterator2 = _createForOfIteratorHelper(this.values),\n _step2;\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var point = _step2.value;\n if (!point) {\n index += 1;\n continue;\n }\n var _point = _slicedToArray(point, 2),\n time = _point[0],\n value = _point[1];\n\n // This is the offset of this time from current time\n // If this is in the future, it will be positive.\n // Subtracting the frame offset pulls it negative.\n var timeOffset = this.lastAppendTime + frameOffset - time;\n var x = width - timeOffset * this.speed * width - 10;\n if (x < 0) {\n continue;\n }\n var y = getWaveHeight(value, height);\n if (index === 0) {\n ctx.moveTo(x, y);\n }\n ctx.lineTo(x, y);\n index += 1;\n }\n\n // Paint the line\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n ctx.stroke();\n }\n }]);\n return RelabiCanvas;\n}();\n/**\n * Get the height of the wave at a given value\n */\n\nvar getWaveHeight = function getWaveHeight(value, height) {\n return (value + 1) / 2 * height;\n};\n;// CONCATENATED MODULE: ./src/relabi/index.js\nfunction relabi_typeof(obj) { "@babel/helpers - typeof"; return relabi_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; }, relabi_typeof(obj); }\nfunction relabi_slicedToArray(arr, i) { return relabi_arrayWithHoles(arr) || relabi_iterableToArrayLimit(arr, i) || relabi_unsupportedIterableToArray(arr, i) || relabi_nonIterableRest(); }\nfunction relabi_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction relabi_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return relabi_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return relabi_arrayLikeToArray(o, minLen); }\nfunction relabi_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction relabi_iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction relabi_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction relabi_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction relabi_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, relabi_toPropertyKey(descriptor.key), descriptor); } }\nfunction relabi_createClass(Constructor, protoProps, staticProps) { if (protoProps) relabi_defineProperties(Constructor.prototype, protoProps); if (staticProps) relabi_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction relabi_toPropertyKey(arg) { var key = relabi_toPrimitive(arg, "string"); return relabi_typeof(key) === "symbol" ? key : String(key); }\nfunction relabi_toPrimitive(input, hint) { if (relabi_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (relabi_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n/**\n * Relabi event generator\n */\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};\n\n/**\n * Relabi generator\n */\nvar Relabi = /*#__PURE__*/function () {\n /**\n * Initialize generator\n */\n function Relabi(_ref) {\n var waves = _ref.waves,\n bounds = _ref.bounds,\n parent = _ref.parent;\n relabi_classCallCheck(this, Relabi);\n this.updateTime = 1;\n this.steps = 50;\n this.waves = waves || [{\n type: "sine",\n frequency: randrange(0.5, 1.5)\n }, {\n type: "sine",\n frequency: randrange(0.75, 2.25)\n }, {\n type: "sine",\n frequency: randrange(1, 3)\n }, {\n type: "sine",\n frequency: randrange(2, 4)\n }];\n this.bounds = bounds;\n this.previousValue = 0;\n this.canvas = new RelabiCanvas({\n relabi: this,\n parent: parent\n });\n }\n\n /**\n * Start the generator\n */\n relabi_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 var values = _this.generate(time);\n _this.canvas.append(time, values);\n _this.play(values);\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: "generate",\n value: function generate(time) {\n var waveCount = this.waves.length;\n var index;\n var step;\n var value;\n var values = [];\n\n // Generate several events per second\n for (step = 0; step < this.steps; step += 1) {\n // Time offset for this event\n var timeOffset = 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](timeOffset * wave.frequency);\n }\n\n // Scale to [-1, 1]\n value /= waveCount;\n values.push([timeOffset, value]);\n }\n return values;\n }\n\n /**\n * Schedule relabi events\n */\n }, {\n key: "play",\n value: function play(values) {\n var boundsCount = this.bounds.length;\n var previousValue = this.previousValue;\n var index;\n var step;\n var noteCount = 0;\n for (step = 0; step < this.steps; step += 1) {\n // Get the next value\n var _values$step = relabi_slicedToArray(values[step], 2),\n time = _values$step[0],\n value = _values$step[1];\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.level && bound.level < previousValue) {\n // Going down\n this.trigger(time, bound.sounds[0]);\n noteCount += 1;\n } else if (value > bound.level && bound.level > previousValue) {\n // Going up\n this.trigger(time, bound.sounds[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 = previousValue;\n }\n\n /**\n * Trigger an event\n */\n }, {\n key: "trigger",\n value: function trigger(time, sound) {\n // console.log("trigger index", index, time);\n sound.instrument.play(time, sound);\n }\n }]);\n return Relabi;\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/sampler.js\nfunction sampler_typeof(obj) { "@babel/helpers - typeof"; return sampler_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; }, sampler_typeof(obj); }\nfunction _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction sampler_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction sampler_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, sampler_toPropertyKey(descriptor.key), descriptor); } }\nfunction sampler_createClass(Constructor, protoProps, staticProps) { if (protoProps) sampler_defineProperties(Constructor.prototype, protoProps); if (staticProps) sampler_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction sampler_toPropertyKey(arg) { var key = sampler_toPrimitive(arg, "string"); return sampler_typeof(key) === "symbol" ? key : String(key); }\nfunction sampler_toPrimitive(input, hint) { if (sampler_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (sampler_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n\n\n\nvar PLAYER_COUNT = 4;\nvar sampler_Sampler = /*#__PURE__*/function () {\n function Sampler(_ref) {\n var samples = _ref.samples,\n tonal = _ref.tonal;\n sampler_classCallCheck(this, Sampler);\n this.tonal = tonal;\n this.samples = samples.map(function (_ref2) {\n var sample = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));\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 return sample;\n });\n }\n sampler_createClass(Sampler, [{\n key: "play",\n value: function play(time, options) {\n var sound = options.index ? this.samples[options.index] : choice(this.samples);\n sound.index = (sound.index + 1) % PLAYER_COUNT;\n var player = sound.players[sound.index];\n if (this.tonal) {\n player.playbackRate = (options.frequency * choice([0.5, 1]) + util_randrange(0, 10)) / sound.root;\n }\n player.start(time || 0);\n }\n }]);\n return Sampler;\n}();\n\n;// CONCATENATED MODULE: ./src/lib/instruments.js\n\nvar Kalimba = new sampler_Sampler({\n tonal: true,\n 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});\nvar Drums = new sampler_Sampler({\n tonal: false,\n samples: [{\n fn: "samples/707_bd.mp3"\n }, {\n fn: "samples/707_clap.mp3"\n },\n // { fn: "samples/707_cow.mp3" },\n {\n fn: "samples/707_hat.mp3"\n }, {\n fn: "samples/707_rim.mp3"\n }]\n});\n;// CONCATENATED MODULE: ./src/ui/App.jsx\nfunction App_slicedToArray(arr, i) { return App_arrayWithHoles(arr) || App_iterableToArrayLimit(arr, i) || App_unsupportedIterableToArray(arr, i) || App_nonIterableRest(); }\nfunction App_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction App_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return App_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return App_arrayLikeToArray(o, minLen); }\nfunction App_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction App_iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction App_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n/**\n * Relabi generator UI\n * @module src/ui/App.js;\n */\n\n\n\n\n\nfunction App() {\n var _useState = (0,react.useState)(),\n _useState2 = App_slicedToArray(_useState, 2),\n relabi = _useState2[0],\n setRelabi = _useState2[1];\n\n /**\n * Instantiate the Relabi generator\n */\n (0,react.useEffect)(function () {\n if (!relabi) {\n var relabiGenerator = new Relabi({\n waves: [{\n type: "sine",\n frequency: 0.75\n }, {\n type: "sine",\n frequency: 1.0\n }, {\n type: "sine",\n frequency: 1.617\n }, {\n type: "sine",\n frequency: 3.141\n }],\n bounds: [{\n level: -0.75,\n color: "#f00",\n sounds: [{\n instrument: Drums,\n index: 0\n }, {\n instrument: Drums,\n index: 1\n }]\n }, {\n level: 0.75,\n color: "#f00",\n sounds: [{\n instrument: Drums,\n index: 2\n }, {\n instrument: Drums,\n index: 3\n }]\n }, {\n level: -0.25,\n color: "#00f",\n sounds: [{\n instrument: Kalimba,\n frequency: 440\n }, {\n instrument: Kalimba,\n frequency: 440 * 3 / 2\n }]\n }, {\n level: 0.25,\n color: "#00f",\n sounds: [{\n instrument: Kalimba,\n frequency: 440 * 6 / 5\n }, {\n instrument: Kalimba,\n frequency: 440 * 6 / 7\n }]\n }]\n });\n relabiGenerator.start();\n setRelabi(relabiGenerator);\n }\n }, [relabi]);\n\n /**\n * Render\n */\n\n return /*#__PURE__*/react.createElement("div", null, "Relabi generator");\n}\n;// CONCATENATED MODULE: ./src/index.jsx\n\n\n\n\ndocument.body.style.backgroundColor = "#111";\ndocument.body.style.color = "#fff";\ndocument.body.style.margin = 0;\ndocument.body.style.padding = 0;\nrequestAudioContext(function () {\n document.body.innerHTML = \'<div id="app"></div>\';\n var root = (0,client/* createRoot */.s)(document.getElementById("app"));\n root.render( /*#__PURE__*/react.createElement(App, null));\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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YUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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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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SSxNQUFNLENBQUMsQ0FBQzs7RUFFWjtBQUNGO0FBQ0E7O0VBRUUsb0JBQU9tSSxtQkFBQSxjQUFLLGtCQUFxQixDQUFDO0FBQ3BDLEM7O0FDdEUrQjtBQUNlO0FBQ2M7QUFFN0I7QUFFL0J6TCxRQUFRLENBQUNDLElBQUksQ0FBQzRCLEtBQUssQ0FBQ1EsZUFBZSxHQUFHLE1BQU07QUFDNUNyQyxRQUFRLENBQUNDLElBQUksQ0FBQzRCLEtBQUssQ0FBQ1UsS0FBSyxHQUFHLE1BQU07QUFDbEN2QyxRQUFRLENBQUNDLElBQUksQ0FBQzRCLEtBQUssQ0FBQ3FLLE1BQU0sR0FBRyxDQUFDO0FBQzlCbE0sUUFBUSxDQUFDQyxJQUFJLENBQUM0QixLQUFLLENBQUNTLE9BQU8sR0FBRyxDQUFDO0FBRS9CakIsbUJBQW1CLENBQUMsWUFBTTtFQUN4QnJCLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDeUIsU0FBUyxHQUFHLHNCQUFzQjtFQUNoRCxJQUFNNEosSUFBSSxHQUFHVyw0QkFBVSxDQUFDak0sUUFBUSxDQUFDbU0sY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0VBQ3ZEYixJQUFJLENBQUNjLE1BQU0sZUFBQ1gsbUJBQUEsQ0FBQ0csR0FBRyxNQUFFLENBQUMsQ0FBQztBQUN0QixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vdmVyc2lvbi5qcz8zMzgzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Fib3J0LWVycm9yLmpzPzczODIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanM/Nzg3YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcz9mMGZlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2FkZC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucy5qcz9hZDNkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZ2xvYmFscy5qcz83NGY2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1jb25zdHJ1Y3RpYmxlLmpzPzUyODAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NwbGl0LWltcG9ydC1zdGF0ZW1lbnRzLmpzPzc4OTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLWF1ZGlvLXdvcmtsZXQtbW9kdWxlLmpzPzc0ODciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC12YWx1ZS1mb3Ita2V5LmpzPzVkNzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3BpY2stZWxlbWVudC1mcm9tLXNldC5qcz81NjBlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanM/YTUyYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzPzAyN2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUuanM/MmY5NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9hdWRpby13b3JrbGV0LW5vZGUuanM/MWI4ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUuanM/YWU1ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUtd2hlbi1uZWNlc3NhcnkuanM/N2E1NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hZGQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzPzMzOWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzPzEwYzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLXNpbGVudC1jb25uZWN0aW9uLmpzP2M5YzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYWRkLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlLmpzP2RhNmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYW5hbHlzZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz8wODU2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0LmpzPzQ5NjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzczMWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydC5qcz8zN2ZmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2luZGV4LXNpemUtZXJyb3IuanM/YmNjZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QuanM/MjNiNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1idWZmZXItY29uc3RydWN0b3IuanM/NTI3YSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2NvbnN0YW50cy5qcz82MmY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZS5qcz8xMWQ0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcz83NTY5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzY0ZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLmpzP2YyZmYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYmlxdWFkLWZpbHRlci1ub2RlLmpzP2EyMjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvY29uc3RhbnQtc291cmNlLW5vZGUuanM/MjQxYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9nYWluLW5vZGUuanM/YWUxMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9vc2NpbGxhdG9yLW5vZGUuanM/NDA5YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9zdGVyZW8tcGFubmVyLW5vZGUuanM/ZmQ3NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMuanM/MmE3OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zLmpzPzRkYWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlYWN0aXZhdGUtYWN0aXZlLWF1ZGlvLW5vZGUtaW5wdXQtY29ubmVjdGlvbnMuanM/YzkzMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVhY3RpdmF0ZS1hdWRpby1ncmFwaC5qcz85ZTliIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQuanM/ODAwMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzPzk1YjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvci5qcz8wNTM3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz84MmIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLWxpc3RlbmVyLWZhY3RvcnkuanM/ZDA3MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9hdWRpby1ub2RlLmpzP2I0NWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9ndWFyZHMvYXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbi5qcz9lOGMyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pbnNlcnQtZWxlbWVudC1pbi1zZXQuanM/MGUyNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvYWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzPzNlMjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2FkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanM/MTZiNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlci5qcz8xMzY2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlLmpzPzJmZTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi5qcz8zYzU0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanM/ZTg2MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGVsZXRlLWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzPzliMTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanM/MjE5NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGlzY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS1mcm9tLW5hdGl2ZS1hdWRpby1ub2RlLmpzP2Y3MjYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tbm9kZS5qcz8zMDRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzPzk0ZDkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2lzLXBhcnQtb2YtYS1jeWNsZS5qcz8zY2NiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1wYXNzaXZlLWF1ZGlvLW5vZGUuanM/YWEzNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLXN1cHBvcnQuanM/ZTM0MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UuanM/MDJiYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS5qcz85MjFhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2QuanM/ZGVmMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby1ub2RlLWNvbnN0cnVjdG9yLmpzPzlmZTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8tcGFyYW0tZmFjdG9yeS5qcz85MmRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLXJlbmRlcmVyLmpzPzA5MDgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9yZWFkLW9ubHktbWFwLmpzPzljODUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yLmpzPzUxMmIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2NvcHktZnJvbS1jaGFubmVsLmpzP2QwMGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2NvcHktdG8tY2hhbm5lbC5qcz9jZmVmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jcmVhdGUtbmVzdGVkLWFycmF5cy5qcz9mMDE4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanM/ZTEyYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8zZjE2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Jhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz9iMTM0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2JpcXVhZC1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz8yNTYwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2JpcXVhZC1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzgyN2IiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY2FjaGUtdGVzdC1yZXN1bHQuanM/ZmM1MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jaGFubmVsLW1lcmdlci1ub2RlLWNvbnN0cnVjdG9yLmpzP2VkMDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzP2UwODciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY2hhbm5lbC1zcGxpdHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzPzU0YmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY2hhbm5lbC1zcGxpdHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/ZWIwMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb25uZWN0LWF1ZGlvLXBhcmFtLmpzPzU3MjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzLmpzPzEyNDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29ubmVjdGVkLW5hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeS5qcz82NDY1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NvbnN0YW50LXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzPzRiZDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8zMTQ0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NvbnZlcnQtbnVtYmVyLXRvLXVuc2lnbmVkLWxvbmcuanM/MDliZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz8wNWU5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2NvbnZvbHZlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/NWE5NyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9jcmVhdGUtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz81MzJjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RhdGEtY2xvbmUtZXJyb3IuanM/MTk1YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZGV0YWNoLWFycmF5LWJ1ZmZlci5qcz85ZjdlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2RlY29kZS1hdWRpby1kYXRhLmpzPzI2OWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVjcmVtZW50LWN5Y2xlLWNvdW50ZXIuanM/MWY0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWxheS1ub2RlLWNvbnN0cnVjdG9yLmpzPzExM2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVsYXktbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzPzFlNzUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanM/ZTIxNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9kZWxldGUtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanM/MWQ0NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2d1YXJkcy9kZWxheS1ub2RlLmpzPzZlOTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZGV0ZWN0LWN5Y2xlcy5qcz83YWIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2Rpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcz8zZDQzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2R5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1jb25zdHJ1Y3Rvci5qcz84MmYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2R5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzP2JhOTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZW5jb2RpbmctZXJyb3IuanM/YjY3YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9ldmFsdWF0ZS1zb3VyY2UuanM/MzVmNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9ldmVudC10YXJnZXQtY29uc3RydWN0b3IuanM/NDIyNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9leHBvc2UtY3VycmVudC1mcmFtZS1hbmQtY3VycmVudC10aW1lLmpzPzYzZjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZmV0Y2gtc291cmNlLmpzP2U5ZGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2Fpbi1ub2RlLWNvbnN0cnVjdG9yLmpzP2M3ZGUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvZ2Fpbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/NzdlZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMuanM/NjA0YSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9nZXQtYXVkaW8tbm9kZS1yZW5kZXJlci5qcz9kYTUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXRhaWwtdGltZS5qcz8wMzYzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1hdWRpby1wYXJhbS1yZW5kZXJlci5qcz8wZmU3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzPzkyMzIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaW52YWxpZC1zdGF0ZS1lcnJvci5qcz9lMDk0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1uYXRpdmUtY29udGV4dC5qcz80ZWFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC1vci1jcmVhdGUtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcz9kYTlkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2dldC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZXMuanM/ZGNlOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pbnZhbGlkLWFjY2Vzcy1lcnJvci5qcz8zNjFhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWlpci1maWx0ZXItbm9kZS1nZXQtZnJlcXVlbmN5LXJlc3BvbnNlLW1ldGhvZC5qcz84NzQ0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz8wNTZlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9maWx0ZXItYnVmZmVyLmpzP2U0MWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaWlyLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MzczOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pbmNyZW1lbnQtY3ljbGUtY291bnRlci1mYWN0b3J5LmpzP2UzMjUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLWNvbnRleHQuanM/NWEyOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tbm9kZS5qcz8wNzg4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLWFueS1hdWRpby1wYXJhbS5qcz83ZTc1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLWFueS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/ZGYyOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tY29udGV4dC5qcz8yMjZjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1ub2RlLmpzPzYzYjkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzPzE1MWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtbmF0aXZlLWNvbnRleHQuanM/NWNlNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9pcy1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzPzVhZDYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvaXMtc2VjdXJlLWNvbnRleHQuanM/ODZmNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzPzczNzAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanM/MzA3NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanM/YWE0YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanM/YmE1OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9taW5pbWFsLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/ZWRkMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9taW5pbWFsLWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcz9kZTYyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydC5qcz9lNTM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL21pbmltYWwtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzPzUwMzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbW9uaXRvci1jb25uZWN0aW9ucy5qcz9mYzc3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uLmpzPzhlZjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zLmpzP2NlNzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2Qtc3VwcG9ydC5qcz8xMDFkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLmpzP2Y1NzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeS5qcz9iMzQwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanM/ODhmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlLmpzPzYzZjAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy5qcz9mODAwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcz8yNTEyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLmpzPzkyNGYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzPzNmOTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanM/MjdlMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tZGVzdGluYXRpb24tbm9kZS5qcz9kZWRjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanM/ZTE2ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1jbG9uYWJpbGl0eS1vZi1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcz82YzJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeS5qcz8yOGRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplLmpzP2QxMTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2Nsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzPzhiNTEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2NyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wcm9taXNlLmpzPzEyZDUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2NyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci5qcz8zYTlmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFrZXItZmFjdG9yeS5qcz8wYzA4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1iaXF1YWQtZmlsdGVyLW5vZGUuanM/YTlkZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtY2hhbm5lbC1tZXJnZXItbm9kZS1mYWN0b3J5LmpzPzI1NmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3dyYXAtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzPzNiYWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWNoYW5uZWwtc3BsaXR0ZXItbm9kZS5qcz84OWJhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzPzVhMDMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucy5qcz81MDFhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWtlci1mYWN0b3J5LmpzP2UwY2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLWNvbnZvbHZlci1ub2RlLWZhY3RvcnkuanM/YTE0ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtZGVsYXktbm9kZS5qcz8wNTE4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtZmFjdG9yeS5qcz80ODk2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1nYWluLW5vZGUuanM/ZjdmMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZhY3RvcnkuanM/ZjNlMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZha2VyLWZhY3RvcnkuanM/ZjhhZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS5qcz8wNzA5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZS5qcz9kMWNhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUuanM/ZWNjNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWZhY3RvcnkuanM/MzYzMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzPzcyZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLW9zY2lsbGF0b3Itbm9kZS1mYWN0b3J5LmpzPzk3ZWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZhY3RvcnkuanM/ZWNmZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcz8wZGFkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS1wZXJpb2RpYy13YXZlLWZhY3RvcnkuanM/OWJiMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9uYXRpdmUtc2NyaXB0LXByb2Nlc3Nvci1ub2RlLmpzP2IxNTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWN0b3J5LmpzPzU4ZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzPzBkZTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFjdG9yeS5qcz84NTk1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL25hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZha2VyLWZhY3RvcnkuanM/MzM0OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9ub3Qtc3VwcG9ydGVkLWVycm9yLmpzPzEzNjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzPzMwZDEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvb3NjaWxsYXRvci1ub2RlLWNvbnN0cnVjdG9yLmpzPzljNWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvb3NjaWxsYXRvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/NzMyYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz82ODRmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Bhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanM/MTgyNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9wZXJpb2RpYy13YXZlLWNvbnN0cnVjdG9yLmpzP2MxMDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcmVuZGVyLWF1dG9tYXRpb24uanM/MThlYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLW5vZGUuanM/M2I4NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLXBhcmFtLmpzPzc0ZjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvcmVuZGVyLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanM/MTNhOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9zZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMuanM/ZjI4MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9zZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUuanM/ZTMwMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9zdGFydC1yZW5kZXJpbmcuanM/NzEzMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9zdGVyZW8tcGFubmVyLW5vZGUtY29uc3RydWN0b3IuanM/OGVjMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy9zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz83YjQwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLXN1cHBvcnQuanM/NGJiMCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXBvc3QtbWVzc2FnZS1zdXBwb3J0LmpzP2ZiY2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvdGVzdC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY3VycmVudC10aW1lLXN1cHBvcnQuanM/Y2VhNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy91bmtub3duLWVycm9yLmpzP2MxZDAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1jb25zdHJ1Y3Rvci5qcz8xNDJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dhdmUtc2hhcGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcz8yODNiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dpbmRvdy5qcz9hYjNiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLmpzPzNlM2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy5qcz8xYWRhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXIuanM/NzBkNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2ZhY3Rvcmllcy93cmFwLWNoYW5uZWwtbWVyZ2VyLW5vZGUuanM/ODc1NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvZ2V0LWZpcnN0LXNhbXBsZS5qcz84OTVhIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9pcy1kYy1jdXJ2ZS5qcz9kNGUxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9vdmVyd3JpdGUtYWNjZXNzb3JzLmpzPzFiMjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Nhbml0aXplLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzPzgwNTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Nhbml0aXplLWNoYW5uZWwtc3BsaXR0ZXItb3B0aW9ucy5qcz80OTA3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy9zYW5pdGl6ZS1wZXJpb2RpYy13YXZlLW9wdGlvbnMuanM/ZjZkZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvc2V0LXZhbHVlLWF0LXRpbWUtdW50aWwtcG9zc2libGUuanM/YTljMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanM/NjcyZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy1zdXBwb3J0LmpzPzhkZGEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXItc3VwcG9ydC5qcz9mNjEyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0LmpzP2UxNmUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanM/ZTU2ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0LmpzPzc0ZjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9oZWxwZXJzL3Rlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHkuanM/NjdjMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvYnVpbGQvZXMyMDE5L2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy5qcz8xZjE1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy5qcz9lZDIyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dC9idWlsZC9lczIwMTkvaGVscGVycy93cmFwLWV2ZW50LWxpc3RlbmVyLmpzP2U0OWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2J1aWxkL2VzMjAxOS9tb2R1bGUuanM/NzhkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0RlYnVnLmpzP2EzNzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9UeXBlQ2hlY2suanM/ODY3MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0F1ZGlvQ29udGV4dC5qcz85MWFiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90c2xpYi90c2xpYi5lczYuanM/OWFiNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UaWNrZXIuanM/YTQ1OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0FkdmFuY2VkVHlwZUNoZWNrLmpzP2JmNmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9EZWZhdWx0cy5qcz81Yjc5Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL1RvbmUuanM/YWZhZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL01hdGguanM/ZjRjZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL1RpbWVsaW5lLmpzP2U1MjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Db250ZXh0SW5pdGlhbGl6YXRpb24uanM/MDEzMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0VtaXR0ZXIuanM/MTVlZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0Jhc2VDb250ZXh0LmpzPzFkMjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9Db250ZXh0LmpzP2EyODIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9EdW1teUNvbnRleHQuanM/NGM5ZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS91dGlsL0ludGVyZmFjZS5qcz8wNmUyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyLmpzPzE0OWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dC5qcz9hYjE1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL0dsb2JhbC5qcz81ODNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3R5cGUvQ29udmVyc2lvbnMuanM/NDZmNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL1RpbWVCYXNlLmpzP2I2NzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9UaW1lLmpzPzQxNDIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdHlwZS9GcmVxdWVuY3kuanM/NDVjNiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL1RyYW5zcG9ydFRpbWUuanM/ZDUwYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1RvbmVXaXRoQ29udGV4dC5qcz9kNjgzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvU3RhdGVUaW1lbGluZS5qcz9mMWIxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvUGFyYW0uanM/MWY3NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGUuanM/YjY0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L0dhaW4uanM/YjIzMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL09uZVNob3RTb3VyY2UuanM/NDc3OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1RvbmVDb25zdGFudFNvdXJjZS5qcz9mNGJlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU2lnbmFsLmpzP2RkZWEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVGlja1BhcmFtLmpzPzVjZTMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVGlja1NpZ25hbC5qcz83MjE3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RpY2tTb3VyY2UuanM/ODJjNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9DbG9jay5qcz8xMGEyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2NvbnRleHQvRGVsYXkuanM/YmIzYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L09mZmxpbmUuanM/ZTk0MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnMuanM/NDlkNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL01pZGkuanM/YzhmZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS90eXBlL1RpY2tzLmpzP2U2Y2UiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9EcmF3LmpzPzU0M2MiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9JbnRlcnZhbFRpbWVsaW5lLmpzPzA4OWMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvaW5kZXguanM/Y2QzOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lLmpzP2EwOTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9EZXN0aW5hdGlvbi5qcz8xYmNlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3V0aWwvVGltZWxpbmVWYWx1ZS5qcz9iMDMzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL2Nsb2NrL1RyYW5zcG9ydEV2ZW50LmpzPzNmMTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY2xvY2svVHJhbnNwb3J0UmVwZWF0RXZlbnQuanM/OThkZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS9jbG9jay9UcmFuc3BvcnQuanM/NGM0ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL1NvdXJjZS5qcz81MDljIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2UvYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2UuanM/MmIzYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL05vaXNlLmpzP2QzMDYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9Vc2VyTWVkaWEuanM/YzczZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvT3NjaWxsYXRvckludGVyZmFjZS5qcz9kOWRjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9Ub25lT3NjaWxsYXRvck5vZGUuanM/ZmJiZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvT3NjaWxsYXRvci5qcz80ZGQwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU2lnbmFsT3BlcmF0b3IuanM/OWU4OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1dhdmVTaGFwZXIuanM/YTNjZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL0F1ZGlvVG9HYWluLmpzP2FkYWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9NdWx0aXBseS5qcz81MDc4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9BTU9zY2lsbGF0b3IuanM/NTgyNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvRk1Pc2NpbGxhdG9yLmpzPzVhMTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL1B1bHNlT3NjaWxsYXRvci5qcz80Mjk1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zb3VyY2Uvb3NjaWxsYXRvci9GYXRPc2NpbGxhdG9yLmpzP2I4ZGQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9vc2NpbGxhdG9yL1BXTU9zY2lsbGF0b3IuanM/ZWZkYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3IuanM/N2Q3OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL0FkZC5qcz80MjgxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9zaWduYWwvU2NhbGUuanM/ZWQ2ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1plcm8uanM/ZWRiNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL29zY2lsbGF0b3IvTEZPLmpzP2YzM2EiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvdXRpbC9EZWNvcmF0b3IuanM/OTZmYiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL2J1ZmZlci9QbGF5ZXIuanM/Nzc4MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL2J1ZmZlci9QbGF5ZXJzLmpzPzQ3NDkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NvdXJjZS9idWZmZXIvR3JhaW5QbGF5ZXIuanM/MGExZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc291cmNlL2luZGV4LmpzP2Y0MjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9BYnMuanM/YmI5MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL0dhaW5Ub0F1ZGlvLmpzPzIyNmMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9OZWdhdGUuanM/MGEyMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1N1YnRyYWN0LmpzP2I2N2QiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9HcmVhdGVyVGhhblplcm8uanM/NjIyNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL0dyZWF0ZXJUaGFuLmpzP2JkMzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9Qb3cuanM/YTg0MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL1NjYWxlRXhwLmpzPzQ2NzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3NpZ25hbC9TeW5jZWRTaWduYWwuanM/OTU3MiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vc2lnbmFsL2luZGV4LmpzPzAzNTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZS5qcz8yM2Y4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L0luc3RydW1lbnQuanM/ZTkzMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Nb25vcGhvbmljLmpzPzc0ZWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZS5qcz9mMjExIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L1N5bnRoLmpzP2U1ZTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTW9kdWxhdGlvblN5bnRoLmpzPzNjMjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvQU1TeW50aC5qcz9iYTA3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0JpcXVhZEZpbHRlci5qcz82NDZmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0ZpbHRlci5qcz8xMzE1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZW52ZWxvcGUvRnJlcXVlbmN5RW52ZWxvcGUuanM/ODcwOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9Nb25vU3ludGguanM/MmRlZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9EdW9TeW50aC5qcz83ODdmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L0ZNU3ludGguanM/YjljOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9NZXRhbFN5bnRoLmpzPzkzMmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvTWVtYnJhbmVTeW50aC5qcz85NTQxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L05vaXNlU3ludGguanM/M2M4ZSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29yZS93b3JrbGV0L1dvcmtsZXRHbG9iYWxTY29wZS5qcz84YTY0Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvVG9uZUF1ZGlvV29ya2xldC5qcz9lMDhmIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb3JlL3dvcmtsZXQvVG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0LmpzPzUxZjEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvd29ya2xldC9TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0LmpzPzU2OGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvd29ya2xldC9EZWxheUxpbmUud29ya2xldC5qcz9kNTA4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlci53b3JrbGV0LmpzPzA4OGMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvRmVlZGJhY2tDb21iRmlsdGVyLmpzP2E1MWYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvT25lUG9sZUZpbHRlci5qcz9hNzhlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyLmpzPzI4ZTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luc3RydW1lbnQvUGx1Y2tTeW50aC5qcz8wNmNjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L1BvbHlTeW50aC5qcz81ODgzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9pbnN0cnVtZW50L1NhbXBsZXIuanM/MzE5NSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5zdHJ1bWVudC9pbmRleC5qcz9jNjEyIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9Ub25lRXZlbnQuanM/ZTUzMSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvTG9vcC5qcz9kYmRiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9QYXJ0LmpzPzhkMzgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2V2ZW50L1BhdHRlcm5HZW5lcmF0b3IuanM/OWNkZiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZXZlbnQvUGF0dGVybi5qcz9jNDY2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9TZXF1ZW5jZS5qcz84ZjkzIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9ldmVudC9pbmRleC5qcz80MDRiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGUuanM/MmM4NiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0VmZmVjdC5qcz9kMTI2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvTEZPRWZmZWN0LmpzPzRiMzkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9BdXRvRmlsdGVyLmpzPzA5NzQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1Bhbm5lci5qcz9iMWViIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQXV0b1Bhbm5lci5qcz8yYTQ3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvRm9sbG93ZXIuanM/NDZiNCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0F1dG9XYWguanM/YzljYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0JpdENydXNoZXIud29ya2xldC5qcz9kYjg1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQml0Q3J1c2hlci5qcz9hNDliIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvQ2hlYnlzaGV2LmpzP2IxODciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL1NwbGl0LmpzPzk5YjgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL01lcmdlLmpzP2QwNWIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9TdGVyZW9FZmZlY3QuanM/ZjA2YyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1N0ZXJlb0ZlZWRiYWNrRWZmZWN0LmpzPzExZTAiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9DaG9ydXMuanM/NzQxYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0Rpc3RvcnRpb24uanM/ODA0OCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0ZlZWRiYWNrRWZmZWN0LmpzP2E3MTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9GZWVkYmFja0RlbGF5LmpzPzhiZjMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvUGhhc2VTaGlmdEFsbHBhc3MuanM/OGQ1MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0ZyZXF1ZW5jeVNoaWZ0ZXIuanM/OGE2MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L0ZyZWV2ZXJiLmpzP2U4OTciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9KQ1JldmVyYi5qcz8xNWRjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9lZmZlY3QvU3RlcmVvWEZlZWRiYWNrRWZmZWN0LmpzPzg5ODYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9QaW5nUG9uZ0RlbGF5LmpzP2RlMjQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9QaXRjaFNoaWZ0LmpzPzg2YTYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9QaGFzZXIuanM/NmI3MCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vZWZmZWN0L1JldmVyYi5qcz8wZDgxIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlU3BsaXQuanM/ZmUzZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvTWlkU2lkZU1lcmdlLmpzPzZmYjIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9NaWRTaWRlRWZmZWN0LmpzP2VmZjciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9TdGVyZW9XaWRlbmVyLmpzPzBkYjIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9UcmVtb2xvLmpzPzBlMWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9WaWJyYXRvLmpzPzBjMWUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2VmZmVjdC9pbmRleC5qcz9lYzRlIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvQW5hbHlzZXIuanM/ZWRhYyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL01ldGVyQmFzZS5qcz80NzZiIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvTWV0ZXIuanM/ZGY0MSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2FuYWx5c2lzL0ZGVC5qcz82NWVkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvRENNZXRlci5qcz83YjkwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvYW5hbHlzaXMvV2F2ZWZvcm0uanM/OTlkMyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvU29sby5qcz8xYmJkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9QYW5Wb2wuanM/MWFmOCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2NoYW5uZWwvQ2hhbm5lbC5qcz9kMzcwIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9Nb25vLmpzPzlmYTgiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9jaGFubmVsL011bHRpYmFuZFNwbGl0LmpzPzM0NTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvcmUvY29udGV4dC9MaXN0ZW5lci5qcz8yMDM4Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9QYW5uZXIzRC5qcz9jOWRkIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvY2hhbm5lbC9SZWNvcmRlci5qcz9hZDdjIiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZHluYW1pY3MvQ29tcHJlc3Nvci5qcz82ZGI1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZHluYW1pY3MvR2F0ZS5qcz84YmY1Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZHluYW1pY3MvTGltaXRlci5qcz8xNWM3Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jb21wb25lbnQvZHluYW1pY3MvTWlkU2lkZUNvbXByZXNzb3IuanM/ZGI1OSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL011bHRpYmFuZENvbXByZXNzb3IuanM/ZmRiZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9FUTMuanM/MmY3MyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2ZpbHRlci9Db252b2x2ZXIuanM/ZWExNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2luZGV4LmpzPzFkNzYiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NsYXNzZXMuanM/ZDNjNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vaW5kZXguanM/NWU1NCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3V0aWwuanM/ZjFlZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvcmVsYWJpL2NhbnZhcy5qcz9kYzlkIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9yZWxhYmkvaW5kZXguanM/MDJmYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL291dHB1dC5qcz8zZmU1Iiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9saWIvc2FtcGxlci5qcz81OTZiIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9saWIvaW5zdHJ1bWVudHMuanM/ZjlhMiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvdWkvQXBwLmpzeD80NDJhIiwid2VicGFjazovL3JlbGFiaS8uL3NyYy9pbmRleC5qc3g/ZWQxMiJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgdmVyc2lvbiA9IFwiMTQuNy43N1wiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dmVyc2lvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWJvcnRFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdBYm9ydEVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hYm9ydC1lcnJvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAoaW5zZXJ0RWxlbWVudEluU2V0KSA9PiB7XG4gICAgcmV0dXJuIChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgICAgIGluc2VydEVsZW1lbnRJblNldChhY3RpdmVJbnB1dHNbaW5wdXRdLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCAoYWN0aXZlSW5wdXRDb25uZWN0aW9uKSA9PiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCwgaWdub3JlRHVwbGljYXRlcyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSAoYXVkaW9Ob2RlQ29ubmVjdGlvbnNTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCBhdWRpb05vZGVSZW5kZXJlciwgbmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0cyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICBhY3RpdmVJbnB1dHMucHVzaChuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIGF1ZGlvTm9kZUNvbm5lY3Rpb25zU3RvcmUuc2V0KGF1ZGlvTm9kZSwge1xuICAgICAgICAgICAgYWN0aXZlSW5wdXRzLFxuICAgICAgICAgICAgb3V0cHV0czogbmV3IFNldCgpLFxuICAgICAgICAgICAgcGFzc2l2ZUlucHV0czogbmV3IFdlYWtNYXAoKSxcbiAgICAgICAgICAgIHJlbmRlcmVyOiBhdWRpb05vZGVSZW5kZXJlclxuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSAoYXVkaW9QYXJhbUNvbm5lY3Rpb25zU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvUGFyYW0sIGF1ZGlvUGFyYW1SZW5kZXJlcikgPT4ge1xuICAgICAgICBhdWRpb1BhcmFtQ29ubmVjdGlvbnNTdG9yZS5zZXQoYXVkaW9QYXJhbSwgeyBhY3RpdmVJbnB1dHM6IG5ldyBTZXQoKSwgcGFzc2l2ZUlucHV0czogbmV3IFdlYWtNYXAoKSwgcmVuZGVyZXI6IGF1ZGlvUGFyYW1SZW5kZXJlciB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgPSBuZXcgV2Vha1NldCgpO1xuZXhwb3J0IGNvbnN0IEFVRElPX05PREVfQ09OTkVDVElPTlNfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEFVRElPX05PREVfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19QQVJBTV9TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQ09OVEVYVF9TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgRVZFTlRfTElTVEVORVJTID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBDWUNMRV9DT1VOVEVSUyA9IG5ldyBXZWFrTWFwKCk7XG4vLyBUaGlzIGNsdW5reSBuYW1lIGlzIGJvcnJvd2VkIGZyb20gdGhlIHNwZWMuIDotKVxuZXhwb3J0IGNvbnN0IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUyA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyA9IG5ldyBXZWFrTWFwKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nbG9iYWxzLmpzLm1hcCIsImNvbnN0IGhhbmRsZXIgPSB7XG4gICAgY29uc3RydWN0KCkge1xuICAgICAgICByZXR1cm4gaGFuZGxlcjtcbiAgICB9XG59O1xuZXhwb3J0IGNvbnN0IGlzQ29uc3RydWN0aWJsZSA9IChjb25zdHJ1Y3RpYmxlKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkoY29uc3RydWN0aWJsZSwgaGFuZGxlcik7XG4gICAgICAgIG5ldyBwcm94eSgpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLXVudXNlZC1leHByZXNzaW9uXG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1jb25zdHJ1Y3RpYmxlLmpzLm1hcCIsIi8qXG4gKiBUaGlzIG1hc3NpdmUgcmVnZXggdHJpZXMgdG8gY292ZXIgYWxsIHRoZSBmb2xsb3dpbmcgY2FzZXMuXG4gKlxuICogaW1wb3J0ICcuL3BhdGgnO1xuICogaW1wb3J0IGRlZmF1bHRJbXBvcnQgZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCB7IG5hbWVkSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCB7IG5hbWVkSW1wb3J0IGFzIHJlbmFtZW5kSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCAqIGFzIG5hbWVzcGFjZUltcG9ydCBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IGRlZmF1bHRJbXBvcnQsIHsgbmFtZWRJbXBvcnQgfSBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IGRlZmF1bHRJbXBvcnQsIHsgbmFtZWRJbXBvcnQgYXMgcmVuYW1lbmRJbXBvcnQgfSBmcm9tICcuL3BhdGgnO1xuICogaW1wb3J0IGRlZmF1bHRJbXBvcnQsICogYXMgbmFtZXNwYWNlSW1wb3J0IGZyb20gJy4vcGF0aCc7XG4gKi9cbmNvbnN0IElNUE9SVF9TVEFURU1FTlRfUkVHRVggPSAvXmltcG9ydCg/Oig/OltcXHNdK1tcXHddK3woPzpbXFxzXStbXFx3XStbXFxzXSosKT9bXFxzXSpcXHtbXFxzXSpbXFx3XSsoPzpbXFxzXSthc1tcXHNdK1tcXHddKyk/KD86W1xcc10qLFtcXHNdKltcXHddKyg/OltcXHNdK2FzW1xcc10rW1xcd10rKT8pKltcXHNdKn18KD86W1xcc10rW1xcd10rW1xcc10qLCk/W1xcc10qXFwqW1xcc10rYXNbXFxzXStbXFx3XSspW1xcc10rZnJvbSk/KD86W1xcc10qKShcIihbXlwiXFxcXF18XFxcXC4pK1wifCcoW14nXFxcXF18XFxcXC4pKycpKD86W1xcc10qKTs/LzsgLy8gdHNsaW50OmRpc2FibGUtbGluZTptYXgtbGluZS1sZW5ndGhcbmV4cG9ydCBjb25zdCBzcGxpdEltcG9ydFN0YXRlbWVudHMgPSAoc291cmNlLCB1cmwpID0+IHtcbiAgICBjb25zdCBpbXBvcnRTdGF0ZW1lbnRzID0gW107XG4gICAgbGV0IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzID0gc291cmNlLnJlcGxhY2UoL15bXFxzXSsvLCAnJyk7XG4gICAgbGV0IHJlc3VsdCA9IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzLm1hdGNoKElNUE9SVF9TVEFURU1FTlRfUkVHRVgpO1xuICAgIHdoaWxlIChyZXN1bHQgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgdW5yZXNvbHZlZFVybCA9IHJlc3VsdFsxXS5zbGljZSgxLCAtMSk7XG4gICAgICAgIGNvbnN0IGltcG9ydFN0YXRlbWVudFdpdGhSZXNvbHZlZFVybCA9IHJlc3VsdFswXVxuICAgICAgICAgICAgLnJlcGxhY2UoLyhbXFxzXSspPzs/JC8sICcnKVxuICAgICAgICAgICAgLnJlcGxhY2UodW5yZXNvbHZlZFVybCwgbmV3IFVSTCh1bnJlc29sdmVkVXJsLCB1cmwpLnRvU3RyaW5nKCkpO1xuICAgICAgICBpbXBvcnRTdGF0ZW1lbnRzLnB1c2goaW1wb3J0U3RhdGVtZW50V2l0aFJlc29sdmVkVXJsKTtcbiAgICAgICAgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMgPSBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cy5zbGljZShyZXN1bHRbMF0ubGVuZ3RoKS5yZXBsYWNlKC9eW1xcc10rLywgJycpO1xuICAgICAgICByZXN1bHQgPSBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cy5tYXRjaChJTVBPUlRfU1RBVEVNRU5UX1JFR0VYKTtcbiAgICB9XG4gICAgcmV0dXJuIFtpbXBvcnRTdGF0ZW1lbnRzLmpvaW4oJzsnKSwgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHNdO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNwbGl0LWltcG9ydC1zdGF0ZW1lbnRzLmpzLm1hcCIsImltcG9ydCB7IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgaXNDb25zdHJ1Y3RpYmxlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1jb25zdHJ1Y3RpYmxlJztcbmltcG9ydCB7IHNwbGl0SW1wb3J0U3RhdGVtZW50cyB9IGZyb20gJy4uL2hlbHBlcnMvc3BsaXQtaW1wb3J0LXN0YXRlbWVudHMnO1xuY29uc3QgdmVyaWZ5UGFyYW1ldGVyRGVzY3JpcHRvcnMgPSAocGFyYW1ldGVyRGVzY3JpcHRvcnMpID0+IHtcbiAgICBpZiAocGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCAmJiAhQXJyYXkuaXNBcnJheShwYXJhbWV0ZXJEZXNjcmlwdG9ycykpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHBhcmFtZXRlckRlc2NyaXB0b3JzIHByb3BlcnR5IG9mIGdpdmVuIHZhbHVlIGZvciBwcm9jZXNzb3JDdG9yIGlzIG5vdCBhbiBhcnJheS4nKTtcbiAgICB9XG59O1xuY29uc3QgdmVyaWZ5UHJvY2Vzc29yQ3RvciA9IChwcm9jZXNzb3JDdG9yKSA9PiB7XG4gICAgaWYgKCFpc0NvbnN0cnVjdGlibGUocHJvY2Vzc29yQ3RvcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGdpdmVuIHZhbHVlIGZvciBwcm9jZXNzb3JDdG9yIHNob3VsZCBiZSBhIGNvbnN0cnVjdG9yLicpO1xuICAgIH1cbiAgICBpZiAocHJvY2Vzc29yQ3Rvci5wcm90b3R5cGUgPT09IG51bGwgfHwgdHlwZW9mIHByb2Nlc3NvckN0b3IucHJvdG90eXBlICE9PSAnb2JqZWN0Jykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdUaGUgZ2l2ZW4gdmFsdWUgZm9yIHByb2Nlc3NvckN0b3Igc2hvdWxkIGhhdmUgYSBwcm90b3R5cGUuJyk7XG4gICAgfVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBZGRBdWRpb1dvcmtsZXRNb2R1bGUgPSAoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZXZhbHVhdGVTb3VyY2UsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBmZXRjaFNvdXJjZSwgZ2V0TmF0aXZlQ29udGV4dCwgZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvciwgb25nb2luZ1JlcXVlc3RzLCByZXNvbHZlZFJlcXVlc3RzLCB0ZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0LCB3aW5kb3cpID0+IHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIHJldHVybiAoY29udGV4dCwgbW9kdWxlVVJMLCBvcHRpb25zID0geyBjcmVkZW50aWFsczogJ29taXQnIH0pID0+IHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dCA9IHJlc29sdmVkUmVxdWVzdHMuZ2V0KGNvbnRleHQpO1xuICAgICAgICBpZiAocmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dCAhPT0gdW5kZWZpbmVkICYmIHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQuaGFzKG1vZHVsZVVSTCkpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQgPSBvbmdvaW5nUmVxdWVzdHMuZ2V0KGNvbnRleHQpO1xuICAgICAgICBpZiAob25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VPZk9uZ29pbmdSZXF1ZXN0ID0gb25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0LmdldChtb2R1bGVVUkwpO1xuICAgICAgICAgICAgaWYgKHByb21pc2VPZk9uZ29pbmdSZXF1ZXN0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZU9mT25nb2luZ1JlcXVlc3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgIC8vIEJ1ZyAjNTk6IFNhZmFyaSBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlIGF1ZGlvV29ya2xldCBwcm9wZXJ0eS5cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5hdGl2ZUNvbnRleHQuYXVkaW9Xb3JrbGV0ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gZmV0Y2hTb3VyY2UobW9kdWxlVVJMKVxuICAgICAgICAgICAgICAgIC50aGVuKChbc291cmNlLCBhYnNvbHV0ZVVybF0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBbaW1wb3J0U3RhdGVtZW50cywgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHNdID0gc3BsaXRJbXBvcnRTdGF0ZW1lbnRzKHNvdXJjZSwgYWJzb2x1dGVVcmwpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyB0aGUgdW5taW5pZmllZCB2ZXJzaW9uIG9mIHRoZSBjb2RlIHVzZWQgYmVsb3c6XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgICAgICAgICAqICR7IGltcG9ydFN0YXRlbWVudHMgfTtcbiAgICAgICAgICAgICAgICAgKiAoKGEsIGIpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgKGFbYl0gPSBhW2JdIHx8IFsgXSkucHVzaChcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIChBdWRpb1dvcmtsZXRQcm9jZXNzb3IsIGdsb2JhbCwgcmVnaXN0ZXJQcm9jZXNzb3IsIHNhbXBsZVJhdGUsIHNlbGYsIHdpbmRvdykgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICR7IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzIH1cbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgKiAgICAgKTtcbiAgICAgICAgICAgICAgICAgKiB9KSh3aW5kb3csICdfQVdHUycpO1xuICAgICAgICAgICAgICAgICAqIGBgYFxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbiAgICAgICAgICAgICAgICBjb25zdCB3cmFwcGVkU291cmNlID0gYCR7aW1wb3J0U3RhdGVtZW50c307KChhLGIpPT57KGFbYl09YVtiXXx8W10pLnB1c2goKEF1ZGlvV29ya2xldFByb2Nlc3NvcixnbG9iYWwscmVnaXN0ZXJQcm9jZXNzb3Isc2FtcGxlUmF0ZSxzZWxmLHdpbmRvdyk9Pnske3NvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzfVxufSl9KSh3aW5kb3csJ19BV0dTJylgO1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIEV2YWx1YXRpbmcgdGhlIGdpdmVuIHNvdXJjZSBjb2RlIGlzIGEgcG9zc2libGUgc2VjdXJpdHkgcHJvYmxlbS5cbiAgICAgICAgICAgICAgICByZXR1cm4gZXZhbHVhdGVTb3VyY2Uod3JhcHBlZFNvdXJjZSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmFsdWF0ZUF1ZGlvV29ya2xldEdsb2JhbFNjb3BlID0gd2luZG93Ll9BV0dTLnBvcCgpO1xuICAgICAgICAgICAgICAgIGlmIChldmFsdWF0ZUF1ZGlvV29ya2xldEdsb2JhbFNjb3BlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKG5hdGl2ZUNvbnRleHQuY3VycmVudFRpbWUsIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgKCkgPT4gZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZShjbGFzcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3Ige1xuICAgICAgICAgICAgICAgIH0sIHVuZGVmaW5lZCwgKG5hbWUsIHByb2Nlc3NvckN0b3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUudHJpbSgpID09PSAnJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPSBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVByb2Nlc3NvckN0b3IocHJvY2Vzc29yQ3Rvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQYXJhbWV0ZXJEZXNjcmlwdG9ycyhwcm9jZXNzb3JDdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcC5zZXQobmFtZSwgcHJvY2Vzc29yQ3Rvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQcm9jZXNzb3JDdG9yKHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UGFyYW1ldGVyRGVzY3JpcHRvcnMocHJvY2Vzc29yQ3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMuc2V0KG5hdGl2ZUNvbnRleHQsIG5ldyBNYXAoW1tuYW1lLCBwcm9jZXNzb3JDdG9yXV0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgdW5kZWZpbmVkLCB1bmRlZmluZWQpKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICA6IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICBmZXRjaFNvdXJjZShtb2R1bGVVUkwpLFxuICAgICAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZShjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCwgdGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCkpXG4gICAgICAgICAgICBdKS50aGVuKChbW3NvdXJjZSwgYWJzb2x1dGVVcmxdLCBpc1N1cHBvcnRpbmdQb3N0TWVzc2FnZV0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50SW5kZXggPSBpbmRleCArIDE7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBjdXJyZW50SW5kZXg7XG4gICAgICAgICAgICAgICAgY29uc3QgW2ltcG9ydFN0YXRlbWVudHMsIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXSA9IHNwbGl0SW1wb3J0U3RhdGVtZW50cyhzb3VyY2UsIGFic29sdXRlVXJsKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTc5OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRvIHRyYW5zZmVyIGFueSBidWZmZXIgd2hpY2ggaGFzIGJlZW4gcGFzc2VkIHRvIHRoZSBwcm9jZXNzKCkgbWV0aG9kIGFzIGFuIGFyZ3VtZW50LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyB0aGUgdW5taW5pZmllZCB2ZXJzaW9uIG9mIHRoZSBjb2RlIHVzZWQgYmVsb3cuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgICAgICAgICAqIGNsYXNzIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBfX2J1ZmZlcnMgPSBuZXcgV2Vha1NldCgpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgIGNvbnN0cnVjdG9yICgpIHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHN1cGVyKCk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHRoaXMucG9ydC5wb3N0TWVzc2FnZSA9ICgocG9zdE1lc3NhZ2UpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICByZXR1cm4gKG1lc3NhZ2UsIHRyYW5zZmVyYWJsZXMpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyZWRUcmFuc2ZlcmFibGVzID0gKHRyYW5zZmVyYWJsZXMpXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICA/IHRyYW5zZmVyYWJsZXMuZmlsdGVyKCh0cmFuc2ZlcmFibGUpID0+ICF0aGlzLl9fYnVmZmVycy5oYXModHJhbnNmZXJhYmxlKSlcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgICAgIDogdHJhbnNmZXJhYmxlcztcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICByZXR1cm4gcG9zdE1lc3NhZ2UuY2FsbCh0aGlzLnBvcnQsIG1lc3NhZ2UsIGZpbHRlcmVkVHJhbnNmZXJhYmxlcyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9KSh0aGlzLnBvcnQucG9zdE1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAqICAgICB9XG4gICAgICAgICAgICAgICAgICogfVxuICAgICAgICAgICAgICAgICAqIGBgYFxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSBpc1N1cHBvcnRpbmdQb3N0TWVzc2FnZVxuICAgICAgICAgICAgICAgICAgICA/ICdBdWRpb1dvcmtsZXRQcm9jZXNzb3InXG4gICAgICAgICAgICAgICAgICAgIDogJ2NsYXNzIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtfX2I9bmV3IFdlYWtTZXQoKTtjb25zdHJ1Y3Rvcigpe3N1cGVyKCk7KHA9PnAucG9zdE1lc3NhZ2U9KHE9PihtLHQpPT5xLmNhbGwocCxtLHQ/dC5maWx0ZXIodT0+IXRoaXMuX19iLmhhcyh1KSk6dCkpKHAucG9zdE1lc3NhZ2UpKSh0aGlzLnBvcnQpfX0nO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICMxNzA6IENocm9tZSBhbmQgRWRnZSBkbyBjYWxsIHByb2Nlc3MoKSB3aXRoIGFuIGFycmF5IHdpdGggZW1wdHkgY2hhbm5lbERhdGEgZm9yIGVhY2ggaW5wdXQgaWYgbm8gaW5wdXQgaXMgY29ubmVjdGVkLlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogQnVnICMxNzk6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdG8gdHJhbnNmZXIgYW55IGJ1ZmZlciB3aGljaCBoYXMgYmVlbiBwYXNzZWQgdG8gdGhlIHByb2Nlc3MoKSBtZXRob2QgYXMgYW4gYXJndW1lbnQuXG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE5MDogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBsb2FkaW5nIGFuIHVucGFyc2FibGUgbW9kdWxlLlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyB0aGUgdW5taW5pZmllZCB2ZXJzaW9uIG9mIHRoZSBjb2RlIHVzZWQgYmVsb3c6XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiBgYGBqc1xuICAgICAgICAgICAgICAgICAqIGAkeyBpbXBvcnRTdGF0ZW1lbnRzIH07XG4gICAgICAgICAgICAgICAgICogKChBdWRpb1dvcmtsZXRQcm9jZXNzb3IsIHJlZ2lzdGVyUHJvY2Vzc29yKSA9PiB7JHsgc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMgfVxuICAgICAgICAgICAgICAgICAqIH0pKFxuICAgICAgICAgICAgICAgICAqICAgICAke8KgcGF0Y2hlZEF1ZGlvV29ya2xldFByb2Nlc3NvciB9LFxuICAgICAgICAgICAgICAgICAqICAgICAobmFtZSwgcHJvY2Vzc29yQ3RvcikgPT4gcmVnaXN0ZXJQcm9jZXNzb3IobmFtZSwgY2xhc3MgZXh0ZW5kcyBwcm9jZXNzb3JDdG9yIHtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgX19jb2xsZWN0QnVmZmVycyA9IChhcnJheSkgPT4ge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIGFycmF5LmZvckVhY2goKGVsZW1lbnQpID0+IHRoaXMuX19idWZmZXJzLmFkZChlbGVtZW50LmJ1ZmZlcikpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICAgICAgcHJvY2VzcyAoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgaW5wdXRzLmZvckVhY2godGhpcy5fX2NvbGxlY3RCdWZmZXJzKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICBvdXRwdXRzLmZvckVhY2godGhpcy5fX2NvbGxlY3RCdWZmZXJzKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICB0aGlzLl9fY29sbGVjdEJ1ZmZlcnMoT2JqZWN0LnZhbHVlcyhwYXJhbWV0ZXJzKSk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICByZXR1cm4gc3VwZXIucHJvY2VzcyhcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgKGlucHV0cy5tYXAoKGlucHV0KSA9PiBpbnB1dC5zb21lKChjaGFubmVsRGF0YSkgPT4gY2hhbm5lbERhdGEubGVuZ3RoID09PSAwKSkgPyBbIF0gOiBpbnB1dCksXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIG91dHB1dHMsXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIHBhcmFtZXRlcnNcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgIH0pXG4gICAgICAgICAgICAgICAgICogKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIHJlZ2lzdGVyUHJvY2Vzc29yKGBfX3NhYyR7Y3VycmVudEluZGV4fWAsIGNsYXNzIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29ye1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgIHByb2Nlc3MgKCkge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAqICAgICB9XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiB9KWBcbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBtZW1iZXJEZWZpbml0aW9uID0gaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2UgPyAnJyA6ICdfX2MgPSAoYSkgPT4gYS5mb3JFYWNoKGU9PnRoaXMuX19iLmFkZChlLmJ1ZmZlcikpOyc7XG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyUmVnaXN0cmF0aW9uID0gaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgPyAnJ1xuICAgICAgICAgICAgICAgICAgICA6ICdpLmZvckVhY2godGhpcy5fX2MpO28uZm9yRWFjaCh0aGlzLl9fYyk7dGhpcy5fX2MoT2JqZWN0LnZhbHVlcyhwKSk7JztcbiAgICAgICAgICAgICAgICBjb25zdCB3cmFwcGVkU291cmNlID0gYCR7aW1wb3J0U3RhdGVtZW50c307KChBdWRpb1dvcmtsZXRQcm9jZXNzb3IscmVnaXN0ZXJQcm9jZXNzb3IpPT57JHtzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c31cbn0pKCR7cGF0Y2hlZEF1ZGlvV29ya2xldFByb2Nlc3Nvcn0sKG4scCk9PnJlZ2lzdGVyUHJvY2Vzc29yKG4sY2xhc3MgZXh0ZW5kcyBweyR7bWVtYmVyRGVmaW5pdGlvbn1wcm9jZXNzKGksbyxwKXske2J1ZmZlclJlZ2lzdHJhdGlvbn1yZXR1cm4gc3VwZXIucHJvY2VzcyhpLm1hcChqPT5qLnNvbWUoaz0+ay5sZW5ndGg9PT0wKT9bXTpqKSxvLHApfX0pKTtyZWdpc3RlclByb2Nlc3NvcignX19zYWMke2N1cnJlbnRJbmRleH0nLGNsYXNzIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29ye3Byb2Nlc3MoKXtyZXR1cm4gITF9fSlgO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbd3JhcHBlZFNvdXJjZV0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLTgnIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnRleHQuYXVkaW9Xb3JrbGV0XG4gICAgICAgICAgICAgICAgICAgIC5hZGRNb2R1bGUodXJsLCBvcHRpb25zKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb250ZXh0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTg2OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGFsbG93IHRvIGNyZWF0ZSBhbiBBdWRpb1dvcmtsZXROb2RlIG9uIGEgY2xvc2VkIEF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQuYXVkaW9Xb3JrbGV0LmFkZE1vZHVsZSh1cmwsIG9wdGlvbnMpLnRoZW4oKCkgPT4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTkwOiBTYWZhcmkgZG9lc24ndCB0aHJvdyBhbiBlcnJvciB3aGVuIGxvYWRpbmcgYW4gdW5wYXJzYWJsZSBtb2R1bGUuXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXcgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGBfX3NhYyR7Y3VycmVudEluZGV4fWApOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLXVudXNlZC1leHByZXNzaW9uXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFN5bnRheEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAuZmluYWxseSgoKSA9PiBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIGlmIChvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgb25nb2luZ1JlcXVlc3RzLnNldChjb250ZXh0LCBuZXcgTWFwKFtbbW9kdWxlVVJMLCBwcm9taXNlXV0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dC5zZXQobW9kdWxlVVJMLCBwcm9taXNlKTtcbiAgICAgICAgfVxuICAgICAgICBwcm9taXNlXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkUmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dCA9IHJlc29sdmVkUmVxdWVzdHMuZ2V0KGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZWRSZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlZFJlcXVlc3RzLnNldChjb250ZXh0LCBuZXcgU2V0KFttb2R1bGVVUkxdKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVkUmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dC5hZGQobW9kdWxlVVJMKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRPbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQgPSBvbmdvaW5nUmVxdWVzdHMuZ2V0KGNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZWRPbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHVwZGF0ZWRPbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQuZGVsZXRlKG1vZHVsZVVSTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcHJvbWlzZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hdWRpby13b3JrbGV0LW1vZHVsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgZ2V0VmFsdWVGb3JLZXkgPSAobWFwLCBrZXkpID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG1hcC5nZXQoa2V5KTtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgdmFsdWUgd2l0aCB0aGUgZ2l2ZW4ga2V5IGNvdWxkIG5vdCBiZSBmb3VuZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC12YWx1ZS1mb3Ita2V5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBwaWNrRWxlbWVudEZyb21TZXQgPSAoc2V0LCBwcmVkaWNhdGUpID0+IHtcbiAgICBjb25zdCBtYXRjaGluZ0VsZW1lbnRzID0gQXJyYXkuZnJvbShzZXQpLmZpbHRlcihwcmVkaWNhdGUpO1xuICAgIGlmIChtYXRjaGluZ0VsZW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ01vcmUgdGhhbiBvbmUgZWxlbWVudCB3YXMgZm91bmQuJyk7XG4gICAgfVxuICAgIGlmIChtYXRjaGluZ0VsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBFcnJvcignTm8gZWxlbWVudCB3YXMgZm91bmQuJyk7XG4gICAgfVxuICAgIGNvbnN0IFttYXRjaGluZ0VsZW1lbnRdID0gbWF0Y2hpbmdFbGVtZW50cztcbiAgICBzZXQuZGVsZXRlKG1hdGNoaW5nRWxlbWVudCk7XG4gICAgcmV0dXJuIG1hdGNoaW5nRWxlbWVudDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1waWNrLWVsZW1lbnQtZnJvbS1zZXQuanMubWFwIiwiaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmltcG9ydCB7IHBpY2tFbGVtZW50RnJvbVNldCB9IGZyb20gJy4vcGljay1lbGVtZW50LWZyb20tc2V0JztcbmV4cG9ydCBjb25zdCBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPSBnZXRWYWx1ZUZvcktleShwYXNzaXZlSW5wdXRzLCBzb3VyY2UpO1xuICAgIGNvbnN0IG1hdGNoaW5nQ29ubmVjdGlvbiA9IHBpY2tFbGVtZW50RnJvbVNldChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucywgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb24pID0+IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IG91dHB1dCAmJiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBpbnB1dCk7XG4gICAgaWYgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLnNpemUgPT09IDApIHtcbiAgICAgICAgcGFzc2l2ZUlucHV0cy5kZWxldGUoc291cmNlKTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoaW5nQ29ubmVjdGlvbjtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgRVZFTlRfTElTVEVORVJTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEVWRU5UX0xJU1RFTkVSUywgYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQUNUSVZFX0FVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3Qgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIGlmIChBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5oYXMoYXVkaW9Ob2RlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBBdWRpb05vZGUgaXMgYWxyZWFkeSBzdG9yZWQuJyk7XG4gICAgfVxuICAgIEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmFkZChhdWRpb05vZGUpO1xuICAgIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoYXVkaW9Ob2RlKS5mb3JFYWNoKChldmVudExpc3RlbmVyKSA9PiBldmVudExpc3RlbmVyKHRydWUpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0F1ZGlvV29ya2xldE5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdwb3J0JyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8td29ya2xldC1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFDVElWRV9BVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgaWYgKCFBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5oYXMoYXVkaW9Ob2RlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSBBdWRpb05vZGUgaXMgbm90IHN0b3JlZC4nKTtcbiAgICB9XG4gICAgQUNUSVZFX0FVRElPX05PREVfU1RPUkUuZGVsZXRlKGF1ZGlvTm9kZSk7XG4gICAgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShhdWRpb05vZGUpLmZvckVhY2goKGV2ZW50TGlzdGVuZXIpID0+IGV2ZW50TGlzdGVuZXIoZmFsc2UpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvV29ya2xldE5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbi8vIFNldCB0aGUgaW50ZXJuYWxTdGF0ZSBvZiB0aGUgYXVkaW9Ob2RlIHRvICdwYXNzaXZlJyBpZiBpdCBpcyBub3QgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBhbmQgaWYgaXQgaGFzIG5vICdhY3RpdmUnIGlucHV0IGNvbm5lY3Rpb25zLlxuZXhwb3J0IGNvbnN0IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5ID0gKGF1ZGlvTm9kZSwgYWN0aXZlSW5wdXRzKSA9PiB7XG4gICAgaWYgKCFpc0F1ZGlvV29ya2xldE5vZGUoYXVkaW9Ob2RlKSAmJiBhY3RpdmVJbnB1dHMuZXZlcnkoKGNvbm5lY3Rpb25zKSA9PiBjb25uZWN0aW9ucy5zaXplID09PSAwKSkge1xuICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKGF1ZGlvTm9kZSk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5LmpzLm1hcCIsImltcG9ydCB7IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUtd2hlbi1uZWNlc3NhcnknO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEF1ZGlvTm9kZVRhaWxUaW1lLCBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIGluc2VydEVsZW1lbnRJblNldCwgaXNBY3RpdmVBdWRpb05vZGUsIGlzUGFydE9mQUN5Y2xlLCBpc1Bhc3NpdmVBdWRpb05vZGUpID0+IHtcbiAgICBjb25zdCB0YWlsVGltZVRpbWVvdXRJZHMgPSBuZXcgV2Vha01hcCgpO1xuICAgIHJldHVybiAoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCwgaXNPZmZsaW5lKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzLCBwYXNzaXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhkZXN0aW5hdGlvbik7XG4gICAgICAgIGNvbnN0IHsgb3V0cHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoc291cmNlKTtcbiAgICAgICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50TGlzdGVuZXIgPSAoaXNBY3RpdmUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShzb3VyY2UpO1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbENvbm5lY3Rpb24gPSBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpc1Bhc3NpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbENvbm5lY3Rpb24gPSBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBwYXJ0aWFsQ29ubmVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCB0YWlsVGltZSA9IGdldEF1ZGlvTm9kZVRhaWxUaW1lKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICBpZiAodGFpbFRpbWUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkoZGVzdGluYXRpb24sIGFjdGl2ZUlucHV0cyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhaWxUaW1lVGltZW91dElkID0gdGFpbFRpbWVUaW1lb3V0SWRzLmdldChkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0YWlsVGltZVRpbWVvdXRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGFpbFRpbWVUaW1lb3V0SWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRhaWxUaW1lVGltZW91dElkcy5zZXQoZGVzdGluYXRpb24sIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5KGRlc3RpbmF0aW9uLCBhY3RpdmVJbnB1dHMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCB0YWlsVGltZSAqIDEwMDApKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGlmIChpbnNlcnRFbGVtZW50SW5TZXQob3V0cHV0cywgW2Rlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0XSwgKG91dHB1dENvbm5lY3Rpb24pID0+IG91dHB1dENvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmIG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCAmJiBvdXRwdXRDb25uZWN0aW9uWzJdID09PSBpbnB1dCwgdHJ1ZSkpIHtcbiAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJzLmFkZChldmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXSwgdHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUocGFzc2l2ZUlucHV0cywgaW5wdXQsIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKGluc2VydEVsZW1lbnRJblNldCkgPT4ge1xuICAgIHJldHVybiAocGFzc2l2ZUlucHV0cywgaW5wdXQsIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICAgICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPSBwYXNzaXZlSW5wdXRzLmdldChzb3VyY2UpO1xuICAgICAgICBpZiAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcGFzc2l2ZUlucHV0cy5zZXQoc291cmNlLCBuZXcgU2V0KFtbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl1dKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIFtvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXSwgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb24pID0+IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IG91dHB1dCAmJiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBpbnB1dCwgaWdub3JlRHVwbGljYXRlcyk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkU2lsZW50Q29ubmVjdGlvbiA9IChjcmVhdGVOYXRpdmVHYWluTm9kZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIGdhaW46IDBcbiAgICAgICAgfSk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0ID0gKCkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZGlzY29ubmVjdCk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuZGlzY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBuYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH07XG4gICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIGRpc2Nvbm5lY3QpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXNpbGVudC1jb25uZWN0aW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSA9IChnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGF1ZGlvV29ya2xldE5vZGUpID0+IHtcbiAgICAgICAgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKG5hdGl2ZUNvbnRleHQpLmFkZChhdWRpb1dvcmtsZXROb2RlKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBmZnRTaXplOiAyMDQ4LFxuICAgIG1heERlY2liZWxzOiAtMzAsXG4gICAgbWluRGVjaWJlbHM6IC0xMDAsXG4gICAgc21vb3RoaW5nVGltZUNvbnN0YW50OiAwLjhcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9uTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEFuYWx5c2VyTm9kZSBleHRlbmRzIGF1ZGlvbk5vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBbmFseXNlck5vZGUgPSBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBhbmFseXNlck5vZGVSZW5kZXJlciA9ICgoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpID8gY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVBbmFseXNlck5vZGUsIGFuYWx5c2VyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZSA9IG5hdGl2ZUFuYWx5c2VyTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZmZ0U2l6ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgZmZ0U2l6ZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZnJlcXVlbmN5QmluQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgICAgICB9XG4gICAgICAgIGdldCBtYXhEZWNpYmVscygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHM7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG1heERlY2liZWxzKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzExODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIG1heERlY2liZWxzIGlzIG5vdCBtb3JlIHRoYW4gbWluRGVjaWJlbHMuXG4gICAgICAgICAgICBjb25zdCBtYXhEZWNpYmVscyA9IHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscztcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKCEodmFsdWUgPiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzID0gbWF4RGVjaWJlbHM7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgbWluRGVjaWJlbHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzO1xuICAgICAgICB9XG4gICAgICAgIHNldCBtaW5EZWNpYmVscyh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxMTg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiBtYXhEZWNpYmVscyBpcyBub3QgbW9yZSB0aGFuIG1pbkRlY2liZWxzLlxuICAgICAgICAgICAgY29uc3QgbWluRGVjaWJlbHMgPSB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHM7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICghKHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyA+IHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscyA9IG1pbkRlY2liZWxzO1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHNtb290aGluZ1RpbWVDb25zdGFudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50O1xuICAgICAgICB9XG4gICAgICAgIHNldCBzbW9vdGhpbmdUaW1lQ29uc3RhbnQodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXRCeXRlRnJlcXVlbmN5RGF0YShhcnJheSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmdldEJ5dGVGcmVxdWVuY3lEYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBnZXRCeXRlVGltZURvbWFpbkRhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlVGltZURvbWFpbkRhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGdldEZsb2F0RnJlcXVlbmN5RGF0YShhcnJheSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmdldEZsb2F0RnJlcXVlbmN5RGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RmxvYXRUaW1lRG9tYWluRGF0YShhcnJheSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmdldEZsb2F0VGltZURvbWFpbkRhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hbmFseXNlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc093bmVkQnlDb250ZXh0ID0gKG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGUuY29udGV4dCA9PT0gbmF0aXZlQ29udGV4dDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1vd25lZC1ieS1jb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBbmFseXNlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBbmFseXNlck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUFuYWx5c2VyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUFuYWx5c2VyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUFuYWx5c2VyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUFuYWx5c2VyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUFuYWx5c2VyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUFuYWx5c2VyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUFuYWx5c2VyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGZmdFNpemU6IG5hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplLFxuICAgICAgICAgICAgICAgICAgICBtYXhEZWNpYmVsczogbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzLFxuICAgICAgICAgICAgICAgICAgICBtaW5EZWNpYmVsczogbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzLFxuICAgICAgICAgICAgICAgICAgICBzbW9vdGhpbmdUaW1lQ29uc3RhbnQ6IG5hdGl2ZUFuYWx5c2VyTm9kZS5zbW9vdGhpbmdUaW1lQ29uc3RhbnRcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUFuYWx5c2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBbmFseXNlck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUFuYWx5c2VyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlID0gcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUFuYWx5c2VyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hbmFseXNlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCA9IChuYXRpdmVBdWRpb0J1ZmZlcikgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwobmV3IEZsb2F0MzJBcnJheSgxKSwgMCwgLTEpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJbmRleFNpemVFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdJbmRleFNpemVFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXgtc2l6ZS1lcnJvci5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbmRleFNpemVFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbmRleC1zaXplLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZCA9IChhdWRpb0J1ZmZlcikgPT4ge1xuICAgIGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhID0gKChnZXRDaGFubmVsRGF0YSkgPT4ge1xuICAgICAgICByZXR1cm4gKGNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldENoYW5uZWxEYXRhLmNhbGwoYXVkaW9CdWZmZXIsIGNoYW5uZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZC5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIG51bWJlck9mQ2hhbm5lbHM6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9IChhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHRlc3ROYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcykgPT4ge1xuICAgIGxldCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbnVsbDtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9CdWZmZXIge1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcigxLCAxLCA0NDEwMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5OTogRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIE5vdFN1cHBvcnRlZEVycm9yIHdoZW4gdGhlIG51bWJlck9mQ2hhbm5lbHMgaXMgemVyby4gQnV0IGl0IG9ubHkgZG9lcyBpdCB3aGVuIHVzaW5nIHRoZVxuICAgICAgICAgICAgICogZmFjdG9yeSBmdW5jdGlvbi4gQnV0IHNpbmNlIEZpcmVmb3ggYWxzbyBzdXBwb3J0cyB0aGUgY29uc3RydWN0b3IgZXZlcnl0aGluZyBzaG91bGQgYmUgZmluZS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgY2FjaGVUZXN0UmVzdWx0KHRlc3ROYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydCwgdGVzdE5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0KVxuICAgICAgICAgICAgICAgID8gbmV3IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSlcbiAgICAgICAgICAgICAgICA6IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzk5OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiB0aGUgbnVtYmVyT2ZDaGFubmVscyBpcyB6ZXJvLlxuICAgICAgICAgICAgaWYgKGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICAgICAgLy8gQnVnICMxMDA6IFNhZmFyaSBkb2VzIHRocm93IGEgd3JvbmcgZXJyb3Igd2hlbiBjYWxsaW5nIGdldENoYW5uZWxEYXRhKCkgd2l0aCBhbiBvdXQtb2YtYm91bmRzIHZhbHVlLlxuICAgICAgICAgICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE1NzogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0aGUgYnVmZmVyT2Zmc2V0IHRvIGJlIG91dC1vZi1ib3VuZHMuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0KGF1ZGlvQnVmZmVyKSkpIHtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogVGhpcyBkb2VzIHZpb2xhdGUgYWxsIGdvb2QgcHJhdGljZXMgYnV0IGl0IGlzIG5lY2Vzc2FyeSB0byBhbGxvdyB0aGlzIEF1ZGlvQnVmZmVyIHRvIGJlIHVzZWQgd2l0aCBuYXRpdmVcbiAgICAgICAgICAgICAqIChPZmZsaW5lKUF1ZGlvQ29udGV4dHMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0oaW5zdGFuY2UpIHtcbiAgICAgICAgICAgIHJldHVybiAoKGluc3RhbmNlICE9PSBudWxsICYmIHR5cGVvZiBpbnN0YW5jZSA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKGluc3RhbmNlKSA9PT0gQXVkaW9CdWZmZXIucHJvdG90eXBlKSB8fFxuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuaGFzKGluc3RhbmNlKSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQgPSAtMy40MDI4MjM0NjYzODUyODg2ZTM4O1xuZXhwb3J0IGNvbnN0IE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUID0gLU1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnRzLmpzLm1hcCIsImltcG9ydCB7IEFDVElWRV9BVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgaXNBY3RpdmVBdWRpb05vZGUgPSAoYXVkaW9Ob2RlKSA9PiBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5oYXMoYXVkaW9Ob2RlKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFjdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBidWZmZXI6IG51bGwsXG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICBsb29wOiBmYWxzZSxcbiAgICBsb29wRW5kOiAwLFxuICAgIGxvb3BTdGFydDogMCxcbiAgICBwbGF5YmFja1JhdGU6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvQnVmZmVyU291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyID0gKChpc09mZmxpbmUgPyBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgPSBhdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlclNldCA9IG1lcmdlZE9wdGlvbnMuYnVmZmVyICE9PSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgICAgICAvLyBCdWcgIzczOiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0J1ZmZlck51bGxpZmllZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGJ1ZmZlcih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IHZhbHVlO1xuICAgICAgICAgICAgLy8gQnVnICM3MjogT25seSBDaHJvbWUgJiBFZGdlIGRvIG5vdCBhbGxvdyB0byByZWFzc2lnbiB0aGUgYnVmZmVyIHlldC5cbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9pc0J1ZmZlclNldCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlclNldCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3A7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGxvb3AodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BFbmQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGxvb3BFbmQodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wRW5kID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wU3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wU3RhcnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25lbmRlZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbmVuZGVkKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLm9uZW5kZWQgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPbkVuZGVkID0gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbmF0aXZlT25FbmRlZCAhPT0gbnVsbCAmJiBuYXRpdmVPbkVuZGVkID09PSB3cmFwcGVkTGlzdGVuZXIgPyB2YWx1ZSA6IG5hdGl2ZU9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnQod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQod2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlci5zdGFydCA9IGR1cmF0aW9uID09PSB1bmRlZmluZWQgPyBbd2hlbiwgb2Zmc2V0XSA6IFt3aGVuLCBvZmZzZXQsIGR1cmF0aW9uXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKHdoZW4pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIuc3RvcCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICAgICAgICAgICAgICAgICAgbG9vcDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BFbmQ6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wRW5kLFxuICAgICAgICAgICAgICAgICAgICBsb29wU3RhcnQ6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wU3RhcnQsXG4gICAgICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnBsYXliYWNrUmF0ZS52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoLi4uc3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3RvcCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcChzdG9wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBsYXliYWNrUmF0ZSwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnBsYXliYWNrUmF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wbGF5YmFja1JhdGUsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2V0IHN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RvcCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0b3AgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAncGxheWJhY2tSYXRlJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0JpcXVhZEZpbHRlck5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdmcmVxdWVuY3knIGluIGF1ZGlvTm9kZSAmJiAnZ2FpbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpcXVhZC1maWx0ZXItbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNDb25zdGFudFNvdXJjZU5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdvZmZzZXQnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNHYWluTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gISgnZnJlcXVlbmN5JyBpbiBhdWRpb05vZGUpICYmICdnYWluJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2Fpbi1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc09zY2lsbGF0b3JOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnZGV0dW5lJyBpbiBhdWRpb05vZGUgJiYgJ2ZyZXF1ZW5jeScgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW9zY2lsbGF0b3Itbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNTdGVyZW9QYW5uZXJOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAncGFuJyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RlcmVvLXBhbm5lci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX05PREVfQ09OTkVDVElPTlNfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX05PREVfQ09OTkVDVElPTlNfU1RPUkUsIGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gKGF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUsIGF1ZGlvUGFyYW0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvQnVmZmVyU291cmNlTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgaXNBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBpc0JpcXVhZEZpbHRlck5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYmlxdWFkLWZpbHRlci1ub2RlJztcbmltcG9ydCB7IGlzQ29uc3RhbnRTb3VyY2VOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2NvbnN0YW50LXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGlzR2Fpbk5vZGUgfSBmcm9tICcuLi9ndWFyZHMvZ2Fpbi1ub2RlJztcbmltcG9ydCB7IGlzT3NjaWxsYXRvck5vZGUgfSBmcm9tICcuLi9ndWFyZHMvb3NjaWxsYXRvci1ub2RlJztcbmltcG9ydCB7IGlzU3RlcmVvUGFubmVyTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9zdGVyZW8tcGFubmVyLW5vZGUnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyB9IGZyb20gJy4vZ2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5leHBvcnQgY29uc3QgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMgPSAoYXVkaW9Ob2RlLCB0cmFjZSkgPT4ge1xuICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhhdWRpb05vZGUpO1xuICAgIGFjdGl2ZUlucHV0cy5mb3JFYWNoKChjb25uZWN0aW9ucykgPT4gY29ubmVjdGlvbnMuZm9yRWFjaCgoW3NvdXJjZV0pID0+IHtcbiAgICAgICAgaWYgKCF0cmFjZS5pbmNsdWRlcyhhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyhzb3VyY2UsIFsuLi50cmFjZSwgYXVkaW9Ob2RlXSk7XG4gICAgICAgIH1cbiAgICB9KSk7XG4gICAgY29uc3QgYXVkaW9QYXJhbXMgPSBpc0F1ZGlvQnVmZmVyU291cmNlTm9kZShhdWRpb05vZGUpXG4gICAgICAgID8gW1xuICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICBhdWRpb05vZGUucGxheWJhY2tSYXRlXG4gICAgICAgIF1cbiAgICAgICAgOiBpc0F1ZGlvV29ya2xldE5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgPyBBcnJheS5mcm9tKGF1ZGlvTm9kZS5wYXJhbWV0ZXJzLnZhbHVlcygpKVxuICAgICAgICAgICAgOiBpc0JpcXVhZEZpbHRlck5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5RLCBhdWRpb05vZGUuZGV0dW5lLCBhdWRpb05vZGUuZnJlcXVlbmN5LCBhdWRpb05vZGUuZ2Fpbl1cbiAgICAgICAgICAgICAgICA6IGlzQ29uc3RhbnRTb3VyY2VOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLm9mZnNldF1cbiAgICAgICAgICAgICAgICAgICAgOiBpc0dhaW5Ob2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5nYWluXVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBpc09zY2lsbGF0b3JOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuZGV0dW5lLCBhdWRpb05vZGUuZnJlcXVlbmN5XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogaXNTdGVyZW9QYW5uZXJOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLnBhbl1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBbXTtcbiAgICBmb3IgKGNvbnN0IGF1ZGlvUGFyYW0gb2YgYXVkaW9QYXJhbXMpIHtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0pO1xuICAgICAgICBpZiAoYXVkaW9QYXJhbUNvbm5lY3Rpb25zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5hY3RpdmVJbnB1dHMuZm9yRWFjaCgoW3NvdXJjZV0pID0+IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zKHNvdXJjZSwgdHJhY2UpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKSkge1xuICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKGF1ZGlvTm9kZSk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlYWN0aXZhdGUtYWN0aXZlLWF1ZGlvLW5vZGUtaW5wdXQtY29ubmVjdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMgfSBmcm9tICcuL2RlYWN0aXZhdGUtYWN0aXZlLWF1ZGlvLW5vZGUtaW5wdXQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVBdWRpb0dyYXBoID0gKGNvbnRleHQpID0+IHtcbiAgICBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyhjb250ZXh0LmRlc3RpbmF0aW9uLCBbXSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVhY3RpdmF0ZS1hdWRpby1ncmFwaC5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNWYWxpZExhdGVuY3lIaW50ID0gKGxhdGVuY3lIaW50KSA9PiB7XG4gICAgcmV0dXJuIChsYXRlbmN5SGludCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHR5cGVvZiBsYXRlbmN5SGludCA9PT0gJ251bWJlcicgfHxcbiAgICAgICAgKHR5cGVvZiBsYXRlbmN5SGludCA9PT0gJ3N0cmluZycgJiYgKGxhdGVuY3lIaW50ID09PSAnYmFsYW5jZWQnIHx8IGxhdGVuY3lIaW50ID09PSAnaW50ZXJhY3RpdmUnIHx8IGxhdGVuY3lIaW50ID09PSAncGxheWJhY2snKSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXZhbGlkLWxhdGVuY3ktaGludC5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQXVkaW9HcmFwaCB9IGZyb20gJy4uL2hlbHBlcnMvZGVhY3RpdmF0ZS1hdWRpby1ncmFwaCc7XG5pbXBvcnQgeyBpc1ZhbGlkTGF0ZW5jeUhpbnQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXZhbGlkLWxhdGVuY3ktaGludCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0NvbnRleHQgZXh0ZW5kcyBiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MiBTYWZhcmkgZG9lcyB0aHJvdyBhIFN5bnRheEVycm9yIGlmIHRoZSBzYW1wbGVSYXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMiAmJiBlcnIubWVzc2FnZSA9PT0gJ3NhbXBsZVJhdGUgaXMgbm90IGluIHJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzEzMSBTYWZhcmkgcmV0dXJucyBudWxsIHdoZW4gdGhlcmUgYXJlIGZvdXIgb3RoZXIgQXVkaW9Db250ZXh0cyBydW5uaW5nIGFscmVhZHkuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlVW5rbm93bkVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzUxIE9ubHkgQ2hyb21lIGFuZCBFZGdlIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiBsYXRlbmN5SGludCBpcyBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgcHJvdmlkZWQgdmFsdWUgJyR7b3B0aW9ucy5sYXRlbmN5SGludH0nIGlzIG5vdCBhIHZhbGlkIGVudW0gdmFsdWUgb2YgdHlwZSBBdWRpb0NvbnRleHRMYXRlbmN5Q2F0ZWdvcnkuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE1MCBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBzZXR0aW5nIHRoZSBzYW1wbGVSYXRlLlxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2FtcGxlUmF0ZSAhPT0gdW5kZWZpbmVkICYmIG5hdGl2ZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlICE9PSBvcHRpb25zLnNhbXBsZVJhdGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlQXVkaW9Db250ZXh0LCAyKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbGF0ZW5jeUhpbnQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHNhbXBsZVJhdGUgfSA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEB0b2RvIFRoZSB2YWx1ZXMgZm9yICdiYWxhbmNlZCcsICdpbnRlcmFjdGl2ZScgYW5kICdwbGF5YmFjaycgYXJlIGp1c3QgY29waWVkIGZyb20gQ2hyb21lJ3MgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgICB0aGlzLl9iYXNlTGF0ZW5jeSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeSA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICAgICAgPyBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3lcbiAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyA1MTIgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnaW50ZXJhY3RpdmUnIHx8IGxhdGVuY3lIaW50ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDI1NiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAncGxheWJhY2snXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMTAyNCAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAvKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEB0b2RvIFRoZSBtaW4gKDI1NikgYW5kIG1heCAoMTYzODQpIHZhbHVlcyBhcmUgdGFrZW4gZnJvbSB0aGUgYWxsb3dlZCBidWZmZXJTaXplIHZhbHVlcyBvZiBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogU2NyaXB0UHJvY2Vzc29yTm9kZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNYXRoLm1heCgyLCBNYXRoLm1pbigxMjgsIE1hdGgucm91bmQoKGxhdGVuY3lIaW50ICogc2FtcGxlUmF0ZSkgLyAxMjgpKSkgKiAxMjgpIC8gc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg4OiBTYWZhcmkgd2lsbCBzZXQgdGhlIGNvbnRleHQncyBzdGF0ZSB0byAnaW50ZXJydXB0ZWQnIGluIGNhc2UgdGhlIHVzZXIgc3dpdGNoZXMgdGFicy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZ2Fpbi52YWx1ZSA9IDFlLTM3O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmNvbm5lY3QodGhpcy5fbmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzM0OiBDaHJvbWUgYW5kIEVkZ2UgcHJldGVuZCB0byBiZSBydW5uaW5nIHJpZ2h0IGF3YXksIGJ1dCBmaXJlIGFuIG9uc3RhdGVjaGFuZ2UgZXZlbnQgd2hlbiB0aGUgc3RhdGUgYWN0dWFsbHkgY2hhbmdlc1xuICAgICAgICAgICAgICogdG8gJ3J1bm5pbmcnLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdzdXNwZW5kZWQnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJldm9rZVN0YXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBiYXNlTGF0ZW5jeSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9iYXNlTGF0ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgIT09IG51bGwgPyB0aGlzLl9zdGF0ZSA6IHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBjbG9zZSgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMzU6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIEF1ZGlvQ29udGV4dCB3YXMgY2xvc2VkIGJlZm9yZS5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMzQ6IElmIHRoZSBzdGF0ZSB3YXMgc2V0IHRvIHN1c3BlbmRlZCBiZWZvcmUgaXQgc2hvdWxkIGJlIHJldm9rZWQgbm93LlxuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlR2Fpbk5vZGUgIT09IG51bGwgJiYgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUF1ZGlvR3JhcGgodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UobWVkaWFFbGVtZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWVkaWFFbGVtZW50IH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShtZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWVkaWFTdHJlYW0gfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFTdHJlYW1UcmFja1NvdXJjZShtZWRpYVN0cmVhbVRyYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhU3RyZWFtVHJhY2sgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdW1lKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc29sdmVQcm9taXNlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXN1bWUoKS50aGVuKHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVzdW1lKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTU6IENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3IgaW5zdGVhZCBvZiBhbiBJbnZhbGlkU3RhdGVFcnJvci5cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQgfHwgZXJyLmNvZGUgPT09IDE1KSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHN1c3BlbmQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN1c3BlbmQoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvRGVzdGluYXRpb25Ob2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZShuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyID0gKChpc09mZmxpbmUgPyBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyKHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSwgYXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9pc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBpc09mZmxpbmU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNTI6IENocm9tZSwgRWRnZSAmIFNhZmFyaSBkbyBub3QgdGhyb3cgYW4gZXhjZXB0aW9uIGF0IGFsbC5cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTQ6IEZpcmVmb3ggZG9lcyB0aHJvdyBhbiBJbmRleFNpemVFcnJvci5cbiAgICAgICAgICAgIGlmICh0aGlzLl9pc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM0NzogVGhlIEF1ZGlvRGVzdGluYXRpb25Ob2RlIGluIFNhZmFyaSBkb2VzIG5vdCBpbml0aWFsaXplIHRoZSBtYXhDaGFubmVsQ291bnQgcHJvcGVydHkgY29ycmVjdGx5LlxuICAgICAgICAgICAgaWYgKHZhbHVlID4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNTM6IE5vIGJyb3dzZXIgZG9lcyB0aHJvdyBhbiBleGNlcHRpb24geWV0LlxuICAgICAgICAgICAgaWYgKHRoaXMuX2lzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1heENoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIgPSAocmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgY29uc3QgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUpO1xuICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvTGlzdGVuZXJGYWN0b3J5ID0gKGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXRGaXJzdFNhbXBsZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKGNvbnRleHQsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlTGlzdGVuZXIgPSBuYXRpdmVDb250ZXh0Lmxpc3RlbmVyO1xuICAgICAgICAvLyBCdWcgIzExNzogT25seSBDaHJvbWUgJiBFZGdlIHN1cHBvcnQgdGhlIG5ldyBpbnRlcmZhY2UgYWxyZWFkeS5cbiAgICAgICAgY29uc3QgY3JlYXRlRmFrZUF1ZGlvUGFyYW1zID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheSgxKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogOVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBsZXQgaXNTY3JpcHRQcm9jZXNzb3JOb2RlQ3JlYXRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgbGV0IGxhc3RPcmllbnRhdGlvbiA9IFswLCAwLCAtMSwgMCwgMSwgMF07XG4gICAgICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gWzAsIDAsIDBdO1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoaXNTY3JpcHRQcm9jZXNzb3JOb2RlQ3JlYXRlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZUNvbnRleHQsIDI1NiwgOSwgMCk7XG4gICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZW50YXRpb24gPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAwKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMiksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNSlcbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVMaXN0ZW5lci5zZXRPcmllbnRhdGlvbiguLi5vcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0b24gPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA2KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDcpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgOClcbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0b24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUxpc3RlbmVyLnNldFBvc2l0aW9uKC4uLnBvc2l0b24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3NpdG9uO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZVNldE9yaWVudGF0aW9uID0gKGluZGV4KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pIHtcbiAgICAgICAgICAgICAgICAgICAgbGFzdE9yaWVudGF0aW9uW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVMaXN0ZW5lci5zZXRPcmllbnRhdGlvbiguLi5sYXN0T3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZVNldFBvc2l0aW9uID0gKGluZGV4KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pIHtcbiAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uW2luZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVMaXN0ZW5lci5zZXRQb3NpdGlvbiguLi5sYXN0UG9zaXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZUZha2VBdWRpb1BhcmFtID0gKGlucHV0LCBpbml0aWFsVmFsdWUsIHNldFZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogaW5pdGlhbFZhbHVlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGlzIHNob3VsZCBiZSBzdG9wcGVkIHdoZW4gdGhlIGNvbnRleHQgaXMgY2xvc2VkLlxuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdGFydCgpO1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCAnZGVmYXVsdFZhbHVlJywge1xuICAgICAgICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5pdGlhbFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzYyICYgIzc0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBDb25zdGFudFNvdXJjZU5vZGVzIGFuZCBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmRcbiAgICAgICAgICAgICAgICAgKiBtaW5WYWx1ZSBmb3IgR2Fpbk5vZGVzLlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtKHsgY29udGV4dCB9LCBpc09mZmxpbmUsIGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKGF1ZGlvUGFyYW0sICd2YWx1ZScsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGF1ZGlvUGFyYW0pLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldC5jYWxsKGF1ZGlvUGFyYW0sIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgIT09IDkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzExNzogVXNpbmcgc2V0T3JpZW50YXRpb24oKSBhbmQgc2V0UG9zaXRpb24oKSBkb2Vzbid0IHdvcmsgd2l0aCBhbiBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmFsdWUodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lID0gKChjYW5jZWxBbmRIb2xkQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNhbmNlbEFuZEhvbGRBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyA9ICgoY2FuY2VsU2NoZWR1bGVkVmFsdWVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNhbmNlbFNjaGVkdWxlZFZhbHVlcy5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lID0gKChleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lID0gKChsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKTtcbiAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFRhcmdldEF0VGltZSA9ICgoc2V0VGFyZ2V0QXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHNldFRhcmdldEF0VGltZS5hcHBseShhdWRpb1BhcmFtLCBhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShhdWRpb1BhcmFtLnNldFRhcmdldEF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSA9ICgoc2V0VmFsdWVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc2V0VmFsdWVBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lID0gKChzZXRWYWx1ZUN1cnZlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHNldFZhbHVlQ3VydmVBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGZvcndhcmRYOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgwLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigwKSksXG4gICAgICAgICAgICAgICAgZm9yd2FyZFk6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDEsIDAsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDEpKSxcbiAgICAgICAgICAgICAgICBmb3J3YXJkWjogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMiwgLTEsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDIpKSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvblg6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDYsIDAsIGNyZWF0ZVNldFBvc2l0aW9uKDApKSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvblk6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDcsIDAsIGNyZWF0ZVNldFBvc2l0aW9uKDEpKSxcbiAgICAgICAgICAgICAgICBwb3NpdGlvblo6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDgsIDAsIGNyZWF0ZVNldFBvc2l0aW9uKDIpKSxcbiAgICAgICAgICAgICAgICB1cFg6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDMsIDAsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDMpKSxcbiAgICAgICAgICAgICAgICB1cFk6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDQsIDEsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDQpKSxcbiAgICAgICAgICAgICAgICB1cFo6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDUsIDAsIGNyZWF0ZVNldE9yaWVudGF0aW9uKDUpKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgeyBmb3J3YXJkWCwgZm9yd2FyZFksIGZvcndhcmRaLCBwb3NpdGlvblgsIHBvc2l0aW9uWSwgcG9zaXRpb25aLCB1cFgsIHVwWSwgdXBaIH0gPSBuYXRpdmVMaXN0ZW5lci5mb3J3YXJkWCA9PT0gdW5kZWZpbmVkID8gY3JlYXRlRmFrZUF1ZGlvUGFyYW1zKCkgOiBuYXRpdmVMaXN0ZW5lcjtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGdldCBmb3J3YXJkWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZFg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGZvcndhcmRZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3J3YXJkWTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgZm9yd2FyZFooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcndhcmRaO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25aO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB1cFgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVwWDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdXBZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1cFk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHVwWigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBaO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tbGlzdGVuZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNBdWRpb05vZGUgPSAoYXVkaW9Ob2RlT3JBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuICdjb250ZXh0JyBpbiBhdWRpb05vZGVPckF1ZGlvUGFyYW07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZSB9IGZyb20gJy4vYXVkaW8tbm9kZSc7XG5leHBvcnQgY29uc3QgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uID0gKG91dHB1dENvbm5lY3Rpb24pID0+IHtcbiAgICByZXR1cm4gaXNBdWRpb05vZGUob3V0cHV0Q29ubmVjdGlvblswXSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgaW5zZXJ0RWxlbWVudEluU2V0ID0gKHNldCwgZWxlbWVudCwgcHJlZGljYXRlLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgZm9yIChjb25zdCBsbW50IG9mIHNldCkge1xuICAgICAgICBpZiAocHJlZGljYXRlKGxtbnQpKSB7XG4gICAgICAgICAgICBpZiAoaWdub3JlRHVwbGljYXRlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IEVycm9yKCdUaGUgc2V0IGNvbnRhaW5zIGF0IGxlYXN0IG9uZSBzaW1pbGFyIGVsZW1lbnQuJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0LmFkZChlbGVtZW50KTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnNlcnQtZWxlbWVudC1pbi1zZXQuanMubWFwIiwiaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi9pbnNlcnQtZWxlbWVudC1pbi1zZXQnO1xuZXhwb3J0IGNvbnN0IGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICBpbnNlcnRFbGVtZW50SW5TZXQoYWN0aXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCAoYWN0aXZlSW5wdXRDb25uZWN0aW9uKSA9PiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IHNvdXJjZSAmJiBhY3RpdmVJbnB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCwgaWdub3JlRHVwbGljYXRlcyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4vaW5zZXJ0LWVsZW1lbnQtaW4tc2V0JztcbmV4cG9ydCBjb25zdCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gKHBhc3NpdmVJbnB1dHMsIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIGlnbm9yZUR1cGxpY2F0ZXMpID0+IHtcbiAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9IHBhc3NpdmVJbnB1dHMuZ2V0KHNvdXJjZSk7XG4gICAgaWYgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcGFzc2l2ZUlucHV0cy5zZXQoc291cmNlLCBuZXcgU2V0KFtbb3V0cHV0LCBldmVudExpc3RlbmVyXV0pKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGluc2VydEVsZW1lbnRJblNldChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucywgW291dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyID0gKG5hdGl2ZUF1ZGlvTm9kZU9yTmF0aXZlQXVkaW9Ob2RlRmFrZXIpID0+IHtcbiAgICByZXR1cm4gJ2lucHV0cycgaW4gbmF0aXZlQXVkaW9Ob2RlT3JOYXRpdmVBdWRpb05vZGVGYWtlcjtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tbm9kZS1mYWtlci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmV4cG9ydCBjb25zdCBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUgPSAobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlKSkge1xuICAgICAgICBjb25zdCBmYWtlTmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZS5pbnB1dHNbaW5wdXRdO1xuICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuY29ubmVjdChmYWtlTmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgMCk7XG4gICAgICAgIHJldHVybiBbZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIDBdO1xuICAgIH1cbiAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgcmV0dXJuIFtuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dF07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS10by1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uID0gKGFjdGl2ZUlucHV0Q29ubmVjdGlvbnMsIHNvdXJjZSwgb3V0cHV0KSA9PiB7XG4gICAgZm9yIChjb25zdCBhY3RpdmVJbnB1dENvbm5lY3Rpb24gb2YgYWN0aXZlSW5wdXRDb25uZWN0aW9ucykge1xuICAgICAgICBpZiAoYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQpIHtcbiAgICAgICAgICAgIGFjdGl2ZUlucHV0Q29ubmVjdGlvbnMuZGVsZXRlKGFjdGl2ZUlucHV0Q29ubmVjdGlvbik7XG4gICAgICAgICAgICByZXR1cm4gYWN0aXZlSW5wdXRDb25uZWN0aW9uO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gKGFjdGl2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpID0+IHtcbiAgICByZXR1cm4gcGlja0VsZW1lbnRGcm9tU2V0KGFjdGl2ZUlucHV0cywgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZUV2ZW50TGlzdGVuZXJPZkF1ZGlvTm9kZSA9IChhdWRpb05vZGUsIGV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICBjb25zdCBldmVudExpc3RlbmVycyA9IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoYXVkaW9Ob2RlKTtcbiAgICBpZiAoIWV2ZW50TGlzdGVuZXJzLmRlbGV0ZShldmVudExpc3RlbmVyKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIGV4cGVjdGVkIGV2ZW50IGxpc3RlbmVyLicpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmltcG9ydCB7IHBpY2tFbGVtZW50RnJvbVNldCB9IGZyb20gJy4vcGljay1lbGVtZW50LWZyb20tc2V0JztcbmV4cG9ydCBjb25zdCBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPSBnZXRWYWx1ZUZvcktleShwYXNzaXZlSW5wdXRzLCBzb3VyY2UpO1xuICAgIGNvbnN0IG1hdGNoaW5nQ29ubmVjdGlvbiA9IHBpY2tFbGVtZW50RnJvbVNldChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucywgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb24pID0+IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25bMF0gPT09IG91dHB1dCk7XG4gICAgaWYgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLnNpemUgPT09IDApIHtcbiAgICAgICAgcGFzc2l2ZUlucHV0cy5kZWxldGUoc291cmNlKTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoaW5nQ29ubmVjdGlvbjtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuZXhwb3J0IGNvbnN0IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSkpIHtcbiAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUuaW5wdXRzW2lucHV0XSwgb3V0cHV0LCAwKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGlzY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS1mcm9tLW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX05PREVfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0TmF0aXZlQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19OT0RFX1NUT1JFLCBhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19QQVJBTV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXROYXRpdmVBdWRpb1BhcmFtID0gKGF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fUEFSQU1fU1RPUkUsIGF1ZGlvUGFyYW0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1uYXRpdmUtYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgQ1lDTEVfQ09VTlRFUlMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmV4cG9ydCBjb25zdCBpc1BhcnRPZkFDeWNsZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gQ1lDTEVfQ09VTlRFUlMuaGFzKGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtcGFydC1vZi1hLWN5Y2xlLmpzLm1hcCIsImltcG9ydCB7IEFDVElWRV9BVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgaXNQYXNzaXZlQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAhQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtcGFzc2l2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZFN1cHBvcnQgPSAobmF0aXZlQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgLypcbiAgICAgICAgICogVGhpcyBidWcgZXhpc3RlZCBpbiBTYWZhcmkgdXAgdW50aWwgdjE0LjAuMi4gU2luY2UgQXVkaW9Xb3JrbGV0cyB3ZXJlIG5vdCBzdXBwb3J0ZWQgaW4gU2FmYXJpIHVudGlsIHYxNC4xIHRoZSBwcmVzZW5jZSBvZiB0aGVcbiAgICAgICAgICogY29uc3RydWN0b3IgZm9yIGFuIEF1ZGlvV29ya2xldE5vZGUgY2FuIGJlIHVzZWQgaGVyZSB0byBza2lwIHRoZSB0ZXN0LlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGFuYWx5emVyID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZVNjcmlwdFByb2Nlc3NvcigyNTYsIDEsIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lIGRlcHJlY2F0aW9uXG4gICAgICAgICAgICBjb25zdCBkdW1teSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAvLyBCdWcgIzk1OiBTYWZhcmkgZG9lcyBub3QgcGxheSBvbmUgc2FtcGxlIGJ1ZmZlcnMuXG4gICAgICAgICAgICBjb25zdCBvbmVzID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAyLCA0NDEwMCk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IG9uZXMuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgICAgICBjaGFubmVsRGF0YVswXSA9IDE7XG4gICAgICAgICAgICBjaGFubmVsRGF0YVsxXSA9IDE7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgICAgICBzb3VyY2UuYnVmZmVyID0gb25lcztcbiAgICAgICAgICAgIHNvdXJjZS5sb29wID0gdHJ1ZTtcbiAgICAgICAgICAgIHNvdXJjZS5jb25uZWN0KGFuYWx5emVyKS5jb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBzb3VyY2UuY29ubmVjdChkdW1teSk7XG4gICAgICAgICAgICBzb3VyY2UuZGlzY29ubmVjdChkdW1teSk7XG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgIGFuYWx5emVyLm9uYXVkaW9wcm9jZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hubmxEdCA9IGV2ZW50LmlucHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKDApOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lIGRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LnByb3RvdHlwZS5zb21lLmNhbGwoY2hubmxEdCwgKHNhbXBsZSkgPT4gc2FtcGxlID09PSAxKSkge1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNvdXJjZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgYW5hbHl6ZXIub25hdWRpb3Byb2Nlc3MgPSBudWxsOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgc291cmNlLmRpc2Nvbm5lY3QoYW5hbHl6ZXIpO1xuICAgICAgICAgICAgICAgIGFuYWx5emVyLmRpc2Nvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQoKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB2aXNpdEVhY2hBdWRpb05vZGVPbmNlID0gKGN5Y2xlcywgdmlzaXRvcikgPT4ge1xuICAgIGNvbnN0IGNvdW50cyA9IG5ldyBNYXAoKTtcbiAgICBmb3IgKGNvbnN0IGN5Y2xlIG9mIGN5Y2xlcykge1xuICAgICAgICBmb3IgKGNvbnN0IGF1ZGlvTm9kZSBvZiBjeWNsZSkge1xuICAgICAgICAgICAgY29uc3QgY291bnQgPSBjb3VudHMuZ2V0KGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBjb3VudHMuc2V0KGF1ZGlvTm9kZSwgY291bnQgPT09IHVuZGVmaW5lZCA/IDEgOiBjb3VudCArIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvdW50cy5mb3JFYWNoKChjb3VudCwgYXVkaW9Ob2RlKSA9PiB2aXNpdG9yKGF1ZGlvTm9kZSwgY291bnQpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD12aXNpdC1lYWNoLWF1ZGlvLW5vZGUtb25jZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNOYXRpdmVBdWRpb05vZGUgPSAobmF0aXZlQXVkaW9Ob2RlT3JBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuICdjb250ZXh0JyBpbiBuYXRpdmVBdWRpb05vZGVPckF1ZGlvUGFyYW07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kID0gKG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IE1hcCgpO1xuICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0ID0gKChjb25uZWN0KSA9PiB7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTppbnZhbGlkLXZvaWQgbm8taW5mZXJyYWJsZS10eXBlc1xuICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJldHVyblZhbHVlID0gaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pID8gY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCkgOiBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXQpO1xuICAgICAgICAgICAgLy8gU2F2ZSB0aGUgbmV3IGNvbm5lY3Rpb24gb25seSBpZiB0aGUgY2FsbHMgdG8gY29ubmVjdCBhYm92ZSBkaWRuJ3QgdGhyb3cgYW4gZXJyb3IuXG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24gPSBjb25uZWN0aW9ucy5nZXQoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuc2V0KGRlc3RpbmF0aW9uLCBbeyBpbnB1dCwgb3V0cHV0IH1dKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZXZlcnkoKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb24uaW5wdXQgIT09IGlucHV0IHx8IGNvbm5lY3Rpb24ub3V0cHV0ICE9PSBvdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5wdXNoKHsgaW5wdXQsIG91dHB1dCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QuYmluZChuYXRpdmVBdWRpb05vZGUpKTtcbiAgICBuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCA9ICgoZGlzY29ubmVjdCkgPT4ge1xuICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICAgICAgICAgIGRpc2Nvbm5lY3QuYXBwbHkobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5jbGVhcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbZGVzdGluYXRpb24sIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbl0gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyZWRDb25uZWN0aW9ucyA9IGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5maWx0ZXIoKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb24ub3V0cHV0ICE9PSBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcmVkQ29ubmVjdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuc2V0KGRlc3RpbmF0aW9uLCBmaWx0ZXJlZENvbm5lY3Rpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvbm5lY3Rpb25zLmhhcyhkZXN0aW5hdGlvbk9yT3V0cHV0KSkge1xuICAgICAgICAgICAgICAgIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24gPSBjb25uZWN0aW9ucy5nZXQoZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjb25uZWN0aW9uc1RvRGVzdGluYXRpb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlsdGVyZWRDb25uZWN0aW9ucyA9IGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5maWx0ZXIoKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb24ub3V0cHV0ICE9PSBvdXRwdXQgJiYgKGNvbm5lY3Rpb24uaW5wdXQgIT09IGlucHV0IHx8IGlucHV0ID09PSB1bmRlZmluZWQpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZENvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbk9yT3V0cHV0LCBmaWx0ZXJlZENvbm5lY3Rpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAoY29uc3QgW2Rlc3RpbmF0aW9uLCBjb25uZWN0aW9uc1RvRGVzdGluYXRpb25dIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmZvckVhY2goKGNvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QoZGVzdGluYXRpb24sIGNvbm5lY3Rpb24ub3V0cHV0LCBjb25uZWN0aW9uLmlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KGRlc3RpbmF0aW9uLCBjb25uZWN0aW9uLm91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX05PREVfU1RPUkUsIEVWRU5UX0xJU1RFTkVSUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgaXNBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2FkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS10by1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb24gfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kaXNjb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLWZyb20tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1ldmVudC1saXN0ZW5lcnMtb2YtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4uL2hlbHBlcnMvaW5zZXJ0LWVsZW1lbnQtaW4tc2V0JztcbmltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBpc1BhcnRPZkFDeWNsZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtcGFydC1vZi1hLWN5Y2xlJztcbmltcG9ydCB7IGlzUGFzc2l2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtcGFzc2l2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUtd2hlbi1uZWNlc3NhcnknO1xuaW1wb3J0IHsgdGVzdEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2RTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyB2aXNpdEVhY2hBdWRpb05vZGVPbmNlIH0gZnJvbSAnLi4vaGVscGVycy92aXNpdC1lYWNoLWF1ZGlvLW5vZGUtb25jZSc7XG5pbXBvcnQgeyB3cmFwQXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kJztcbmNvbnN0IGFkZENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW1PZkF1ZGlvQ29udGV4dCA9IChzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlzT2ZmbGluZSkgPT4ge1xuICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzLCBwYXNzaXZlSW5wdXRzIH0gPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IHsgb3V0cHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoc291cmNlKTtcbiAgICBjb25zdCBldmVudExpc3RlbmVycyA9IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoc291cmNlKTtcbiAgICBjb25zdCBldmVudExpc3RlbmVyID0gKGlzQWN0aXZlKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShzb3VyY2UpO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbik7XG4gICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgY29uc3QgcGFydGlhbENvbm5lY3Rpb24gPSBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKGFjdGl2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpO1xuICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBwYXJ0aWFsQ29ubmVjdGlvbiwgZmFsc2UpO1xuICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBpZiAoaW5zZXJ0RWxlbWVudEluU2V0KG91dHB1dHMsIFtkZXN0aW5hdGlvbiwgb3V0cHV0XSwgKG91dHB1dENvbm5lY3Rpb24pID0+IG91dHB1dENvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmIG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCwgdHJ1ZSkpIHtcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuYWRkKGV2ZW50TGlzdGVuZXIpO1xuICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoc291cmNlKSkge1xuICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBldmVudExpc3RlbmVyXSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIFtzb3VyY2UsIG91dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuY29uc3QgZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb05vZGUgPSAoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzLCBwYXNzaXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhkZXN0aW5hdGlvbik7XG4gICAgY29uc3QgYWN0aXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uKGFjdGl2ZUlucHV0c1tpbnB1dF0sIHNvdXJjZSwgb3V0cHV0KTtcbiAgICBpZiAoYWN0aXZlSW5wdXRDb25uZWN0aW9uID09PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgcmV0dXJuIFtwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzJdLCBmYWxzZV07XG4gICAgfVxuICAgIHJldHVybiBbYWN0aXZlSW5wdXRDb25uZWN0aW9uWzJdLCB0cnVlXTtcbn07XG5jb25zdCBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvUGFyYW0gPSAoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgeyBhY3RpdmVJbnB1dHMsIHBhc3NpdmVJbnB1dHMgfSA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhkZXN0aW5hdGlvbik7XG4gICAgY29uc3QgYWN0aXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uKGFjdGl2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpO1xuICAgIGlmIChhY3RpdmVJbnB1dENvbm5lY3Rpb24gPT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZVBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgc291cmNlLCBvdXRwdXQpO1xuICAgICAgICByZXR1cm4gW3Bhc3NpdmVJbnB1dENvbm5lY3Rpb25bMV0sIGZhbHNlXTtcbiAgICB9XG4gICAgcmV0dXJuIFthY3RpdmVJbnB1dENvbm5lY3Rpb25bMl0sIHRydWVdO1xufTtcbmNvbnN0IGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IFtsaXN0ZW5lciwgaXNBY3RpdmVdID0gZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb05vZGUoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCk7XG4gICAgaWYgKGxpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZUV2ZW50TGlzdGVuZXJPZkF1ZGlvTm9kZShzb3VyY2UsIGxpc3RlbmVyKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlICYmICFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKGdldE5hdGl2ZUF1ZGlvTm9kZShzb3VyY2UpLCBnZXROYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhkZXN0aW5hdGlvbik7XG4gICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5KGRlc3RpbmF0aW9uLCBhY3RpdmVJbnB1dHMpO1xuICAgIH1cbn07XG5jb25zdCBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0gPSAoc291cmNlLCBpc09mZmxpbmUsIGRlc3RpbmF0aW9uLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBbbGlzdGVuZXIsIGlzQWN0aXZlXSA9IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9QYXJhbShzb3VyY2UsIGRlc3RpbmF0aW9uLCBvdXRwdXQpO1xuICAgIGlmIChsaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUoc291cmNlLCBsaXN0ZW5lcik7XG4gICAgICAgIGlmIChpc0FjdGl2ZSAmJiAhaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKS5kaXNjb25uZWN0KGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pLCBvdXRwdXQpO1xuICAgICAgICB9XG4gICAgfVxufTtcbmNvbnN0IGRlbGV0ZUFueUNvbm5lY3Rpb24gPSAoc291cmNlLCBpc09mZmxpbmUpID0+IHtcbiAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoc291cmNlKTtcbiAgICBjb25zdCBkZXN0aW5hdGlvbnMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IG91dHB1dENvbm5lY3Rpb24gb2YgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzKSB7XG4gICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0Q29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZGVzdGluYXRpb25zLnB1c2gob3V0cHV0Q29ubmVjdGlvblswXSk7XG4gICAgfVxuICAgIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cy5jbGVhcigpO1xuICAgIHJldHVybiBkZXN0aW5hdGlvbnM7XG59O1xuY29uc3QgZGVsZXRlQ29ubmVjdGlvbkF0T3V0cHV0ID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoc291cmNlKTtcbiAgICBjb25zdCBkZXN0aW5hdGlvbnMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IG91dHB1dENvbm5lY3Rpb24gb2YgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzKSB7XG4gICAgICAgIGlmIChvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQpIHtcbiAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0Q29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0oc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVzdGluYXRpb25zLnB1c2gob3V0cHV0Q29ubmVjdGlvblswXSk7XG4gICAgICAgICAgICBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMuZGVsZXRlKG91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXN0aW5hdGlvbnM7XG59O1xuY29uc3QgZGVsZXRlQ29ubmVjdGlvblRvRGVzdGluYXRpb24gPSAoc291cmNlLCBpc09mZmxpbmUsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzKVxuICAgICAgICAuZmlsdGVyKChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJlxuICAgICAgICAob3V0cHV0ID09PSB1bmRlZmluZWQgfHwgb3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSAmJlxuICAgICAgICAoaW5wdXQgPT09IHVuZGVmaW5lZCB8fCBvdXRwdXRDb25uZWN0aW9uWzJdID09PSBpbnB1dCkpXG4gICAgICAgIC5tYXAoKG91dHB1dENvbm5lY3Rpb24pID0+IHtcbiAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXRDb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUoc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMuZGVsZXRlKG91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICByZXR1cm4gb3V0cHV0Q29ubmVjdGlvblswXTtcbiAgICB9KTtcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Ob2RlQ29uc3RydWN0b3IgPSAoYWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkZWNyZW1lbnRDeWNsZUNvdW50ZXIsIGRldGVjdEN5Y2xlcywgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZUF1ZGlvUGFyYW0sIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvTm9kZSBleHRlbmRzIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBpc0FjdGl2ZSwgbmF0aXZlQXVkaW9Ob2RlLCBhdWRpb05vZGVSZW5kZXJlcikge1xuICAgICAgICAgICAgc3VwZXIobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlID0gbmF0aXZlQXVkaW9Ob2RlO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICAvLyBCdWcgIzEyOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCB0byBkaXNjb25uZWN0IGEgc3BlY2lmaWMgZGVzdGluYXRpb24uXG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgJiZcbiAgICAgICAgICAgICAgICB0cnVlICE9PVxuICAgICAgICAgICAgICAgICAgICBjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2RTdXBwb3J0LCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGVzdEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2RTdXBwb3J0KG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2QobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEFVRElPX05PREVfU1RPUkUuc2V0KHRoaXMsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBFVkVOVF9MSVNURU5FUlMuc2V0KHRoaXMsIG5ldyBTZXQoKSk7XG4gICAgICAgICAgICBpZiAoY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcgJiYgaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRBdWRpb05vZGVDb25uZWN0aW9ucyh0aGlzLCBhdWRpb05vZGVSZW5kZXJlciwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICB9XG4gICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgfVxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkXG4gICAgICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzQ6IFNhZmFyaSBkb2VzIGV4cG9zZSBhIHdyb25nIG51bWJlck9mT3V0cHV0cyBmb3IgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZXMuXG4gICAgICAgICAgICBpZiAob3V0cHV0IDwgMCB8fCBvdXRwdXQgPj0gdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mT3V0cHV0cykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dCh0aGlzLl9jb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikgfHwgaXNOYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKHRoaXMuX25hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc1Bhc3NpdmUgPSBpc1Bhc3NpdmVBdWRpb05vZGUodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUgfHwgaXNQYXNzaXZlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCguLi5jb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJyAmJiAhaXNQYXNzaXZlICYmIGlzUGFzc2l2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQxOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgdGhlIGNvcnJlY3QgZXhjZXB0aW9uIHNvIGZhci5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGFkZENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCwgaXNPZmZsaW5lKTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgICAgICBpZiAoaXNOZXdDb25uZWN0aW9uVG9BdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3ljbGVzID0gZGV0ZWN0Q3ljbGVzKFt0aGlzXSwgZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB2aXNpdEVhY2hBdWRpb05vZGVPbmNlKGN5Y2xlcywgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyKGlzT2ZmbGluZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzdGluYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM3MywgIzE0NyAmICMxNTM6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHRvIGNvbm5lY3QgYW4gaW5wdXQgc2lnbmFsIHRvIHRoZSBwbGF5YmFja1JhdGUgQXVkaW9QYXJhbSBvZiBhblxuICAgICAgICAgICAgICogQXVkaW9CdWZmZXJTb3VyY2VOb2RlLiBUaGlzIGNhbid0IGJlIGVhc2lseSBkZXRlY3RlZCBhbmQgdGhhdCdzIHdoeSB0aGUgb3V0ZGF0ZWQgbmFtZSBwcm9wZXJ0eSBpcyB1c2VkIGhlcmUgdG8gaWRlbnRpZnlcbiAgICAgICAgICAgICAqIFNhZmFyaS4gSW4gYWRkaXRpb24gdG8gdGhhdCB0aGUgbWF4VmFsdWUgcHJvcGVydHkgaXMgdXNlZCB0byBvbmx5IGRldGVjdCB0aGUgYWZmZWN0ZWQgdmVyc2lvbnMgYmVsb3cgdjE0LjAuMi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvUGFyYW0ubmFtZSA9PT0gJ3BsYXliYWNrUmF0ZScgJiYgbmF0aXZlQXVkaW9QYXJhbS5tYXhWYWx1ZSA9PT0gMTAyNCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSB8fCBpc1Bhc3NpdmVBdWRpb05vZGUodGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1ODogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSBhZGRDb25uZWN0aW9uVG9BdWRpb1BhcmFtT2ZBdWRpb0NvbnRleHQodGhpcywgZGVzdGluYXRpb24sIG91dHB1dCwgaXNPZmZsaW5lKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTY0OiBPbmx5IEZpcmVmb3ggZGV0ZWN0cyBjeWNsZXMgc28gZmFyLlxuICAgICAgICAgICAgaWYgKGlzTmV3Q29ubmVjdGlvblRvQXVkaW9QYXJhbSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN5Y2xlcyA9IGRldGVjdEN5Y2xlcyhbdGhpc10sIGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB2aXNpdEVhY2hBdWRpb05vZGVPbmNlKGN5Y2xlcywgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyKGlzT2ZmbGluZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCkge1xuICAgICAgICAgICAgbGV0IGRlc3RpbmF0aW9ucztcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KHRoaXMuX2NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgaWYgKGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9ucyA9IGRlbGV0ZUFueUNvbm5lY3Rpb24odGhpcywgaXNPZmZsaW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0IDwgMCB8fCBkZXN0aW5hdGlvbk9yT3V0cHV0ID49IHRoaXMubnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9ucyA9IGRlbGV0ZUNvbm5lY3Rpb25BdE91dHB1dCh0aGlzLCBpc09mZmxpbmUsIGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dCAhPT0gdW5kZWZpbmVkICYmIChvdXRwdXQgPCAwIHx8IG91dHB1dCA+PSB0aGlzLm51bWJlck9mT3V0cHV0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpICYmIGlucHV0ICE9PSB1bmRlZmluZWQgJiYgKGlucHV0IDwgMCB8fCBpbnB1dCA+PSBkZXN0aW5hdGlvbk9yT3V0cHV0Lm51bWJlck9mSW5wdXRzKSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVDb25uZWN0aW9uVG9EZXN0aW5hdGlvbih0aGlzLCBpc09mZmxpbmUsIGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTY0OiBPbmx5IEZpcmVmb3ggZGV0ZWN0cyBjeWNsZXMgc28gZmFyLlxuICAgICAgICAgICAgZm9yIChjb25zdCBkZXN0aW5hdGlvbiBvZiBkZXN0aW5hdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjeWNsZXMgPSBkZXRlY3RDeWNsZXMoW3RoaXNdLCBkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGRlY3JlbWVudEN5Y2xlQ291bnRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgQXV0b21hdGlvbkV2ZW50TGlzdCB9IGZyb20gJ2F1dG9tYXRpb24tZXZlbnRzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeSA9IChhZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMsIGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgYXVkaW9QYXJhbVN0b3JlLCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIsIGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgaXNBdWRpb1BhcmFtT2ZPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtLCBtYXhWYWx1ZSA9IG51bGwsIG1pblZhbHVlID0gbnVsbCkgPT4ge1xuICAgICAgICAvLyBCdWcgIzE5NiBPbmx5IFNhZmFyaSBzZXRzIHRoZSBkZWZhdWx0VmFsdWUgdG8gdGhlIGluaXRpYWwgdmFsdWUuXG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IG5hdGl2ZUF1ZGlvUGFyYW0udmFsdWU7XG4gICAgICAgIGNvbnN0IGF1dG9tYXRpb25FdmVudExpc3QgPSBuZXcgQXV0b21hdGlvbkV2ZW50TGlzdChkZWZhdWx0VmFsdWUpO1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtUmVuZGVyZXIgPSBpc0F1ZGlvUGFyYW1PZk9mZmxpbmVBdWRpb0NvbnRleHQgPyBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIoYXV0b21hdGlvbkV2ZW50TGlzdCkgOiBudWxsO1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtID0ge1xuICAgICAgICAgICAgZ2V0IGRlZmF1bHRWYWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtYXhWYWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWF4VmFsdWUgPT09IG51bGwgPyBuYXRpdmVBdWRpb1BhcmFtLm1heFZhbHVlIDogbWF4VmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtaW5WYWx1ZSA9PT0gbnVsbCA/IG5hdGl2ZUF1ZGlvUGFyYW0ubWluVmFsdWUgOiBtaW5WYWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvUGFyYW0udmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHZhbHVlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjOTg6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IHlldCB0cmVhdCB0aGUgdmFsdWUgc2V0dGVyIGxpa2UgYSBjYWxsIHRvIHNldFZhbHVlQXRUaW1lKCkuXG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUoY2FuY2VsVGltZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMjg6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IHlldCBpbXBsZW1lbnQgY2FuY2VsQW5kSG9sZEF0VGltZSgpLlxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQoY2FuY2VsVGltZSkpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUoY2FuY2VsVGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91c0xhc3RFdmVudCA9IEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQoY2FuY2VsVGltZSkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50TGFzdEV2ZW50ID0gQXJyYXkuZnJvbShhdXRvbWF0aW9uRXZlbnRMaXN0KS5wb3AoKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c0xhc3RFdmVudCAhPT0gY3VycmVudExhc3RFdmVudCAmJiBjdXJyZW50TGFzdEV2ZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50TGFzdEV2ZW50LnR5cGUgPT09ICdleHBvbmVudGlhbFJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZShjdXJyZW50TGFzdEV2ZW50LnZhbHVlLCBjdXJyZW50TGFzdEV2ZW50LmVuZFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnbGluZWFyUmFtcFRvVmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShjdXJyZW50TGFzdEV2ZW50LnZhbHVlLCBjdXJyZW50TGFzdEV2ZW50LmVuZFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnc2V0VmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZShjdXJyZW50TGFzdEV2ZW50LnZhbHVlLCBjdXJyZW50TGFzdEV2ZW50LnN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50TGFzdEV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZUN1cnZlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShjdXJyZW50TGFzdEV2ZW50LnZhbHVlcywgY3VycmVudExhc3RFdmVudC5zdGFydFRpbWUsIGN1cnJlbnRMYXN0RXZlbnQuZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNhbmNlbFNjaGVkdWxlZFZhbHVlcyhjYW5jZWxUaW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhjYW5jZWxUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM0NTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxODc6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoZW5kVGltZSkgfHwgZW5kVGltZSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5NDogRmlyZWZveCBkb2VzIG5vdCBpbXBsaWNpdGx5IGNhbGwgc2V0VmFsdWVBdFRpbWUoKSBpZiB0aGVyZSBpcyBubyBwcmV2aW91cyBldmVudC5cbiAgICAgICAgICAgICAgICBpZiAoQXJyYXkuZnJvbShhdXRvbWF0aW9uRXZlbnRMaXN0KS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSkpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBlbmRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTU6IEZpcmVmb3ggZG9lcyBub3QgaW1wbGljaXRseSBjYWxsIHNldFZhbHVlQXRUaW1lKCkgaWYgdGhlcmUgaXMgbm8gcHJldmlvdXMgZXZlbnQuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50KGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZShkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQodmFsdWUsIGVuZFRpbWUpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXRUYXJnZXRBdFRpbWUodGFyZ2V0LCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCh0YXJnZXQsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUodGFyZ2V0LCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBzdGFydFRpbWUpKTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnIDE4MzogU2FmYXJpIG9ubHkgYWNjZXB0cyBhIEZsb2F0MzJBcnJheS5cbiAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWRWYWx1ZXMgPSB2YWx1ZXMgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyB2YWx1ZXMgOiBuZXcgRmxvYXQzMkFycmF5KHZhbHVlcyk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE1MjogU2FmYXJpIGRvZXMgbm90IGNvcnJlY3RseSBpbnRlcnBvbGF0ZSB0aGUgdmFsdWVzIG9mIHRoZSBjdXJ2ZS5cbiAgICAgICAgICAgICAgICAgKiBAdG9kbyBVbmZvcnR1bmF0ZWx5IHRoZXJlIGlzIG5vIHdheSB0byB0ZXN0IGZvciB0aGlzIGJlaGF2aW9yIGluIGEgc3luY2hyb25vdXMgZmFzaGlvbiB3aGljaCBpcyB3aHkgdGVzdGluZyBmb3IgdGhlXG4gICAgICAgICAgICAgICAgICogZXhpc3RlbmNlIG9mIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW5kVGltZSA9IHN0YXJ0VGltZSArIGR1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzYW1wbGVSYXRlID0gYXVkaW9Ob2RlLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmlyc3RTYW1wbGUgPSBNYXRoLmNlaWwoc3RhcnRUaW1lICogc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RTYW1wbGUgPSBNYXRoLmZsb29yKGVuZFRpbWUgKiBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZJbnRlcnBvbGF0ZWRWYWx1ZXMgPSBsYXN0U2FtcGxlIC0gZmlyc3RTYW1wbGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVycG9sYXRlZFZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobnVtYmVyT2ZJbnRlcnBvbGF0ZWRWYWx1ZXMpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRoZW9yZXRpY0luZGV4ID0gKChjb252ZXJ0ZWRWYWx1ZXMubGVuZ3RoIC0gMSkgLyBkdXJhdGlvbikgKiAoKGZpcnN0U2FtcGxlICsgaSkgLyBzYW1wbGVSYXRlIC0gc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvd2VySW5kZXggPSBNYXRoLmZsb29yKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwcGVySW5kZXggPSBNYXRoLmNlaWwodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJwb2xhdGVkVmFsdWVzW2ldID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlckluZGV4ID09PSB1cHBlckluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gY29udmVydGVkVmFsdWVzW2xvd2VySW5kZXhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiBjb252ZXJ0ZWRWYWx1ZXNbbG93ZXJJbmRleF0gK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgLSAodXBwZXJJbmRleCAtIHRoZW9yZXRpY0luZGV4KSkgKiBjb252ZXJ0ZWRWYWx1ZXNbdXBwZXJJbmRleF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChpbnRlcnBvbGF0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKGludGVycG9sYXRlZFZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVPZkxhc3RTYW1wbGUgPSBsYXN0U2FtcGxlIC8gc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVPZkxhc3RTYW1wbGUgPCBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUoYXVkaW9QYXJhbSwgaW50ZXJwb2xhdGVkVmFsdWVzW2ludGVycG9sYXRlZFZhbHVlcy5sZW5ndGggLSAxXSwgdGltZU9mTGFzdFNhbXBsZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKGF1ZGlvUGFyYW0sIGNvbnZlcnRlZFZhbHVlc1tjb252ZXJ0ZWRWYWx1ZXMubGVuZ3RoIC0gMV0sIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudChjb252ZXJ0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKGNvbnZlcnRlZFZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBhdWRpb1BhcmFtU3RvcmUuc2V0KGF1ZGlvUGFyYW0sIG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgICAgICBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUuc2V0KGF1ZGlvUGFyYW0sIGF1ZGlvTm9kZSk7XG4gICAgICAgIGFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtLCBhdWRpb1BhcmFtUmVuZGVyZXIpO1xuICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXBhcmFtLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlciA9IChhdXRvbWF0aW9uRXZlbnRMaXN0KSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmVwbGF5KGF1ZGlvUGFyYW0pIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgYXV0b21hdGlvbkV2ZW50IG9mIGF1dG9tYXRpb25FdmVudExpc3QpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdleHBvbmVudGlhbFJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGVuZFRpbWUsIHZhbHVlIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnbGluZWFyUmFtcFRvVmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZW5kVGltZSwgdmFsdWUgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnc2V0VGFyZ2V0Jykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHN0YXJ0VGltZSwgdGFyZ2V0LCB0aW1lQ29uc3RhbnQgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUodGFyZ2V0LCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnc2V0VmFsdWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgc3RhcnRUaW1lLCB2YWx1ZSB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlQ3VydmUnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZHVyYXRpb24sIHN0YXJ0VGltZSwgdmFsdWVzIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FuJ3QgYXBwbHkgYW4gdW5rbm93biBhdXRvbWF0aW9uLlwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXBhcmFtLXJlbmRlcmVyLmpzLm1hcCIsImV4cG9ydCBjbGFzcyBSZWFkT25seU1hcCB7XG4gICAgY29uc3RydWN0b3IocGFyYW1ldGVycykge1xuICAgICAgICB0aGlzLl9tYXAgPSBuZXcgTWFwKHBhcmFtZXRlcnMpO1xuICAgIH1cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5zaXplO1xuICAgIH1cbiAgICBlbnRyaWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmVudHJpZXMoKTtcbiAgICB9XG4gICAgZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZyA9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHZhbHVlLCBrZXksIHRoaXMpKTtcbiAgICB9XG4gICAgZ2V0KG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5nZXQobmFtZSk7XG4gICAgfVxuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuaGFzKG5hbWUpO1xuICAgIH1cbiAgICBrZXlzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmtleXMoKTtcbiAgICB9XG4gICAgdmFsdWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLnZhbHVlcygpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlYWQtb25seS1tYXAuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBSZWFkT25seU1hcCB9IGZyb20gJy4uL3JlYWQtb25seS1tYXAnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAvLyBCdWcgIzYxOiBUaGUgY2hhbm5lbENvdW50TW9kZSBzaG91bGQgYmUgJ21heCcgYWNjb3JkaW5nIHRvIHRoZSBzcGVjIGJ1dCBpcyBzZXQgdG8gJ2V4cGxpY2l0JyB0byBhY2hpZXZlIGNvbnNpc3RlbnQgYmVoYXZpb3IuXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgbnVtYmVyT2ZJbnB1dHM6IDEsXG4gICAgbnVtYmVyT2ZPdXRwdXRzOiAxLFxuICAgIHBhcmFtZXRlckRhdGE6IHt9LFxuICAgIHByb2Nlc3Nvck9wdGlvbnM6IHt9XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IChhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zLCBzZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzLCB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9Xb3JrbGV0Tm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgbmFtZSwgb3B0aW9ucykge1xuICAgICAgICAgICAgdmFyIF9hO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyh7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTkxOiBTYWZhcmkgZG9lc24ndCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgb3B0aW9ucyBhcmVuJ3QgY2xvbmFibGUuXG4gICAgICAgICAgICB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eShtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCA9IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUy5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBwcm9jZXNzb3JDb25zdHJ1Y3RvciA9IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCA9PT0gbnVsbCB8fCBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcC5nZXQobmFtZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE4NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBhbGxvdyB0byBjcmVhdGUgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBvbiBhIGNsb3NlZCBBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gaXNPZmZsaW5lIHx8IG5hdGl2ZUNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnXG4gICAgICAgICAgICAgICAgPyBuYXRpdmVDb250ZXh0XG4gICAgICAgICAgICAgICAgOiAoX2EgPSBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBuYXRpdmVDb250ZXh0O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGUobmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgaXNPZmZsaW5lID8gbnVsbCA6IGNvbnRleHQuYmFzZUxhdGVuY3ksIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmFtZSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyID0gKChpc09mZmxpbmUgPyBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIobmFtZSwgbWVyZ2VkT3B0aW9ucywgcHJvY2Vzc29yQ29uc3RydWN0b3IpIDogbnVsbCkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEB0b2RvIEFkZCBhIG1lY2hhbmlzbSB0byBzd2l0Y2ggYW4gQXVkaW9Xb3JrbGV0Tm9kZSB0byBwYXNzaXZlIG9uY2UgdGhlIHByb2Nlc3MoKSBmdW5jdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yXG4gICAgICAgICAgICAgKiByZXR1cm5zIGZhbHNlLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IFtdO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzLmZvckVhY2goKG5hdGl2ZUF1ZGlvUGFyYW0sIG5tKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXVkaW9QYXJhbSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzLnB1c2goW25tLCBhdWRpb1BhcmFtXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBuYXRpdmVBdWRpb1dvcmtsZXROb2RlO1xuICAgICAgICAgICAgdGhpcy5fb25wcm9jZXNzb3JlcnJvciA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbWV0ZXJzID0gbmV3IFJlYWRPbmx5TWFwKHBhcmFtZXRlcnMpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjODYgJiAjODc6IEludm9raW5nIHRoZSByZW5kZXJlciBvZiBhbiBBdWRpb1dvcmtsZXROb2RlIG1pZ2h0IGJlIG5lY2Vzc2FyeSBpZiBpdCBoYXMgbm8gZGlyZWN0IG9yIGluZGlyZWN0IGNvbm5lY3Rpb24gdG9cbiAgICAgICAgICAgICAqIHRoZSBkZXN0aW5hdGlvbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlKG5hdGl2ZUNvbnRleHQsIHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBhY3RpdmVJbnB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHRoaXMpO1xuICAgICAgICAgICAgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhY3RpdmVJbnB1dHMpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbnByb2Nlc3NvcmVycm9yKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29ucHJvY2Vzc29yZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9ucHJvY2Vzc29yZXJyb3IodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlLm9ucHJvY2Vzc29yZXJyb3IgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPblByb2Nlc3NvckVycm9yID0gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yO1xuICAgICAgICAgICAgdGhpcy5fb25wcm9jZXNzb3JlcnJvciA9XG4gICAgICAgICAgICAgICAgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciAhPT0gbnVsbCAmJiBuYXRpdmVPblByb2Nlc3NvckVycm9yID09PSB3cmFwcGVkTGlzdGVuZXJcbiAgICAgICAgICAgICAgICAgICAgPyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICA6IG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBhcmFtZXRlcnMoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fcGFyYW1ldGVycyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoZSBkZWZpbml0aW9uIHRoYXQgVHlwZVNjcmlwdCB1c2VzIG9mIHRoZSBBdWRpb1BhcmFtTWFwIGlzIGxhY2tpbmcgbWFueSBtZXRob2RzLlxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW1ldGVycztcbiAgICAgICAgfVxuICAgICAgICBnZXQgcG9ydCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBvcnQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgZnVuY3Rpb24gY29weUZyb21DaGFubmVsKGF1ZGlvQnVmZmVyLCBcbi8vIEB0b2RvIFRoZXJlIGlzIGN1cnJlbnRseSBubyB3YXkgdG8gZGVmaW5lIHNvbWV0aGluZyBsaWtlIHsgWyBrZXk6IG51bWJlciB8IHN0cmluZyBdOiBGbG9hdDMyQXJyYXkgfVxucGFyZW50LCBrZXksIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCkge1xuICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBwYXJlbnRba2V5XSA9IG5ldyBGbG9hdDMyQXJyYXkoMTI4KTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwocGFyZW50W2tleV0sIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkuXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpO1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50W2tleV0gPSBjaGFubmVsRGF0YS5zbGljZShidWZmZXJPZmZzZXQsIGJ1ZmZlck9mZnNldCArIDEyOCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzbGljZWRJbnB1dCA9IG5ldyBGbG9hdDMyQXJyYXkoY2hhbm5lbERhdGEuYnVmZmVyLCBidWZmZXJPZmZzZXQgKiBGbG9hdDMyQXJyYXkuQllURVNfUEVSX0VMRU1FTlQsIDEyOCk7XG4gICAgICAgICAgICBwYXJlbnRba2V5XS5zZXQoc2xpY2VkSW5wdXQpO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29weS1mcm9tLWNoYW5uZWwuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNvcHlUb0NoYW5uZWwgPSAoYXVkaW9CdWZmZXIsIHBhcmVudCwga2V5LCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpID0+IHtcbiAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwocGFyZW50W2tleV0sIGNoYW5uZWxOdW1iZXIsIGJ1ZmZlck9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5VG9DaGFubmVsKCkuXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcikuc2V0KHBhcmVudFtrZXldLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICB9XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcHktdG8tY2hhbm5lbC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmVzdGVkQXJyYXlzID0gKHgsIHkpID0+IHtcbiAgICBjb25zdCBhcnJheXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHg7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBhcnJheSA9IFtdO1xuICAgICAgICBjb25zdCBsZW5ndGggPSB0eXBlb2YgeSA9PT0gJ251bWJlcicgPyB5IDogeVtpXTtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgYXJyYXkucHVzaChuZXcgRmxvYXQzMkFycmF5KDEyOCkpO1xuICAgICAgICB9XG4gICAgICAgIGFycmF5cy5wdXNoKGFycmF5KTtcbiAgICB9XG4gICAgcmV0dXJuIGFycmF5cztcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtbmVzdGVkLWFycmF5cy5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX1RPX1BST0NFU1NPUl9NQVBTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2dldC1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvV29ya2xldFByb2Nlc3NvciA9IChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eSkgPT4ge1xuICAgIGNvbnN0IG5vZGVUb1Byb2Nlc3Nvck1hcCA9IGdldFZhbHVlRm9yS2V5KE5PREVfVE9fUFJPQ0VTU09SX01BUFMsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShub2RlVG9Qcm9jZXNzb3JNYXAsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci5qcy5tYXAiLCJpbXBvcnQgeyBjb3B5RnJvbUNoYW5uZWwgfSBmcm9tICcuLi9oZWxwZXJzL2NvcHktZnJvbS1jaGFubmVsJztcbmltcG9ydCB7IGNvcHlUb0NoYW5uZWwgfSBmcm9tICcuLi9oZWxwZXJzL2NvcHktdG8tY2hhbm5lbCc7XG5pbXBvcnQgeyBjcmVhdGVOZXN0ZWRBcnJheXMgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZS1uZXN0ZWQtYXJyYXlzJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmNvbnN0IHByb2Nlc3NCdWZmZXIgPSBhc3luYyAocHJveHksIHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zLCBvdXRwdXRDaGFubmVsQ291bnQsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSkgPT4ge1xuICAgIC8vIENlaWwgdGhlIGxlbmd0aCB0byB0aGUgbmV4dCBmdWxsIHJlbmRlciBxdWFudHVtLlxuICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgY29uc3QgbGVuZ3RoID0gcmVuZGVyZWRCdWZmZXIgPT09IG51bGwgPyBNYXRoLmNlaWwocHJveHkuY29udGV4dC5sZW5ndGggLyAxMjgpICogMTI4IDogcmVuZGVyZWRCdWZmZXIubGVuZ3RoO1xuICAgIGNvbnN0IG51bWJlck9mSW5wdXRDaGFubmVscyA9IG9wdGlvbnMuY2hhbm5lbENvdW50ICogb3B0aW9ucy5udW1iZXJPZklucHV0cztcbiAgICBjb25zdCBudW1iZXJPZk91dHB1dENoYW5uZWxzID0gb3V0cHV0Q2hhbm5lbENvdW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApO1xuICAgIGNvbnN0IHByb2Nlc3NlZEJ1ZmZlciA9IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPT09IDBcbiAgICAgICAgPyBudWxsXG4gICAgICAgIDogbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIobnVtYmVyT2ZPdXRwdXRDaGFubmVscywgbGVuZ3RoLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgcHJvY2Vzc29yIGNvbnN0cnVjdG9yLicpO1xuICAgIH1cbiAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHByb3h5KTtcbiAgICBjb25zdCBhdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSBhd2FpdCBnZXRBdWRpb1dvcmtsZXRQcm9jZXNzb3IobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpO1xuICAgIGNvbnN0IGlucHV0cyA9IGNyZWF0ZU5lc3RlZEFycmF5cyhvcHRpb25zLm51bWJlck9mSW5wdXRzLCBvcHRpb25zLmNoYW5uZWxDb3VudCk7XG4gICAgY29uc3Qgb3V0cHV0cyA9IGNyZWF0ZU5lc3RlZEFycmF5cyhvcHRpb25zLm51bWJlck9mT3V0cHV0cywgb3V0cHV0Q2hhbm5lbENvdW50KTtcbiAgICBjb25zdCBwYXJhbWV0ZXJzID0gQXJyYXkuZnJvbShwcm94eS5wYXJhbWV0ZXJzLmtleXMoKSkucmVkdWNlKChwcm10cnMsIG5hbWUpID0+ICh7IC4uLnBybXRycywgW25hbWVdOiBuZXcgRmxvYXQzMkFycmF5KDEyOCkgfSksIHt9KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxMjgpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMgPiAwICYmIHJlbmRlcmVkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwocmVuZGVyZWRCdWZmZXIsIGlucHV0c1tqXSwgaywgaywgaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkICYmIHJlbmRlcmVkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5mb3JFYWNoKCh7IG5hbWUgfSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwocmVuZGVyZWRCdWZmZXIsIHBhcmFtZXRlcnMsIG5hbWUsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGluZGV4LCBpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG91dHB1dENoYW5uZWxDb3VudFtqXTsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0c1tqXVtrXS5ieXRlTGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dHNbal1ba10gPSBuZXcgRmxvYXQzMkFycmF5KDEyOCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwb3RlbnRpYWxseUVtcHR5SW5wdXRzID0gaW5wdXRzLm1hcCgoaW5wdXQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvTm9kZUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0c1tpbmRleF0uc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgYWN0aXZlU291cmNlRmxhZyA9IGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKGkgLyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSwgKCkgPT4gYXVkaW9Xb3JrbGV0UHJvY2Vzc29yLnByb2Nlc3MocG90ZW50aWFsbHlFbXB0eUlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykpO1xuICAgICAgICAgICAgaWYgKHByb2Nlc3NlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29weVRvQ2hhbm5lbChwcm9jZXNzZWRCdWZmZXIsIG91dHB1dHNbal0sIGssIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBrLCBpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtqXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWFjdGl2ZVNvdXJjZUZsYWcpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIHByb3h5LmRpc3BhdGNoRXZlbnQobmV3IEVycm9yRXZlbnQoJ3Byb2Nlc3NvcmVycm9yJywge1xuICAgICAgICAgICAgICAgIGNvbG5vOiBlcnJvci5jb2xubyxcbiAgICAgICAgICAgICAgICBmaWxlbmFtZTogZXJyb3IuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgbGluZW5vOiBlcnJvci5saW5lbm8sXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHByb2Nlc3NlZEJ1ZmZlcjtcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAobmFtZSwgb3B0aW9ucywgcHJvY2Vzc29yQ29uc3RydWN0b3IpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHByb2Nlc3NlZEJ1ZmZlclByb21pc2UgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIGxldCBuYXRpdmVPdXRwdXROb2RlcyA9IG51bGw7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsQ291bnQgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50KVxuICAgICAgICAgICAgICAgID8gb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnRcbiAgICAgICAgICAgICAgICA6IEFycmF5LmZyb20ob3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQpO1xuICAgICAgICAgICAgLy8gQnVnICM2MTogT25seSBDaHJvbWUsIEVkZ2UgJiBGaXJlZm94IGhhdmUgYW4gaW1wbGVtZW50YXRpb24gb2YgdGhlIEF1ZGlvV29ya2xldE5vZGUgeWV0LlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPSBvdXRwdXRDaGFubmVsQ291bnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByb3h5Lm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogb3V0cHV0Q2hhbm5lbENvdW50W2ldXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNvbm5lY3QgPSBjb25uZWN0TXVsdGlwbGVPdXRwdXRzLmJpbmQobnVsbCwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzKTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0ID0gZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcyk7XG4gICAgICAgICAgICAgICAgbmF0aXZlT3V0cHV0Tm9kZXMgPSBbb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLCBvdXRwdXRHYWluTm9kZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlT3V0cHV0Tm9kZXMgPT09IG51bGwgPyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlIDogbmF0aXZlT3V0cHV0Tm9kZXNbMl0pO1xuICAgICAgICAgICAgaWYgKG5hdGl2ZU91dHB1dE5vZGVzICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NlZEJ1ZmZlclByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgcHJvY2Vzc29yIGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0NzogVGhlIEF1ZGlvRGVzdGluYXRpb25Ob2RlIGluIFNhZmFyaSBnZXRzIG5vdCBpbml0aWFsaXplZCBjb3JyZWN0bHkuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mSW5wdXRDaGFubmVscyA9IHByb3h5LmNoYW5uZWxDb3VudCAqIHByb3h5Lm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZlBhcmFtZXRlcnMgPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkID8gMCA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZDaGFubmVscyA9IG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyQnVmZmVyID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKG51bWJlck9mQ2hhbm5lbHMsIFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2VpbCB0aGUgbGVuZ3RoIHRvIHRoZSBuZXh0IGZ1bGwgcmVuZGVyIHF1YW50dW0uXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5jZWlsKHByb3h5LmNvbnRleHQubGVuZ3RoIC8gMTI4KSAqIDEyOCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2RlcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluTm9kZXMucHVzaChjcmVhdGVOYXRpdmVHYWluTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IG9wdGlvbnMuY2hhbm5lbENvdW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlcyA9IGF3YWl0IFByb21pc2UuYWxsKEFycmF5LmZyb20ocHJveHkucGFyYW1ldGVycy52YWx1ZXMoKSkubWFwKGFzeW5jIChhdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGF1ZGlvUGFyYW0udmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnMpXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGVzW2ldLmNvbm5lY3QoaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0uY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCBqLCBpICogb3B0aW9ucy5jaGFubmVsQ291bnQgKyBqKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtpbmRleCwgY29uc3RhbnRTb3VyY2VOb2RlXSBvZiBjb25zdGFudFNvdXJjZU5vZGVzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIDAsIG51bWJlck9mSW5wdXRDaGFubmVscyArIGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3QocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoZ2Fpbk5vZGVzLm1hcCgoZ2Fpbk5vZGUpID0+IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgZ2Fpbk5vZGUpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3NlZEJ1ZmZlclByb21pc2UgPSBwcm9jZXNzQnVmZmVyKHByb3h5LCBudW1iZXJPZkNoYW5uZWxzID09PSAwID8gbnVsbCA6IGF3YWl0IHJlbmRlckJ1ZmZlcigpLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zLCBvdXRwdXRDaGFubmVsQ291bnQsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHByb2Nlc3NlZEJ1ZmZlciA9IGF3YWl0IHByb2Nlc3NlZEJ1ZmZlclByb21pc2U7XG4gICAgICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0IFtvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMsIG91dHB1dEdhaW5Ob2RlXSA9IG5hdGl2ZU91dHB1dE5vZGVzO1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IHByb2Nlc3NlZEJ1ZmZlcjtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGkgPCBwcm94eS5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdXRwdXRDaGFubmVsQ291bnRbaV07IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxNZXJnZXJOb2RlLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaiwgaik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBvdXRwdXRHYWluTm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtubSwgYXVkaW9QYXJhbV0gb2YgcHJveHkucGFyYW1ldGVycy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhlIGRlZmluaXRpb24gdGhhdCBUeXBlU2NyaXB0IHVzZXMgb2YgdGhlIEF1ZGlvUGFyYW1NYXAgaXMgbGFja2luZyBtYW55IG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycy5nZXQobm0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtubSwgYXVkaW9QYXJhbV0gb2YgcHJveHkucGFyYW1ldGVycy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoZSBkZWZpbml0aW9uIHRoYXQgVHlwZVNjcmlwdCB1c2VzIG9mIHRoZSBBdWRpb1BhcmFtTWFwIGlzIGxhY2tpbmcgbWFueSBtZXRob2RzLlxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnMuZ2V0KG5tKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBkZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb1dvcmtsZXROb2RlT3JHYWluTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZU9yR2Fpbk5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZU9yR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXdvcmtsZXQtbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoYWRkQXVkaW9Xb3JrbGV0TW9kdWxlLCBhbmFseXNlck5vZGVDb25zdHJ1Y3RvciwgYXVkaW9CdWZmZXJDb25zdHJ1Y3RvciwgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciwgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciwgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yLCBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciwgY29udm9sdmVyTm9kZUNvbnN0cnVjdG9yLCBkZWNvZGVBdWRpb0RhdGEsIGRlbGF5Tm9kZUNvbnN0cnVjdG9yLCBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IsIGdhaW5Ob2RlQ29uc3RydWN0b3IsIGlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciwgcGFubmVyTm9kZUNvbnN0cnVjdG9yLCBwZXJpb2RpY1dhdmVDb25zdHJ1Y3Rvciwgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yLCB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEJhc2VBdWRpb0NvbnRleHQgZXh0ZW5kcyBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoX25hdGl2ZUNvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgIHN1cGVyKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnRleHQgPSBfbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX2F1ZGlvV29ya2xldCA9XG4gICAgICAgICAgICAgICAgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRNb2R1bGU6IChtb2R1bGVVUkwsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKHRoaXMsIG1vZHVsZVVSTCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGF1ZGlvV29ya2xldCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdWRpb1dvcmtsZXQ7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQW5hbHlzZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgYXVkaW9CdWZmZXJDb25zdHJ1Y3Rvcih7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCdWZmZXJTb3VyY2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNoYW5uZWxNZXJnZXIobnVtYmVyT2ZJbnB1dHMgPSA2KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IodGhpcywgeyBudW1iZXJPZklucHV0cyB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDaGFubmVsU3BsaXR0ZXIobnVtYmVyT2ZPdXRwdXRzID0gNikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IodGhpcywgeyBudW1iZXJPZk91dHB1dHMgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ29uc3RhbnRTb3VyY2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNvbnZvbHZlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY29udm9sdmVyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZURlbGF5KG1heERlbGF5VGltZSA9IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgZGVsYXlOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtYXhEZWxheVRpbWUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlR2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgZ2Fpbk5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVJSVJGaWx0ZXIoZmVlZGZvcndhcmQsIGZlZWRiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGlJUkZpbHRlck5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IGZlZWRiYWNrLCBmZWVkZm9yd2FyZCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVPc2NpbGxhdG9yKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZVBhbm5lcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgcGFubmVyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnLCBjb25zdHJhaW50cyA9IHsgZGlzYWJsZU5vcm1hbGl6YXRpb246IGZhbHNlIH0pIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IodGhpcywgeyAuLi5jb25zdHJhaW50cywgaW1hZywgcmVhbCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVTdGVyZW9QYW5uZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGRlY29kZUF1ZGlvRGF0YShhdWRpb0RhdGEsIHN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIGRlY29kZUF1ZGlvRGF0YSh0aGlzLl9uYXRpdmVDb250ZXh0LCBhdWRpb0RhdGEpLnRoZW4oKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBzdWNjZXNzQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2Vzc0NhbGxiYWNrKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyO1xuICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZXJyb3JDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBlcnJvckNhbGxiYWNrKGVycik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBROiAxLFxuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGV0dW5lOiAwLFxuICAgIGZyZXF1ZW5jeTogMzUwLFxuICAgIGdhaW46IDAsXG4gICAgdHlwZTogJ2xvd3Bhc3MnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQmlxdWFkRmlsdGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgYmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgYmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjODA6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9RID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuUSwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzg6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2RldHVuZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmRldHVuZSwgMTIwMCAqIE1hdGgubG9nMihNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCksIC0xMjAwICogTWF0aC5sb2cyKE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUKSk7XG4gICAgICAgICAgICAvLyBCdWcgIzc3OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWUgZm9yIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5LCBjb250ZXh0LnNhbXBsZVJhdGUgLyAyLCAwKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzk6IEZpcmVmb3ggJiBTYWZhcmkgZG8gbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2dhaW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nYWluLCA0MCAqIE1hdGgubG9nMTAoTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQpLCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gbmF0aXZlQmlxdWFkRmlsdGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRldHVuZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXR1bmU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZyZXF1ZW5jeSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2FpbjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgUSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9RO1xuICAgICAgICB9XG4gICAgICAgIGdldCB0eXBlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUudHlwZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgdHlwZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS50eXBlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE4OTogU2FmYXJpIGRvZXMgdGhyb3cgYW4gSW52YWxpZFN0YXRlRXJyb3IuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDExKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzY4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHBhcmFtZXRlcnMgZGlmZmVyIGluIHRoZWlyIGxlbmd0aC5cbiAgICAgICAgICAgIGlmIChmcmVxdWVuY3lIei5sZW5ndGggIT09IG1hZ1Jlc3BvbnNlLmxlbmd0aCB8fCBtYWdSZXNwb25zZS5sZW5ndGggIT09IHBoYXNlUmVzcG9uc2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpcXVhZC1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQmlxdWFkRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBROiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLlEudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGV0dW5lOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmRldHVuZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5OiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZ2FpbjogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5nYWluLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLnR5cGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUJpcXVhZEZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5RLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLlEpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGV0dW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2Fpbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5RLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLlEpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRldHVuZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmZyZXF1ZW5jeSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2Fpbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQmlxdWFkRmlsdGVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWJpcXVhZC1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDYWNoZVRlc3RSZXN1bHQgPSAob25nb2luZ1Rlc3RzLCB0ZXN0UmVzdWx0cykgPT4ge1xuICAgIHJldHVybiAodGVzdGVyLCB0ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGNhY2hlZFRlc3RSZXN1bHQgPSB0ZXN0UmVzdWx0cy5nZXQodGVzdGVyKTtcbiAgICAgICAgaWYgKGNhY2hlZFRlc3RSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhY2hlZFRlc3RSZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb25nb2luZ1Rlc3QgPSBvbmdvaW5nVGVzdHMuZ2V0KHRlc3Rlcik7XG4gICAgICAgIGlmIChvbmdvaW5nVGVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb25nb2luZ1Rlc3Q7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHN5bmNocm9ub3VzVGVzdFJlc3VsdCA9IHRlc3QoKTtcbiAgICAgICAgICAgIGlmIChzeW5jaHJvbm91c1Rlc3RSZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgICAgICAgICAgb25nb2luZ1Rlc3RzLnNldCh0ZXN0ZXIsIHN5bmNocm9ub3VzVGVzdFJlc3VsdCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN5bmNocm9ub3VzVGVzdFJlc3VsdFxuICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKCkgPT4gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChmaW5hbFRlc3RSZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgb25nb2luZ1Rlc3RzLmRlbGV0ZSh0ZXN0ZXIpO1xuICAgICAgICAgICAgICAgICAgICB0ZXN0UmVzdWx0cy5zZXQodGVzdGVyLCBmaW5hbFRlc3RSZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmluYWxUZXN0UmVzdWx0O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGVzdFJlc3VsdHMuc2V0KHRlc3Rlciwgc3luY2hyb25vdXNUZXN0UmVzdWx0KTtcbiAgICAgICAgICAgIHJldHVybiBzeW5jaHJvbm91c1Rlc3RSZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgdGVzdFJlc3VsdHMuc2V0KHRlc3RlciwgZmFsc2UpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jYWNoZS10ZXN0LXJlc3VsdC5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAxLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG51bWJlck9mSW5wdXRzOiA2XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ2hhbm5lbE1lcmdlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciA9ICgoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpID8gY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2hhbm5lbC1tZXJnZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQXVkaW9Ob2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Ob2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQXVkaW9Ob2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IG5hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZklucHV0c1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2hhbm5lbC1tZXJnZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDYsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgbnVtYmVyT2ZPdXRwdXRzOiA2XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucykgPT4ge1xuICAgIHJldHVybiBjbGFzcyBDaGFubmVsU3BsaXR0ZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMoeyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfSk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlciA9ICgoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpID8gY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2hhbm5lbC1zcGxpdHRlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQXVkaW9Ob2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Ob2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQXVkaW9Ob2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZPdXRwdXRzXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtc3BsaXR0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDb25uZWN0QXVkaW9QYXJhbSA9IChyZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIG5hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgcmV0dXJuIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbShhdWRpb1BhcmFtLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbm5lY3QtYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbm5lY3RNdWx0aXBsZU91dHB1dHMgPSAoY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG91dHB1dEF1ZGlvTm9kZXMsIGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApID0+IHtcbiAgICAgICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlID0gb3V0cHV0QXVkaW9Ob2Rlc1tvdXRwdXRdO1xuICAgICAgICBpZiAob3V0cHV0QXVkaW9Ob2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZS5jb25uZWN0KGRlc3RpbmF0aW9uLCAwLCBpbnB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZS5jb25uZWN0KGRlc3RpbmF0aW9uLCAwKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMiwgNDQxMDApO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXI7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wID0gdHJ1ZTtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3QobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc2Nvbm5lY3QobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbm5lY3RlZC1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgb2Zmc2V0OiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnksIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBDb25zdGFudFNvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5KCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciA9IGNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjNjIgJiAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IENvbnN0YW50U291cmNlTm9kZXMgYW5kIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZVxuICAgICAgICAgICAgICogZm9yIEdhaW5Ob2Rlcy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgdGhpcy5fb2Zmc2V0ID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb2Zmc2V0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25lbmRlZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbmVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbmVuZGVkKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9uZW5kZWQgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPbkVuZGVkID0gdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbmF0aXZlT25FbmRlZCAhPT0gbnVsbCAmJiBuYXRpdmVPbkVuZGVkID09PSB3cmFwcGVkTGlzdGVuZXIgPyB2YWx1ZSA6IG5hdGl2ZU9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnQod2hlbiA9IDApIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdGFydCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLnN0YXJ0ID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdG9wKHdoZW4pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIuc3RvcCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gbnVsbDtcbiAgICAgICAgbGV0IHN0b3AgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KHN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHN0b3AgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vZmZzZXQsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub2Zmc2V0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBzdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0b3AodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdG9wID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSByZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50LXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyA9ICh1bml0MzJBcnJheSkgPT4ge1xuICAgIHJldHVybiAodmFsdWUpID0+IHtcbiAgICAgICAgdW5pdDMyQXJyYXlbMF0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHVuaXQzMkFycmF5WzBdO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udmVydC1udW1iZXItdG8tdW5zaWduZWQtbG9uZy5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYnVmZmVyOiBudWxsLFxuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnY2xhbXBlZC1tYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBkaXNhYmxlTm9ybWFsaXphdGlvbjogZmFsc2Vcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ29udm9sdmVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnZvbHZlck5vZGUgPSBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgY29udm9sdmVyTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQ29udm9sdmVyTm9kZSwgY29udm9sdmVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlID0gbmF0aXZlQ29udm9sdmVyTm9kZTtcbiAgICAgICAgICAgIGlmIChtZXJnZWRPcHRpb25zLmJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIG1lcmdlZE9wdGlvbnMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGJ1ZmZlcih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIgPSB2YWx1ZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE1OiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gc2V0IHRoZSBidWZmZXIgdG8gbnVsbC5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCAmJiB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSB0aGlzLl9uYXRpdmVDb252b2x2ZXJOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzQnVmZmVyTnVsbGlmaWVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIgPT09IG51bGwgPyAwIDogdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBub3JtYWxpemUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG5vcm1hbGl6ZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udm9sdmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUNvbnZvbHZlck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUNvbnZvbHZlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb252b2x2ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQ29udm9sdmVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUNvbnZvbHZlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBuYXRpdmVDb252b2x2ZXJOb2RlLmJ1ZmZlcixcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVDb252b2x2ZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQ29udm9sdmVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUNvbnZvbHZlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlTm9ybWFsaXphdGlvbjogIW5hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVDb252b2x2ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnZvbHZlck5vZGUpO1xuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlQ29udm9sdmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29udm9sdmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnZvbHZlck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnZvbHZlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGUgPSByZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQ29udm9sdmVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb252b2x2ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkgPT4ge1xuICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTQzLCAjMTQ0ICYgIzE0NjogU2FmYXJpIHRocm93cyBhIFN5bnRheEVycm9yIHdoZW4gbnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoIG9yIHNhbXBsZVJhdGUgYXJlIGludmFsaWQuXG4gICAgICAgICAgICBpZiAoZXJyLm5hbWUgPT09ICdTeW50YXhFcnJvcicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRGF0YUNsb25lRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnRGF0YUNsb25lRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGEtY2xvbmUtZXJyb3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGRldGFjaEFycmF5QnVmZmVyID0gKGFycmF5QnVmZmVyKSA9PiB7XG4gICAgY29uc3QgeyBwb3J0MSwgcG9ydDIgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICBjb25zdCBjbG9zZUFuZFJlc29sdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICBwb3J0Mi5vbm1lc3NhZ2UgPSBudWxsO1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH07XG4gICAgICAgIHBvcnQyLm9ubWVzc2FnZSA9ICgpID0+IGNsb3NlQW5kUmVzb2x2ZSgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcG9ydDEucG9zdE1lc3NhZ2UoYXJyYXlCdWZmZXIsIFthcnJheUJ1ZmZlcl0pO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICBjbG9zZUFuZFJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRldGFjaC1hcnJheS1idWZmZXIuanMubWFwIiwiaW1wb3J0IHsgZGV0YWNoQXJyYXlCdWZmZXIgfSBmcm9tICcuLi9oZWxwZXJzL2RldGFjaC1hcnJheS1idWZmZXInO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kJztcbmV4cG9ydCBjb25zdCBjcmVhdGVEZWNvZGVBdWRpb0RhdGEgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVEYXRhQ2xvbmVFcnJvciwgY3JlYXRlRW5jb2RpbmdFcnJvciwgZGV0YWNoZWRBcnJheUJ1ZmZlcnMsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB0ZXN0UHJvbWlzZVN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICByZXR1cm4gKGFueUNvbnRleHQsIGF1ZGlvRGF0YSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gaXNOYXRpdmVDb250ZXh0KGFueUNvbnRleHQpID8gYW55Q29udGV4dCA6IGdldE5hdGl2ZUNvbnRleHQoYW55Q29udGV4dCk7XG4gICAgICAgIC8vIEJ1ZyAjNDM6IE9ubHkgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGEgRGF0YUNsb25lRXJyb3IuXG4gICAgICAgIGlmIChkZXRhY2hlZEFycmF5QnVmZmVycy5oYXMoYXVkaW9EYXRhKSkge1xuICAgICAgICAgICAgY29uc3QgZXJyID0gY3JlYXRlRGF0YUNsb25lRXJyb3IoKTtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSBhdWRpb0RhdGEgcGFyYW1ldGVyIG1heWJlIG9mIGEgdHlwZSB3aGljaCBjYW4ndCBiZSBhZGRlZCB0byBhIFdlYWtTZXQuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBkZXRhY2hlZEFycmF5QnVmZmVycy5hZGQoYXVkaW9EYXRhKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIHlldC5cbiAgICAgICAgaWYgKGNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmRlY29kZUF1ZGlvRGF0YShhdWRpb0RhdGEpLnRoZW4oKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMzM6IFNhZmFyaSBkb2VzIG5ldXRlciB0aGUgQXJyYXlCdWZmZXIuXG4gICAgICAgICAgICAgICAgZGV0YWNoQXJyYXlCdWZmZXIoYXVkaW9EYXRhKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNTc6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdGhlIGJ1ZmZlck9mZnNldCB0byBiZSBvdXQtb2YtYm91bmRzLlxuICAgICAgICAgICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0KGF1ZGlvQnVmZmVyKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMyMTogU2FmYXJpIGRvZXMgbm90IHJldHVybiBhIFByb21pc2UgeWV0LlxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29tcGxldGUgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMzM6IFNhZmFyaSBkb2VzIG5ldXRlciB0aGUgQXJyYXlCdWZmZXIuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZGV0YWNoQXJyYXlCdWZmZXIoYXVkaW9EYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBmYWlsID0gKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgIGNvbXBsZXRlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gQnVnICMyNjogU2FmYXJpIHRocm93cyBhIHN5bmNocm9ub3VzIGVycm9yLlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE6IFNhZmFyaSByZXF1aXJlcyBhIHN1Y2Nlc3NDYWxsYmFjay5cbiAgICAgICAgICAgICAgICBuYXRpdmVDb250ZXh0LmRlY29kZUF1ZGlvRGF0YShhdWRpb0RhdGEsIChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTAwOiBTYWZhcmkgZG9lcyB0aHJvdyBhIHdyb25nIGVycm9yIHdoZW4gY2FsbGluZyBnZXRDaGFubmVsRGF0YSgpIHdpdGggYW4gb3V0LW9mLWJvdW5kcyB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZSgpLnRoZW4oKCkgPT4gcmVzb2x2ZShhdWRpb0J1ZmZlcikpO1xuICAgICAgICAgICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0OiBTYWZhcmkgcmV0dXJucyBudWxsIGluc3RlYWQgb2YgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoY3JlYXRlRW5jb2RpbmdFcnJvcigpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZhaWwoZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGZhaWwoZXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWNvZGUtYXVkaW8tZGF0YS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbic7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVjcmVtZW50Q3ljbGVDb3VudGVyID0gKGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgY3ljbGVDb3VudGVycywgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNBY3RpdmVBdWRpb05vZGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCBjb3VudCkgPT4ge1xuICAgICAgICBjb25zdCBjeWNsZUNvdW50ZXIgPSBjeWNsZUNvdW50ZXJzLmdldChhdWRpb05vZGUpO1xuICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgZXhwZWN0ZWQgY3ljbGUgY291bnQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoYXVkaW9Ob2RlLmNvbnRleHQpO1xuICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgIGlmIChjeWNsZUNvdW50ZXIgPT09IGNvdW50KSB7XG4gICAgICAgICAgICBjeWNsZUNvdW50ZXJzLmRlbGV0ZShhdWRpb05vZGUpO1xuICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgaXNBY3RpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgb3V0cHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG91dHB1dCBvZiBvdXRwdXRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUob3V0cHV0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXRbMV0sIG91dHB1dFsyXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvUGFyYW0gPSBnZXROYXRpdmVBdWRpb1BhcmFtKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvUGFyYW0sIG91dHB1dFsxXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjeWNsZUNvdW50ZXJzLnNldChhdWRpb05vZGUsIGN5Y2xlQ291bnRlciAtIGNvdW50KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVjcmVtZW50LWN5Y2xlLWNvdW50ZXIuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGVsYXlUaW1lOiAwLFxuICAgIG1heERlbGF5VGltZTogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVEZWxheU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBEZWxheU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEZWxheU5vZGUgPSBjcmVhdGVOYXRpdmVEZWxheU5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBkZWxheU5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVEZWxheU5vZGVSZW5kZXJlcihtZXJnZWRPcHRpb25zLm1heERlbGF5VGltZSkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVEZWxheU5vZGUsIGRlbGF5Tm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIG1lcmdlZE9wdGlvbnMubWF4RGVsYXlUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGVsYXlUaW1lKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RlbGF5VGltZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsYXktbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVEZWxheU5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAobWF4RGVsYXlUaW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRGVsYXlOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZURlbGF5Tm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZURlbGF5Tm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlRGVsYXlOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVsYXlOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlRGVsYXlOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlRGVsYXlOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlRGVsYXlOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlRGVsYXlOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlRGVsYXlOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGVsYXlUaW1lOiBuYXRpdmVEZWxheU5vZGUuZGVsYXlUaW1lLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBtYXhEZWxheVRpbWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZURlbGF5Tm9kZSA9IGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlRGVsYXlOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlRGVsYXlOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlRGVsYXlOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZGVsYXlUaW1lLCBuYXRpdmVEZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRlbGF5VGltZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlRGVsYXlOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVEZWxheU5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZSA9IHJlbmRlcmVkTmF0aXZlRGVsYXlOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlRGVsYXlOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVEZWxheU5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsYXktbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVEZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChwaWNrRWxlbWVudEZyb21TZXQpID0+IHtcbiAgICByZXR1cm4gKGFjdGl2ZUlucHV0cywgc291cmNlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgICAgIHJldHVybiBwaWNrRWxlbWVudEZyb21TZXQoYWN0aXZlSW5wdXRzW2lucHV0XSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZURlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlID0gKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYXVkaW9Xb3JrbGV0Tm9kZSkgPT4ge1xuICAgICAgICBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMobmF0aXZlQ29udGV4dCkuZGVsZXRlKGF1ZGlvV29ya2xldE5vZGUpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0RlbGF5Tm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ2RlbGF5VGltZScgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBpc0RlbGF5Tm9kZSB9IGZyb20gJy4uL2d1YXJkcy9kZWxheS1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVEZXRlY3RDeWNsZXMgPSAoYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0VmFsdWVGb3JLZXkpID0+IHtcbiAgICByZXR1cm4gZnVuY3Rpb24gZGV0ZWN0Q3ljbGVzKGNoYWluLCBuZXh0TGluaykge1xuICAgICAgICBjb25zdCBhdWRpb05vZGUgPSBpc0F1ZGlvTm9kZShuZXh0TGluaykgPyBuZXh0TGluayA6IGdldFZhbHVlRm9yS2V5KGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgbmV4dExpbmspO1xuICAgICAgICBpZiAoaXNEZWxheU5vZGUoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFpblswXSA9PT0gYXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gW2NoYWluXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhaW4uaW5jbHVkZXMoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgb3V0cHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20ob3V0cHV0cylcbiAgICAgICAgICAgIC5tYXAoKG91dHB1dENvbm5lY3Rpb24pID0+IGRldGVjdEN5Y2xlcyhbLi4uY2hhaW4sIGF1ZGlvTm9kZV0sIG91dHB1dENvbm5lY3Rpb25bMF0pKVxuICAgICAgICAgICAgLnJlZHVjZSgobWVyZ2VkQ3ljbGVzLCBuZXN0ZWRDeWNsZXMpID0+IG1lcmdlZEN5Y2xlcy5jb25jYXQobmVzdGVkQ3ljbGVzKSwgW10pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGV0ZWN0LWN5Y2xlcy5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZSc7XG5jb25zdCBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4ID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBvdXRwdXRBdWRpb05vZGUgPSBvdXRwdXRBdWRpb05vZGVzW291dHB1dF07XG4gICAgaWYgKG91dHB1dEF1ZGlvTm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGU7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMgPSAoY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG91dHB1dEF1ZGlvTm9kZXMsIGRlc3RpbmF0aW9uT3JPdXRwdXQgPSB1bmRlZmluZWQsIG91dHB1dCA9IHVuZGVmaW5lZCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGVzLmZvckVhY2goKG91dHB1dEF1ZGlvTm9kZSkgPT4gb3V0cHV0QXVkaW9Ob2RlLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIGRlc3RpbmF0aW9uT3JPdXRwdXQpLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb25Pck91dHB1dCkpIHtcbiAgICAgICAgICAgIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGVzLmZvckVhY2goKG91dHB1dEF1ZGlvTm9kZSkgPT4gb3V0cHV0QXVkaW9Ob2RlLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlucHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwLCBpbnB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIDApO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGlzY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBhdHRhY2s6IDAuMDAzLFxuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnY2xhbXBlZC1tYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBrbmVlOiAzMCxcbiAgICByYXRpbzogMTIsXG4gICAgcmVsZWFzZTogMC4yNSxcbiAgICB0aHJlc2hvbGQ6IC0yNFxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRHluYW1pY3NDb21wcmVzc29yTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2F0dGFjayA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjayk7XG4gICAgICAgICAgICB0aGlzLl9rbmVlID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUua25lZSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZTtcbiAgICAgICAgICAgIHRoaXMuX3JhdGlvID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmF0aW8pO1xuICAgICAgICAgICAgdGhpcy5fcmVsZWFzZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgdGhpcy5fdGhyZXNob2xkID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUudGhyZXNob2xkKTtcbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDAuMDA2KTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgYXR0YWNrKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2F0dGFjaztcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzEwODogU2FmYXJpIGFsbG93cyBhIGNoYW5uZWxDb3VudCBvZiB0aHJlZSBhbmQgYWJvdmUgd2hpY2ggaXMgd2h5IHRoZSBnZXR0ZXIgYW5kIHNldHRlciBuZWVkcyB0byBiZSBvdmVyd3JpdHRlbiBoZXJlLlxuICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzQ2hhbm5lbENvdW50ID0gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gMikge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gcHJldmlvdXNDaGFubmVsQ291bnQ7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzEwOTogT25seSBDaHJvbWUgYW5kIEZpcmVmb3ggZGlzYWxsb3cgYSBjaGFubmVsQ291bnRNb2RlIG9mICdtYXgnIHlldCB3aGljaCBpcyB3aHkgdGhlIGdldHRlciBhbmQgc2V0dGVyIG5lZWRzIHRvIGJlXG4gICAgICAgICAqIG92ZXJ3cml0dGVuIGhlcmUuXG4gICAgICAgICAqL1xuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzQ2hhbm5lbENvdW50ID0gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlID0gcHJldmlvdXNDaGFubmVsQ291bnQ7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQga25lZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9rbmVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCByYXRpbygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yYXRpbztcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmVkdWN0aW9uKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxMTE6IFNhZmFyaSByZXR1cm5zIGFuIEF1ZGlvUGFyYW0gaW5zdGVhZCBvZiBhIG51bWJlci5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWR1Y3Rpb24udmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVkdWN0aW9uLnZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVkdWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGdldCByZWxlYXNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3JlbGVhc2U7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHRocmVzaG9sZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aHJlc2hvbGQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmVcbiAgICAgICAgICAgICAqIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGtuZWU6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUua25lZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcmF0aW86IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmF0aW8udmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVsZWFzZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdGhyZXNob2xkOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZC52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmF0dGFjaywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2spO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkua25lZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5rbmVlKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnJhdGlvLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnJlbGVhc2UsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVsZWFzZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS50aHJlc2hvbGQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUudGhyZXNob2xkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmF0dGFjaywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2spO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmtuZWUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUua25lZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucmF0aW8sIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmF0aW8pO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnJlbGVhc2UsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVsZWFzZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkudGhyZXNob2xkLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWR5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVFbmNvZGluZ0Vycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0VuY29kaW5nRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWVuY29kaW5nLWVycm9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVFdmFsdWF0ZVNvdXJjZSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKHNvdXJjZSkgPT4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgcmVqZWN0KG5ldyBTeW50YXhFcnJvcigpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBoZWFkID0gd2luZG93LmRvY3VtZW50LmhlYWQ7XG4gICAgICAgIGlmIChoZWFkID09PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgcmVqZWN0KG5ldyBTeW50YXhFcnJvcigpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHNjcmlwdCA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgICAgICAgIC8vIEB0b2RvIFNhZmFyaSBkb2Vzbid0IGxpa2UgVVJMcyB3aXRoIGEgdHlwZSBvZiAnYXBwbGljYXRpb24vamF2YXNjcmlwdDsgY2hhcnNldD11dGYtOCcuXG4gICAgICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3NvdXJjZV0sIHsgdHlwZTogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnIH0pO1xuICAgICAgICAgICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsT25FcnJvckhhbmRsZXIgPSB3aW5kb3cub25lcnJvcjtcbiAgICAgICAgICAgIGNvbnN0IHJlbW92ZUVycm9yRXZlbnRMaXN0ZW5lckFuZFJldm9rZVVybCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB3aW5kb3cub25lcnJvciA9IG9yaWdpbmFsT25FcnJvckhhbmRsZXI7XG4gICAgICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHdpbmRvdy5vbmVycm9yID0gKG1lc3NhZ2UsIHNyYywgbGluZW5vLCBjb2xubywgZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBFZGdlIHRoaW5rcyB0aGUgc291cmNlIGlzIHRoZSBvbmUgb2YgdGhlIGh0bWwgZG9jdW1lbnQuXG4gICAgICAgICAgICAgICAgaWYgKHNyYyA9PT0gdXJsIHx8IChzcmMgPT09IHdpbmRvdy5sb2NhdGlvbi5ocmVmICYmIGxpbmVubyA9PT0gMSAmJiBjb2xubyA9PT0gMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRXJyb3JFdmVudExpc3RlbmVyQW5kUmV2b2tlVXJsKCk7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsT25FcnJvckhhbmRsZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsT25FcnJvckhhbmRsZXIobWVzc2FnZSwgc3JjLCBsaW5lbm8sIGNvbG5vLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHNjcmlwdC5vbmVycm9yID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlbW92ZUVycm9yRXZlbnRMaXN0ZW5lckFuZFJldm9rZVVybCgpO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBTeW50YXhFcnJvcigpKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzY3JpcHQub25sb2FkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlbW92ZUVycm9yRXZlbnRMaXN0ZW5lckFuZFJldm9rZVVybCgpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzY3JpcHQuc3JjID0gdXJsO1xuICAgICAgICAgICAgc2NyaXB0LnR5cGUgPSAnbW9kdWxlJztcbiAgICAgICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2YWx1YXRlLXNvdXJjZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRXZlbnRUYXJnZXRDb25zdHJ1Y3RvciA9ICh3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBFdmVudFRhcmdldCB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVFdmVudFRhcmdldCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRXZlbnRUYXJnZXQgPSBfbmF0aXZlRXZlbnRUYXJnZXQ7XG4gICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICB9XG4gICAgICAgIGFkZEV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxldCB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IHRoaXMuX2xpc3RlbmVycy5nZXQobGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIGlmICh3cmFwcGVkRXZlbnRMaXN0ZW5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdyYXBwZWRFdmVudExpc3RlbmVyID0gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgbGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9saXN0ZW5lcnMuc2V0KGxpc3RlbmVyLCB3cmFwcGVkRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlRXZlbnRUYXJnZXQuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCB3cmFwcGVkRXZlbnRMaXN0ZW5lciwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZGlzcGF0Y2hFdmVudChldmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0LmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgbGlzdGVuZXIsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRFdmVudExpc3RlbmVyID0gbGlzdGVuZXIgPT09IG51bGwgPyB1bmRlZmluZWQgOiB0aGlzLl9saXN0ZW5lcnMuZ2V0KGxpc3RlbmVyKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPT09IHVuZGVmaW5lZCA/IG51bGwgOiB3cmFwcGVkRXZlbnRMaXN0ZW5lciwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV2ZW50LXRhcmdldC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUgPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChjdXJyZW50VGltZSwgc2FtcGxlUmF0ZSwgZm4pID0+IHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMod2luZG93LCB7XG4gICAgICAgICAgICBjdXJyZW50RnJhbWU6IHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChjdXJyZW50VGltZSAqIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjdXJyZW50VGltZToge1xuICAgICAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBnZXQoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJyZW50VGltZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIGZuKCk7XG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICBpZiAod2luZG93ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHdpbmRvdy5jdXJyZW50RnJhbWU7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHdpbmRvdy5jdXJyZW50VGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXhwb3NlLWN1cnJlbnQtZnJhbWUtYW5kLWN1cnJlbnQtdGltZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRmV0Y2hTb3VyY2UgPSAoY3JlYXRlQWJvcnRFcnJvcikgPT4ge1xuICAgIHJldHVybiBhc3luYyAodXJsKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2F3YWl0IHJlc3BvbnNlLnRleHQoKSwgcmVzcG9uc2UudXJsXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tZW1wdHlcbiAgICAgICAgdGhyb3cgY3JlYXRlQWJvcnRFcnJvcigpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmV0Y2gtc291cmNlLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBnYWluOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdhaW5Ob2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgR2Fpbk5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZ2Fpbk5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVHYWluTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVHYWluTm9kZSwgZ2Fpbk5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzc0OiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZ2FpbiA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVHYWluTm9kZS5nYWluLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBnYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dhaW47XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdhaW4tbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVHYWluTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUdhaW5Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlR2Fpbk5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUdhaW5Ob2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVHYWluTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUdhaW5Ob2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlR2Fpbk5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZ2FpbjogbmF0aXZlR2Fpbk5vZGUuZ2Fpbi52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUdhaW5Ob2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlR2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlR2Fpbk5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlID0gcmVuZGVyZWROYXRpdmVHYWluTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUdhaW5Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdhaW4tbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSwgZ2V0VmFsdWVGb3JLZXkpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUpID0+IGdldFZhbHVlRm9yS2V5KGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRBdWRpb05vZGVSZW5kZXJlciA9IChnZXRBdWRpb05vZGVDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICAgICAgaWYgKGF1ZGlvTm9kZUNvbm5lY3Rpb25zLnJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHJlbmRlcmVyIG9mIHRoZSBnaXZlbiBBdWRpb05vZGUgaW4gdGhlIGF1ZGlvIGdyYXBoLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhdWRpb05vZGVDb25uZWN0aW9ucy5yZW5kZXJlcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1ub2RlLXJlbmRlcmVyLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRBdWRpb05vZGVUYWlsVGltZSA9IChhdWRpb05vZGVUYWlsVGltZVN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUpID0+IHsgdmFyIF9hOyByZXR1cm4gKF9hID0gYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZS5nZXQoYXVkaW9Ob2RlKSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogMDsgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldEF1ZGlvUGFyYW1SZW5kZXJlciA9IChnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0pO1xuICAgICAgICBpZiAoYXVkaW9QYXJhbUNvbm5lY3Rpb25zLnJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHJlbmRlcmVyIG9mIHRoZSBnaXZlbiBBdWRpb1BhcmFtIGluIHRoZSBhdWRpbyBncmFwaC4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXVkaW9QYXJhbUNvbm5lY3Rpb25zLnJlbmRlcmVyO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLXBhcmFtLXJlbmRlcmVyLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICByZXR1cm4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1iYWNrdXAtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdJbnZhbGlkU3RhdGVFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW52YWxpZC1zdGF0ZS1lcnJvci5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4vaW52YWxpZC1zdGF0ZS1lcnJvcic7XG5leHBvcnQgY29uc3QgY3JlYXRlR2V0TmF0aXZlQ29udGV4dCA9IChjb250ZXh0U3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGNvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGNvbnRleHRTdG9yZS5nZXQoY29udGV4dCk7XG4gICAgICAgIGlmIChuYXRpdmVDb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1uYXRpdmUtY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGxldCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgaWYgKGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE0MTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY3JlYXRpbmcgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRoIGxlc3MgdGhhbiA0NDEwMCBIei5cbiAgICAgICAgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoMSwgMSwgNDQxMDApO1xuICAgICAgICBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUuc2V0KG5hdGl2ZUNvbnRleHQsIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICByZXR1cm4gYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1vci1jcmVhdGUtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID0gKHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID0gdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgIGlmICh1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY29udGV4dCBoYXMgbm8gc2V0IG9mIEF1ZGlvV29ya2xldE5vZGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXM7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGVzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW52YWxpZEFjY2Vzc0Vycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnZhbGlkLWFjY2Vzcy1lcnJvci5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW52YWxpZC1hY2Nlc3MtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBJSVJGaWx0ZXJOb2RlR2V0RnJlcXVlbmN5UmVzcG9uc2VNZXRob2QgPSAobmF0aXZlSUlSRmlsdGVyTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUlJUkZpbHRlck5vZGUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UgPSAoKGdldEZyZXF1ZW5jeVJlc3BvbnNlKSA9PiB7XG4gICAgICAgIHJldHVybiAoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBpZiAoZnJlcXVlbmN5SHoubGVuZ3RoICE9PSBtYWdSZXNwb25zZS5sZW5ndGggfHwgbWFnUmVzcG9uc2UubGVuZ3RoICE9PSBwaGFzZVJlc3BvbnNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGdldEZyZXF1ZW5jeVJlc3BvbnNlLmNhbGwobmF0aXZlSUlSRmlsdGVyTm9kZSwgZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVJSVJGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWlpci1maWx0ZXItbm9kZS1nZXQtZnJlcXVlbmN5LXJlc3BvbnNlLW1ldGhvZC5qcy5tYXAiLCJpbXBvcnQgeyB3cmFwSUlSRmlsdGVyTm9kZUdldEZyZXF1ZW5jeVJlc3BvbnNlTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWlpci1maWx0ZXItbm9kZS1nZXQtZnJlcXVlbmN5LXJlc3BvbnNlLW1ldGhvZCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUsIGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBJSVJGaWx0ZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUobmF0aXZlQ29udGV4dCwgaXNPZmZsaW5lID8gbnVsbCA6IGNvbnRleHQuYmFzZUxhdGVuY3ksIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaWlyRmlsdGVyTm9kZVJlbmRlcmVyID0gKChpc09mZmxpbmUgPyBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIobWVyZ2VkT3B0aW9ucy5mZWVkYmFjaywgbWVyZ2VkT3B0aW9ucy5mZWVkZm9yd2FyZCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlSUlSRmlsdGVyTm9kZSwgaWlyRmlsdGVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMjMgJiAjMjQ6IEZpcmVmb3hEZXZlbG9wZXIgZG9lcyBub3QgdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yLlxuICAgICAgICAgICAgLy8gQHRvZG8gV3JpdGUgYSB0ZXN0IHdoaWNoIGFsbG93cyBvdGhlciBicm93c2VycyB0byByZW1haW4gdW5wYXRjaGVkLlxuICAgICAgICAgICAgd3JhcElJUkZpbHRlck5vZGVHZXRGcmVxdWVuY3lSZXNwb25zZU1ldGhvZChuYXRpdmVJSVJGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUlJUkZpbHRlck5vZGUgPSBuYXRpdmVJSVJGaWx0ZXJOb2RlO1xuICAgICAgICAgICAgLy8gQHRvZG8gRGV0ZXJtaW5lIGEgbWVhbmluZ2Z1bCB0YWlsLXRpbWUgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIG9uZSBzZWNvbmQuXG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVJSVJGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlpci1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCIvLyBUaGlzIGltcGxlbWVudGF0aW9uIGFzIHNoYW1lbGVzc2x5IGluc3BpcmVkIGJ5IHNvdXJjZSBjb2RlIG9mXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4vLyB7QGxpbmsgaHR0cHM6Ly9jaHJvbWl1bS5nb29nbGVzb3VyY2UuY29tL2Nocm9taXVtL3NyYy5naXQvKy9tYXN0ZXIvdGhpcmRfcGFydHkvV2ViS2l0L1NvdXJjZS9wbGF0Zm9ybS9hdWRpby9JSVJGaWx0ZXIuY3BwfENocm9taXVtJ3MgSUlSRmlsdGVyfS5cbmV4cG9ydCBjb25zdCBmaWx0ZXJCdWZmZXIgPSAoZmVlZGJhY2ssIGZlZWRiYWNrTGVuZ3RoLCBmZWVkZm9yd2FyZCwgZmVlZGZvcndhcmRMZW5ndGgsIG1pbkxlbmd0aCwgeEJ1ZmZlciwgeUJ1ZmZlciwgYnVmZmVySW5kZXgsIGJ1ZmZlckxlbmd0aCwgaW5wdXQsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgIGxldCBpID0gYnVmZmVySW5kZXg7XG4gICAgZm9yIChsZXQgaiA9IDA7IGogPCBpbnB1dExlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGxldCB5ID0gZmVlZGZvcndhcmRbMF0gKiBpbnB1dFtqXTtcbiAgICAgICAgZm9yIChsZXQgayA9IDE7IGsgPCBtaW5MZW5ndGg7IGsgKz0gMSkge1xuICAgICAgICAgICAgY29uc3QgeCA9IChpIC0gaykgJiAoYnVmZmVyTGVuZ3RoIC0gMSk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYml0d2lzZVxuICAgICAgICAgICAgeSArPSBmZWVkZm9yd2FyZFtrXSAqIHhCdWZmZXJbeF07XG4gICAgICAgICAgICB5IC09IGZlZWRiYWNrW2tdICogeUJ1ZmZlclt4XTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBrID0gbWluTGVuZ3RoOyBrIDwgZmVlZGZvcndhcmRMZW5ndGg7IGsgKz0gMSkge1xuICAgICAgICAgICAgeSArPSBmZWVkZm9yd2FyZFtrXSAqIHhCdWZmZXJbKGkgLSBrKSAmIChidWZmZXJMZW5ndGggLSAxKV07IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYml0d2lzZVxuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGsgPSBtaW5MZW5ndGg7IGsgPCBmZWVkYmFja0xlbmd0aDsgayArPSAxKSB7XG4gICAgICAgICAgICB5IC09IGZlZWRiYWNrW2tdICogeUJ1ZmZlclsoaSAtIGspICYgKGJ1ZmZlckxlbmd0aCAtIDEpXTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby1iaXR3aXNlXG4gICAgICAgIH1cbiAgICAgICAgeEJ1ZmZlcltpXSA9IGlucHV0W2pdO1xuICAgICAgICB5QnVmZmVyW2ldID0geTtcbiAgICAgICAgaSA9IChpICsgMSkgJiAoYnVmZmVyTGVuZ3RoIC0gMSk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYml0d2lzZVxuICAgICAgICBvdXRwdXRbal0gPSB5O1xuICAgIH1cbiAgICByZXR1cm4gaTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1maWx0ZXItYnVmZmVyLmpzLm1hcCIsImltcG9ydCB7IGZpbHRlckJ1ZmZlciB9IGZyb20gJy4uL2hlbHBlcnMvZmlsdGVyLWJ1ZmZlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmNvbnN0IGZpbHRlckZ1bGxCdWZmZXIgPSAocmVuZGVyZWRCdWZmZXIsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGZlZWRiYWNrLCBmZWVkZm9yd2FyZCkgPT4ge1xuICAgIGNvbnN0IGNvbnZlcnRlZEZlZWRiYWNrID0gZmVlZGJhY2sgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBmZWVkYmFjayA6IG5ldyBGbG9hdDY0QXJyYXkoZmVlZGJhY2spO1xuICAgIGNvbnN0IGNvbnZlcnRlZEZlZWRmb3J3YXJkID0gZmVlZGZvcndhcmQgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBmZWVkZm9yd2FyZCA6IG5ldyBGbG9hdDY0QXJyYXkoZmVlZGZvcndhcmQpO1xuICAgIGNvbnN0IGZlZWRiYWNrTGVuZ3RoID0gY29udmVydGVkRmVlZGJhY2subGVuZ3RoO1xuICAgIGNvbnN0IGZlZWRmb3J3YXJkTGVuZ3RoID0gY29udmVydGVkRmVlZGZvcndhcmQubGVuZ3RoO1xuICAgIGNvbnN0IG1pbkxlbmd0aCA9IE1hdGgubWluKGZlZWRiYWNrTGVuZ3RoLCBmZWVkZm9yd2FyZExlbmd0aCk7XG4gICAgaWYgKGNvbnZlcnRlZEZlZWRiYWNrWzBdICE9PSAxKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmVlZGJhY2tMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29udmVydGVkRmVlZGZvcndhcmRbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBmZWVkZm9yd2FyZExlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb252ZXJ0ZWRGZWVkYmFja1tpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBidWZmZXJMZW5ndGggPSAzMjtcbiAgICBjb25zdCB4QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgIGNvbnN0IHlCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgY29uc3QgZmlsdGVyZWRCdWZmZXIgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcihyZW5kZXJlZEJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzLCByZW5kZXJlZEJ1ZmZlci5sZW5ndGgsIHJlbmRlcmVkQnVmZmVyLnNhbXBsZVJhdGUpO1xuICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSByZW5kZXJlZEJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZDaGFubmVsczsgaSArPSAxKSB7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gcmVuZGVyZWRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSk7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGZpbHRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICB4QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgIHlCdWZmZXIuZmlsbCgwKTtcbiAgICAgICAgZmlsdGVyQnVmZmVyKGNvbnZlcnRlZEZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgY29udmVydGVkRmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXIsIHlCdWZmZXIsIDAsIGJ1ZmZlckxlbmd0aCwgaW5wdXQsIG91dHB1dCk7XG4gICAgfVxuICAgIHJldHVybiBmaWx0ZXJlZEJ1ZmZlcjtcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoZmVlZGJhY2ssIGZlZWRmb3J3YXJkKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBmaWx0ZXJlZEJ1ZmZlclByb21pc2UgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUlJUkZpbHRlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlSUlSRmlsdGVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAvLyBCdWcgIzk6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IElJUkZpbHRlck5vZGVzLlxuICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlSUlSRmlsdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghbmF0aXZlSUlSRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGRlZmluZXMgdGhlIHBhcmFtZXRlcnMgb2YgY3JlYXRlSUlSRmlsdGVyKCkgYXMgYXJyYXlzIG9mIG51bWJlcnMuXG4gICAgICAgICAgICAgICAgbmF0aXZlSUlSRmlsdGVyTm9kZSA9IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlSUlSRmlsdGVyKGZlZWRmb3J3YXJkLCBmZWVkYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9PT0gbnVsbCA/IG5hdGl2ZUlJUkZpbHRlck5vZGUgOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZEJ1ZmZlclByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZ2V0cyBub3QgaW5pdGlhbGl6ZWQgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgICAgICBwcm94eS5jb250ZXh0LmRlc3RpbmF0aW9uLmNoYW5uZWxDb3VudCwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICAgICAgICAgIHByb3h5LmNvbnRleHQubGVuZ3RoLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZEJ1ZmZlclByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZEJ1ZmZlciA9IGF3YWl0IHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlckZ1bGxCdWZmZXIocmVuZGVyZWRCdWZmZXIsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGZlZWRiYWNrLCBmZWVkZm9yd2FyZCk7XG4gICAgICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQnVmZmVyID0gYXdhaXQgZmlsdGVyZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBmaWx0ZXJlZEJ1ZmZlcjtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVJSVJGaWx0ZXJOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVJSVJGaWx0ZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlpci1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby1ub2RlLW91dHB1dC1jb25uZWN0aW9uJztcbmV4cG9ydCBjb25zdCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXJGYWN0b3J5ID0gKGN5Y2xlQ291bnRlcnMsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBpc0FjdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoaXNPZmZsaW5lKSA9PiB7XG4gICAgICAgIHJldHVybiAoYXVkaW9Ob2RlLCBjb3VudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3ljbGVDb3VudGVyID0gY3ljbGVDb3VudGVycy5nZXQoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGlmIChjeWNsZUNvdW50ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmIGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlU291cmNlQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgb3V0cHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBvdXRwdXQgb2Ygb3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbihvdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUob3V0cHV0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXRbMV0sIG91dHB1dFsyXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvUGFyYW0gPSBnZXROYXRpdmVBdWRpb1BhcmFtKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtLCBvdXRwdXRbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuc2V0KGF1ZGlvTm9kZSwgY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY3ljbGVDb3VudGVycy5zZXQoYXVkaW9Ob2RlLCBjeWNsZUNvdW50ZXIgKyBjb3VudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmNyZW1lbnQtY3ljbGUtY291bnRlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueUF1ZGlvQ29udGV4dCA9IChjb250ZXh0U3RvcmUsIGlzTmF0aXZlQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gY29udGV4dFN0b3JlLmdldChhbnl0aGluZyk7XG4gICAgICAgIHJldHVybiBpc05hdGl2ZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSB8fCBpc05hdGl2ZUF1ZGlvQ29udGV4dChhbnl0aGluZyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hbnktYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlBdWRpb05vZGUgPSAoYXVkaW9Ob2RlU3RvcmUsIGlzTmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4gYXVkaW9Ob2RlU3RvcmUuaGFzKGFueXRoaW5nKSB8fCBpc05hdGl2ZUF1ZGlvTm9kZShhbnl0aGluZyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYW55LWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55QXVkaW9QYXJhbSA9IChhdWRpb1BhcmFtU3RvcmUsIGlzTmF0aXZlQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IGF1ZGlvUGFyYW1TdG9yZS5oYXMoYW55dGhpbmcpIHx8IGlzTmF0aXZlQXVkaW9QYXJhbShhbnl0aGluZyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYW55LWF1ZGlvLXBhcmFtLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgPSAoY29udGV4dFN0b3JlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBjb250ZXh0U3RvcmUuZ2V0KGFueXRoaW5nKTtcbiAgICAgICAgcmV0dXJuIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSB8fCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoYW55dGhpbmcpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYW55LW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVBdWRpb0NvbnRleHQgPSAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9Ob2RlID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdyAhPT0gbnVsbCAmJiB0eXBlb2Ygd2luZG93LkF1ZGlvTm9kZSA9PT0gJ2Z1bmN0aW9uJyAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIHdpbmRvdy5BdWRpb05vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVBdWRpb1BhcmFtID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdyAhPT0gbnVsbCAmJiB0eXBlb2Ygd2luZG93LkF1ZGlvUGFyYW0gPT09ICdmdW5jdGlvbicgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiB3aW5kb3cuQXVkaW9QYXJhbTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVDb250ZXh0ID0gKGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiBpc05hdGl2ZUF1ZGlvQ29udGV4dChhbnl0aGluZykgfHwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGFueXRoaW5nKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIGFueXRoaW5nIGluc3RhbmNlb2YgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNTZWN1cmVDb250ZXh0ID0gKHdpbmRvdykgPT4gd2luZG93ICE9PSBudWxsICYmIHdpbmRvdy5pc1NlY3VyZUNvbnRleHQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1zZWN1cmUtY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAvLyBCdWcgIzE3MTogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgd2l0aCBhbiBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlLCBudWxsKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWVkaWFFbGVtZW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZS5tZWRpYUVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTczOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgd2l0aCBhbiBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RyZWFtKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUuc3RyZWFtO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgLy8gQnVnICMxNzI6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgd2l0aCBhbiBPZmZsaW5lQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCBudWxsKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1lZGlhU3RyZWFtKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLm1lZGlhU3RyZWFtO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQXVkaW9HcmFwaCB9IGZyb20gJy4uL2hlbHBlcnMvZGVhY3RpdmF0ZS1hdWRpby1ncmFwaCc7XG5pbXBvcnQgeyBpc1ZhbGlkTGF0ZW5jeUhpbnQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXZhbGlkLWxhdGVuY3ktaGludCc7XG5leHBvcnQgY29uc3QgY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNaW5pbWFsQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTkyIFNhZmFyaSBkb2VzIHRocm93IGEgU3ludGF4RXJyb3IgaWYgdGhlIHNhbXBsZVJhdGUgaXMgbm90IHN1cHBvcnRlZC5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyICYmIGVyci5tZXNzYWdlID09PSAnc2FtcGxlUmF0ZSBpcyBub3QgaW4gcmFuZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTMxIFNhZmFyaSByZXR1cm5zIG51bGwgd2hlbiB0aGVyZSBhcmUgZm91ciBvdGhlciBBdWRpb0NvbnRleHRzIHJ1bm5pbmcgYWxyZWFkeS5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVVbmtub3duRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTEgT25seSBDaHJvbWUgYW5kIEVkZ2UgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGdpdmVuIGxhdGVuY3lIaW50IGlzIGludmFsaWQuXG4gICAgICAgICAgICBpZiAoIWlzVmFsaWRMYXRlbmN5SGludChvcHRpb25zLmxhdGVuY3lIaW50KSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFRoZSBwcm92aWRlZCB2YWx1ZSAnJHtvcHRpb25zLmxhdGVuY3lIaW50fScgaXMgbm90IGEgdmFsaWQgZW51bSB2YWx1ZSBvZiB0eXBlIEF1ZGlvQ29udGV4dExhdGVuY3lDYXRlZ29yeS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTUwIFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHNldHRpbmcgdGhlIHNhbXBsZVJhdGUuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5zYW1wbGVSYXRlICE9PSB1bmRlZmluZWQgJiYgbmF0aXZlQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUgIT09IG9wdGlvbnMuc2FtcGxlUmF0ZSkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVBdWRpb0NvbnRleHQsIDIpO1xuICAgICAgICAgICAgY29uc3QgeyBsYXRlbmN5SGludCB9ID0gb3B0aW9ucztcbiAgICAgICAgICAgIGNvbnN0IHsgc2FtcGxlUmF0ZSB9ID0gbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgLy8gQHRvZG8gVGhlIHZhbHVlcyBmb3IgJ2JhbGFuY2VkJywgJ2ludGVyYWN0aXZlJyBhbmQgJ3BsYXliYWNrJyBhcmUganVzdCBjb3BpZWQgZnJvbSBDaHJvbWUncyBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICAgIHRoaXMuX2Jhc2VMYXRlbmN5ID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5ID09PSAnbnVtYmVyJ1xuICAgICAgICAgICAgICAgICAgICA/IG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeVxuICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnYmFsYW5jZWQnXG4gICAgICAgICAgICAgICAgICAgICAgICA/IDUxMiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdpbnRlcmFjdGl2ZScgfHwgbGF0ZW5jeUhpbnQgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMjU2IC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdwbGF5YmFjaydcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAxMDI0IC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IC8qXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQHRvZG8gVGhlIG1pbiAoMjU2KSBhbmQgbWF4ICgxNjM4NCkgdmFsdWVzIGFyZSB0YWtlbiBmcm9tIHRoZSBhbGxvd2VkIGJ1ZmZlclNpemUgdmFsdWVzIG9mIGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBTY3JpcHRQcm9jZXNzb3JOb2RlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE1hdGgubWF4KDIsIE1hdGgubWluKDEyOCwgTWF0aC5yb3VuZCgobGF0ZW5jeUhpbnQgKiBzYW1wbGVSYXRlKSAvIDEyOCkpKSAqIDEyOCkgLyBzYW1wbGVSYXRlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0ID0gbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgLy8gQnVnICMxODg6IFNhZmFyaSB3aWxsIHNldCB0aGUgY29udGV4dCdzIHN0YXRlIHRvICdpbnRlcnJ1cHRlZCcgaW4gY2FzZSB0aGUgdXNlciBzd2l0Y2hlcyB0YWJzLlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5nYWluLnZhbHVlID0gMWUtMzc7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuY29ubmVjdCh0aGlzLl9uYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0YXJ0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjMzQ6IENocm9tZSBhbmQgRWRnZSBwcmV0ZW5kIHRvIGJlIHJ1bm5pbmcgcmlnaHQgYXdheSwgYnV0IGZpcmUgYW4gb25zdGF0ZWNoYW5nZSBldmVudCB3aGVuIHRoZSBzdGF0ZSBhY3R1YWxseSBjaGFuZ2VzXG4gICAgICAgICAgICAgKiB0byAncnVubmluZycuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gJ3N1c3BlbmRlZCc7XG4gICAgICAgICAgICAgICAgY29uc3QgcmV2b2tlU3RhdGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXZva2VTdGF0ZSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXZva2VTdGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJhc2VMYXRlbmN5KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VMYXRlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZSAhPT0gbnVsbCA/IHRoaXMuX3N0YXRlIDogdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIGNsb3NlKCkge1xuICAgICAgICAgICAgLy8gQnVnICMzNTogRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgQXVkaW9Db250ZXh0IHdhcyBjbG9zZWQgYmVmb3JlLlxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5jbG9zZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMzNDogSWYgdGhlIHN0YXRlIHdhcyBzZXQgdG8gc3VzcGVuZGVkIGJlZm9yZSBpdCBzaG91bGQgYmUgcmV2b2tlZCBub3cuXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5jbG9zZSgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVHYWluTm9kZSAhPT0gbnVsbCAmJiB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWFjdGl2YXRlQXVkaW9HcmFwaCh0aGlzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VtZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlUHJvbWlzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzdW1lKCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlc3VtZSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU1OiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIGluc3RlYWQgb2YgYW4gSW52YWxpZFN0YXRlRXJyb3IuXG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkIHx8IGVyci5jb2RlID09PSAxNSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBzdXNwZW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdXNwZW5kKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IENPTlRFWFRfU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvTGlzdGVuZXIsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWluaW1hbEJhc2VBdWRpb0NvbnRleHQgZXh0ZW5kcyBldmVudFRhcmdldENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoX25hdGl2ZUNvbnRleHQsIG51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgIHN1cGVyKF9uYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnRleHQgPSBfbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgIENPTlRFWFRfU1RPUkUuc2V0KHRoaXMsIF9uYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoX25hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZS5zZXQoX25hdGl2ZUNvbnRleHQsIG5ldyBTZXQoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9kZXN0aW5hdGlvbiA9IG5ldyBhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yKHRoaXMsIG51bWJlck9mQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXIgPSBjcmVhdGVBdWRpb0xpc3RlbmVyKHRoaXMsIF9uYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIHRoaXMuX29uc3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkZXN0aW5hdGlvbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXN0aW5hdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGlzdGVuZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbGlzdGVuZXI7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uc3RhdGVjaGFuZ2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25zdGF0ZWNoYW5nZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25zdGF0ZWNoYW5nZSh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnRleHQub25zdGF0ZWNoYW5nZSA9IHdyYXBwZWRMaXN0ZW5lcjtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9uU3RhdGVDaGFuZ2UgPSB0aGlzLl9uYXRpdmVDb250ZXh0Lm9uc3RhdGVjaGFuZ2U7XG4gICAgICAgICAgICB0aGlzLl9vbnN0YXRlY2hhbmdlID0gbmF0aXZlT25TdGF0ZUNoYW5nZSAhPT0gbnVsbCAmJiBuYXRpdmVPblN0YXRlQ2hhbmdlID09PSB3cmFwcGVkTGlzdGVuZXIgPyB2YWx1ZSA6IG5hdGl2ZU9uU3RhdGVDaGFuZ2U7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVDb250ZXh0LnN0YXRlO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW5pbWFsLWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdFByb21pc2VTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAvLyBUaGlzIDEyIG51bWJlcnMgcmVwcmVzZW50IHRoZSA0OCBieXRlcyBvZiBhbiBlbXB0eSBXQVZFIGZpbGUgd2l0aCBhIHNpbmdsZSBzYW1wbGUuXG4gICAgY29uc3QgdWludDMyQXJyYXkgPSBuZXcgVWludDMyQXJyYXkoWzExNzkwMTE0MTAsIDQwLCAxMTYzMjgwNzI3LCA1NDQ1MDEwOTQsIDE2LCAxMzEwNzMsIDQ0MTAwLCAxNzY0MDAsIDEwNDg1ODAsIDE2MzUwMTcwNjAsIDQsIDBdKTtcbiAgICB0cnkge1xuICAgICAgICAvLyBCdWcgIzE6IFNhZmFyaSByZXF1aXJlcyBhIHN1Y2Nlc3NDYWxsYmFjay5cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5hdGl2ZUNvbnRleHQuZGVjb2RlQXVkaW9EYXRhKHVpbnQzMkFycmF5LmJ1ZmZlciwgKCkgPT4ge1xuICAgICAgICAgICAgLy8gSWdub3JlIHRoZSBzdWNjZXNzIGNhbGxiYWNrLlxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHByb21pc2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHByb21pc2UuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgLy8gSWdub3JlIHJlamVjdGVkIGVycm9ycy5cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LXByb21pc2Utc3VwcG9ydC5qcy5tYXAiLCJpbXBvcnQgeyBkZWFjdGl2YXRlQXVkaW9HcmFwaCB9IGZyb20gJy4uL2hlbHBlcnMvZGVhY3RpdmF0ZS1hdWRpby1ncmFwaCc7XG5pbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBudW1iZXJPZkNoYW5uZWxzOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc3RhcnRSZW5kZXJpbmcpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHQgZXh0ZW5kcyBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgLy8gIzIxIFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIGFuZCB0aGVyZWZvcmUgd291bGQgZmlyZSB0aGUgc3RhdGVjaGFuZ2UgZXZlbnQgYmVmb3JlIHRoZSBwcm9taXNlIGNhbiBiZSByZXNvbHZlZC5cbiAgICAgICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RQcm9taXNlU3VwcG9ydCwgKCkgPT4gdGVzdFByb21pc2VTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlbGF5U3RhdGVDaGFuZ2VFdmVudCA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIGRlbGF5U3RhdGVDaGFuZ2VFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWxheVN0YXRlQ2hhbmdlRXZlbnQ7XG4gICAgICAgICAgICAgICAgfSkoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuX2xlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZSA9PT0gbnVsbCA/IHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhdGUgOiB0aGlzLl9zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydFJlbmRlcmluZygpIHtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzkgJiAjNTk6IEl0IGlzIHRoZW9yZXRpY2FsbHkgcG9zc2libGUgdGhhdCBzdGFydFJlbmRlcmluZygpIHdpbGwgZmlyc3QgcmVuZGVyIGEgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuIFRoZXJlZm9yZVxuICAgICAgICAgICAgICogdGhlIHN0YXRlIG9mIHRoZSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IG1pZ2h0IG5vIHRyYW5zaXRpb24gdG8gcnVubmluZyBpbW1lZGlhdGVseS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdydW5uaW5nJztcbiAgICAgICAgICAgIHJldHVybiBzdGFydFJlbmRlcmluZyh0aGlzLmRlc3RpbmF0aW9uLCB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUF1ZGlvR3JhcGgodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBfd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1taW5pbWFsLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTW9uaXRvckNvbm5lY3Rpb25zID0gKGluc2VydEVsZW1lbnRJblNldCwgaXNOYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvTm9kZSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCkgPT4ge1xuICAgICAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBTZXQoKTtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QgPSAoKGNvbm5lY3QpID0+IHtcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTppbnZhbGlkLXZvaWQgbm8taW5mZXJyYWJsZS10eXBlc1xuICAgICAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgd2FzRGlzY29ubmVjdGVkID0gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMDtcbiAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDMgYXJndW1lbnRzIHlldC5cbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQoY29ubmVjdGlvbnMsIFtkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dF0sIChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQgJiYgY29ubmVjdGlvblsyXSA9PT0gaW5wdXQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAod2FzRGlzY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3aGVuQ29ubmVjdGVkKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICAgICAgICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQoY29ubmVjdGlvbnMsIFtkZXN0aW5hdGlvbiwgb3V0cHV0XSwgKGNvbm5lY3Rpb24pID0+IGNvbm5lY3Rpb25bMF0gPT09IGRlc3RpbmF0aW9uICYmIGNvbm5lY3Rpb25bMV0gPT09IG91dHB1dCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHdhc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB3aGVuQ29ubmVjdGVkKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KTtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QgPSAoKGRpc2Nvbm5lY3QpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdhc0Nvbm5lY3RlZCA9IGNvbm5lY3Rpb25zLnNpemUgPiAwO1xuICAgICAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdC5hcHBseShuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5jbGVhcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMSBhcmd1bWVudCB5ZXQuXG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25uZWN0aW9uWzFdID09PSBkZXN0aW5hdGlvbk9yT3V0cHV0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb25Pck91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDMgYXJndW1lbnRzIHlldC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMiBhcmd1bWVudHMgeWV0LlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb25Pck91dHB1dCwgb3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbk9yT3V0cHV0ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG91dHB1dCA9PT0gdW5kZWZpbmVkIHx8IGNvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW5wdXQgPT09IHVuZGVmaW5lZCB8fCBjb25uZWN0aW9uWzJdID09PSBpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXNEaXNjb25uZWN0ZWQgPSBjb25uZWN0aW9ucy5zaXplID09PSAwO1xuICAgICAgICAgICAgICAgIGlmICh3YXNDb25uZWN0ZWQgJiYgaXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hlbkRpc2Nvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vbml0b3ItY29ubmVjdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiA9IChuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsIG9wdGlvbikgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gb3B0aW9uc1tvcHRpb25dO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBuYXRpdmVBdWRpb05vZGVbb3B0aW9uXSkge1xuICAgICAgICBuYXRpdmVBdWRpb05vZGVbb3B0aW9uXSA9IHZhbHVlO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4vYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5leHBvcnQgY29uc3QgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyA9IChuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMpID0+IHtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCAnY2hhbm5lbENvdW50Jyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxDb3VudE1vZGUnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCAnY2hhbm5lbEludGVycHJldGF0aW9uJyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydCA9IChuYXRpdmVBbmFseXNlck5vZGUpID0+IHtcbiAgICByZXR1cm4gdHlwZW9mIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhID09PSAnZnVuY3Rpb24nO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2Qtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2QgPSAobmF0aXZlQW5hbHlzZXJOb2RlKSA9PiB7XG4gICAgbmF0aXZlQW5hbHlzZXJOb2RlLmdldEZsb2F0VGltZURvbWFpbkRhdGEgPSAoYXJyYXkpID0+IHtcbiAgICAgICAgY29uc3QgYnl0ZVRpbWVEb21haW5EYXRhID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXkubGVuZ3RoKTtcbiAgICAgICAgbmF0aXZlQW5hbHlzZXJOb2RlLmdldEJ5dGVUaW1lRG9tYWluRGF0YShieXRlVGltZURvbWFpbkRhdGEpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBNYXRoLm1heChieXRlVGltZURvbWFpbkRhdGEubGVuZ3RoLCBuYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGFycmF5W2ldID0gKGJ5dGVUaW1lRG9tYWluRGF0YVtpXSAtIDEyOCkgKiAwLjAwNzgxMjU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFycmF5O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgdGVzdEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2RTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgd3JhcEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2QnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZUZhY3RvcnkgPSAoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBbmFseXNlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgICAgIC8vIEJ1ZyAjMzc6IEZpcmVmb3ggZG9lcyBub3QgY3JlYXRlIGFuIEFuYWx5c2VyTm9kZSB3aXRoIHRoZSBkZWZhdWx0IHByb3BlcnRpZXMuXG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgLy8gQnVnICMxMTg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiBtYXhEZWNpYmVscyBpcyBub3QgbW9yZSB0aGFuIG1pbkRlY2liZWxzLlxuICAgICAgICBpZiAoIShvcHRpb25zLm1heERlY2liZWxzID4gb3B0aW9ucy5taW5EZWNpYmVscykpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ2ZmdFNpemUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ21heERlY2liZWxzJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdtaW5EZWNpYmVscycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnc21vb3RoaW5nVGltZUNvbnN0YW50Jyk7XG4gICAgICAgIC8vIEJ1ZyAjMzY6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGdldEZsb2F0VGltZURvbWFpbkRhdGEoKSB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydCwgKCkgPT4gdGVzdEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2RTdXBwb3J0KG5hdGl2ZUFuYWx5c2VyTm9kZSkpKSB7XG4gICAgICAgICAgICB3cmFwQW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZChuYXRpdmVBbmFseXNlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYW5hbHlzZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ0F1ZGlvQnVmZmVyJykpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5BdWRpb0J1ZmZlcjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlID0gKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgYXVkaW9QYXJhbSkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gb3B0aW9uc1thdWRpb1BhcmFtXTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbmF0aXZlQXVkaW9Ob2RlW2F1ZGlvUGFyYW1dLnZhbHVlKSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZVthdWRpb1BhcmFtXS52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW52YWxpZC1zdGF0ZS1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxscyA9IChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQgPSAoKHN0YXJ0KSA9PiB7XG4gICAgICAgIGxldCBpc1NjaGVkdWxlZCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gKHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikgPT4ge1xuICAgICAgICAgICAgaWYgKGlzU2NoZWR1bGVkKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YXJ0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIGlzU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzID0gKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdGFydCA9ICgoc3RhcnQpID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmICgodHlwZW9mIGR1cmF0aW9uID09PSAnbnVtYmVyJyAmJiBkdXJhdGlvbiA8IDApIHx8IG9mZnNldCA8IDAgfHwgd2hlbiA8IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSBwYXJhbWV0ZXJzIGNhbid0IGJlIG5lZ2F0aXZlLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDMgYXJndW1lbnRzIHlldC5cbiAgICAgICAgICAgIHN0YXJ0LmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCB3aGVuLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RhcnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLmpzLm1hcCIsImV4cG9ydCBjb25zdCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyA9IChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCA9ICgoc3RvcCkgPT4ge1xuICAgICAgICByZXR1cm4gKHdoZW4gPSAwKSA9PiB7XG4gICAgICAgICAgICBpZiAod2hlbiA8IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSBwYXJhbWV0ZXIgY2FuJ3QgYmUgbmVnYXRpdmUuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RvcC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3ApO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5ID0gKGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1wbGluZywgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdwbGF5YmFja1JhdGUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucywgJ2J1ZmZlcicpO1xuICAgICAgICAvLyBCdWcgIzE0OTogU2FmYXJpIGRvZXMgbm90IHlldCBzdXBwb3J0IHRoZSBkZXR1bmUgQXVkaW9QYXJhbS5cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucywgJ2xvb3AnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucywgJ2xvb3BFbmQnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgb3B0aW9ucywgJ2xvb3BTdGFydCcpO1xuICAgICAgICAvLyBCdWcgIzY5OiBTYWZhcmkgZG9lcyBhbGxvdyBjYWxscyB0byBzdGFydCgpIG9mIGFuIGFscmVhZHkgc2NoZWR1bGVkIEF1ZGlvQnVmZmVyU291cmNlTm9kZS5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxscyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTU0ICYgIzE1NTogU2FmYXJpIGRvZXMgbm90IGhhbmRsZSBvZmZzZXRzIHdoaWNoIGFyZSBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gdGhlIGR1cmF0aW9uIG9mIHRoZSBidWZmZXIuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBsaW5nKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNjI6IFNhZmFyaSBkb2VzIHRocm93IGFuIGVycm9yIHdoZW4gc3RvcCgpIGlzIGNhbGxlZCBvbiBhbiBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgd2hpY2ggaGFzIG5vIGJ1ZmZlciBhc3NpZ25lZCB0byBpdC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlcihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxOTogU2FmYXJpIGRvZXMgbm90IGlnbm9yZSBjYWxscyB0byBzdG9wKCkgb2YgYW4gYWxyZWFkeSBzdG9wcGVkIEF1ZGlvQnVmZmVyU291cmNlTm9kZS5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzU6IFNhZmFyaSB3aWxsIG5vdCBmaXJlIGFuIGVuZGVkIGV2ZW50IGlmIHRoZSBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1idWZmZXItc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAod2luZG93KSA9PiB7XG4gICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnQXVkaW9Db250ZXh0JykpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdy5BdWRpb0NvbnRleHQ7XG4gICAgfVxuICAgIHJldHVybiB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ3dlYmtpdEF1ZGlvQ29udGV4dCcpID8gd2luZG93LndlYmtpdEF1ZGlvQ29udGV4dCA6IG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVHYWluTm9kZSwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlzTm9kZU9mTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb247XG4gICAgICAgIC8vIEJ1ZyAjMTMyOiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnQuXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgIT09IGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgPSBjaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNjk6IFNhZmFyaSB0aHJvd3MgYW4gZXJyb3Igb24gZWFjaCBhdHRlbXB0IHRvIGNoYW5nZSB0aGUgY2hhbm5lbENvdW50LlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjODM6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudE1vZGUuXG4gICAgICAgIGlmIChpc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgJiYgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NzogVGhlIEF1ZGlvRGVzdGluYXRpb25Ob2RlIGluIFNhZmFyaSBkb2VzIG5vdCBpbml0aWFsaXplIHRoZSBtYXhDaGFubmVsQ291bnQgcHJvcGVydHkgY29ycmVjdGx5LlxuICAgICAgICBpZiAobmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50ID09PSAwKSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUsICdtYXhDaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IGNoYW5uZWxDb3VudFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNjg6IE5vIGJyb3dzZXIgZG9lcyB5ZXQgaGF2ZSBhbiBBdWRpb0Rlc3RpbmF0aW9uTm9kZSB3aXRoIGFuIG91dHB1dC5cbiAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICBnYWluOiAxXG4gICAgICAgIH0pO1xuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMoZ2Fpbk5vZGUsICdjaGFubmVsQ291bnQnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChnYWluTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwoZ2Fpbk5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNjk6IFNhZmFyaSB0aHJvd3MgYW4gZXJyb3Igb24gZWFjaCBhdHRlbXB0IHRvIGNoYW5nZSB0aGUgY2hhbm5lbENvdW50LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA+IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKGdhaW5Ob2RlLCAnY2hhbm5lbENvdW50TW9kZScsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGdhaW5Ob2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChnYWluTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKGdhaW5Ob2RlLCAnY2hhbm5lbEludGVycHJldGF0aW9uJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoZ2Fpbk5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKGdhaW5Ob2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnYWluTm9kZSwgJ21heENoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBAdG9kbyBUaGlzIHNob3VsZCBiZSBkaXNjb25uZWN0ZWQgd2hlbiB0aGUgY29udGV4dCBpcyBjbG9zZWQuXG4gICAgICAgIGdhaW5Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUpO1xuICAgICAgICByZXR1cm4gZ2Fpbk5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tZGVzdGluYXRpb24tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ0F1ZGlvV29ya2xldE5vZGUnKSA/IHdpbmRvdy5BdWRpb1dvcmtsZXROb2RlIDogbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0Q2xvbmFiaWxpdHlPZkF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgY29uc3QgeyBwb3J0MSB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yIGlmIHRoZSBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyBhcmUgbm90IGNsb25hYmxlLlxuICAgICAgICBwb3J0MS5wb3N0TWVzc2FnZShhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgfVxuICAgIGZpbmFsbHkge1xuICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWNsb25hYmlsaXR5LW9mLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzLm1hcCIsImltcG9ydCB7IHRlc3RDbG9uYWJpbGl0eU9mQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtY2xvbmFiaWxpdHktb2YtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWN0b3J5ID0gKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYW1lLCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucykgPT4ge1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBuZXcgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKG5hdGl2ZUNvbnRleHQsIG5hbWUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVycyA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgICAgICBsZXQgb25wcm9jZXNzb3JlcnJvciA9IG51bGw7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwge1xuICAgICAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAgICAgKiBCdWcgIzYxOiBPdmVyd3JpdGluZyB0aGUgcHJvcGVydHkgYWNjZXNzb3JzIGZvciBjaGFubmVsQ291bnQgYW5kIGNoYW5uZWxDb3VudE1vZGUgaXMgbmVjZXNzYXJ5IGFzIGxvbmcgYXMgc29tZVxuICAgICAgICAgICAgICAgICAgICAgKiBicm93c2VycyBoYXZlIG5vIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiB0byBhY2hpZXZlIGEgY29uc2lzdGVudCBiZWhhdmlvci5cbiAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTU2OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IHlldCBmaXJlIGFuIEVycm9yRXZlbnQuXG4gICAgICAgICAgICAgICAgICAgIG9ucHJvY2Vzc29yZXJyb3I6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gb25wcm9jZXNzb3JlcnJvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25wcm9jZXNzb3JlcnJvciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5hZGRFdmVudExpc3RlbmVyKCdwcm9jZXNzb3JlcnJvcicsIG9ucHJvY2Vzc29yZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUuYWRkRXZlbnRMaXN0ZW5lciA9ICgoYWRkRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAncHJvY2Vzc29yZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHR5cGVvZiBhcmdzWzFdID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXJnc1sxXVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHR5cGVvZiBhcmdzWzFdID09PSAnb2JqZWN0JyAmJiBhcmdzWzFdICE9PSBudWxsICYmIHR5cGVvZiBhcmdzWzFdLmhhbmRsZUV2ZW50ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV0uaGFuZGxlRXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodW5wYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHBhdGNoZWRFdmVudExpc3RlbmVycy5nZXQoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzWzFdID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzg6IENocm9tZSBhbmQgRWRnZSBkbyBmaXJlIGFuIGV2ZW50IG9mIHR5cGUgZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoZXZlbnQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IHsgdmFsdWU6ICdwcm9jZXNzb3JlcnJvcicgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lcihldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnBhdGNoZWRFdmVudExpc3RlbmVyKG5ldyBFcnJvckV2ZW50KGFyZ3NbMF0sIHsgLi4uZXZlbnQgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuc2V0KHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIsIGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzg6IENocm9tZSBhbmQgRWRnZSBkbyBmaXJlIGFuIGV2ZW50IG9mIHR5cGUgZXJyb3IuXG4gICAgICAgICAgICAgICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgJ2Vycm9yJywgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWRkRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIC4uLmFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUuYWRkRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5yZW1vdmVFdmVudExpc3RlbmVyID0gKChyZW1vdmVFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09ICdwcm9jZXNzb3JlcnJvcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHBhdGNoZWRFdmVudExpc3RlbmVycy5nZXQoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhdGNoZWRFdmVudExpc3RlbmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmRlbGV0ZShhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IHBhdGNoZWRFdmVudExpc3RlbmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsICdlcnJvcicsIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICM4NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBpbnZva2UgdGhlIHByb2Nlc3MoKSBmdW5jdGlvbiBpZiB0aGUgY29ycmVzcG9uZGluZyBBdWRpb1dvcmtsZXROb2RlIGlzIHVuY29ubmVjdGVkIGJ1dFxuICAgICAgICAgICAgICAgICAqIGhhcyBhbiBvdXRwdXQuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhaW46IDBcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IG5hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IG5hdGl2ZUdhaW5Ob2RlLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIERpc2Nvbm5lY3QgdGhlIGNvbm5lY3Rpb24gd2hlbiB0aGUgcHJvY2VzcygpIGZ1bmN0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXROb2RlIHJldHVybnMgZmFsc2UuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1dvcmtsZXROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNjA6IENocm9tZSAmIEVkZ2UgdGhyb3cgYW4gSW52YWxpZFN0YXRlRXJyb3IgaW5zdGVhZCBvZiBhIE5vdFN1cHBvcnRlZEVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNjE6IE9ubHkgQ2hyb21lICYgRWRnZSBoYXZlIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXROb2RlIHlldC5cbiAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGVzdENsb25hYmlsaXR5T2ZBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyhvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjb21wdXRlQnVmZmVyU2l6ZSA9IChiYXNlTGF0ZW5jeSwgc2FtcGxlUmF0ZSkgPT4ge1xuICAgIGlmIChiYXNlTGF0ZW5jeSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gNTEyO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5tYXgoNTEyLCBNYXRoLm1pbigxNjM4NCwgTWF0aC5wb3coMiwgTWF0aC5yb3VuZChNYXRoLmxvZzIoYmFzZUxhdGVuY3kgKiBzYW1wbGVSYXRlKSkpKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29tcHV0ZS1idWZmZXItc2l6ZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY2xvbmVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICAgICAgcG9ydDEub25tZXNzYWdlID0gKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgICAgICAgICAgcG9ydDIuY2xvc2UoKTtcbiAgICAgICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICAgIH07XG4gICAgICAgIHBvcnQxLm9ubWVzc2FnZWVycm9yID0gKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgICBwb3J0MS5jbG9zZSgpO1xuICAgICAgICAgICAgcG9ydDIuY2xvc2UoKTtcbiAgICAgICAgICAgIHJlamVjdChkYXRhKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGVycm9yIGlmIHRoZSBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyBhcmUgbm90IGNsb25hYmxlLlxuICAgICAgICBwb3J0Mi5wb3N0TWVzc2FnZShhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xvbmUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgY2xvbmVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyB9IGZyb20gJy4vY2xvbmUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBhc3luYyAocHJvY2Vzc29yQ29uc3RydWN0b3IsIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgY29uc3QgY2xvbmVkQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSBhd2FpdCBjbG9uZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICByZXR1cm4gbmV3IHByb2Nlc3NvckNvbnN0cnVjdG9yKGNsb25lZEF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcHJvbWlzZS5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX1RPX1BST0NFU1NPUl9NQVBTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlIH0gZnJvbSAnLi9jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3ItcHJvbWlzZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGxldCBub2RlVG9Qcm9jZXNzb3JNYXAgPSBOT0RFX1RPX1BST0NFU1NPUl9NQVBTLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICBpZiAobm9kZVRvUHJvY2Vzc29yTWFwID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbm9kZVRvUHJvY2Vzc29yTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgTk9ERV9UT19QUk9DRVNTT1JfTUFQUy5zZXQobmF0aXZlQ29udGV4dCwgbm9kZVRvUHJvY2Vzc29yTWFwKTtcbiAgICB9XG4gICAgY29uc3QgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSA9IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UocHJvY2Vzc29yQ29uc3RydWN0b3IsIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICBub2RlVG9Qcm9jZXNzb3JNYXAuc2V0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UpO1xuICAgIHJldHVybiBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNyZWF0ZS1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgY29tcHV0ZUJ1ZmZlclNpemUgfSBmcm9tICcuLi9oZWxwZXJzL2NvbXB1dGUtYnVmZmVyLXNpemUnO1xuaW1wb3J0IHsgY29weUZyb21DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LWZyb20tY2hhbm5lbCc7XG5pbXBvcnQgeyBjb3B5VG9DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LXRvLWNoYW5uZWwnO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3InO1xuaW1wb3J0IHsgY3JlYXRlTmVzdGVkQXJyYXlzIH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGUtbmVzdGVkLWFycmF5cyc7XG5pbXBvcnQgeyBSZWFkT25seU1hcCB9IGZyb20gJy4uL3JlYWQtb25seS1tYXAnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlckZhY3RvcnkgPSAoY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucykgPT4ge1xuICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZklucHV0cyA9PT0gMCAmJiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsQ291bnQgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50KVxuICAgICAgICAgICAgPyBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudFxuICAgICAgICAgICAgOiBBcnJheS5mcm9tKG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50KTtcbiAgICAgICAgLy8gQHRvZG8gQ2hlY2sgaWYgYW55IG9mIHRoZSBjaGFubmVsQ291bnQgdmFsdWVzIGlzIGdyZWF0ZXIgdGhhbiB0aGUgaW1wbGVtZW50YXRpb24ncyBtYXhpbXVtIG51bWJlciBvZiBjaGFubmVscy5cbiAgICAgICAgaWYgKG91dHB1dENoYW5uZWxDb3VudC5zb21lKChjaGFubmVsQ291bnQpID0+IGNoYW5uZWxDb3VudCA8IDEpKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXRDaGFubmVsQ291bnQubGVuZ3RoICE9PSBvcHRpb25zLm51bWJlck9mT3V0cHV0cykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlICE9PSAnZXhwbGljaXQnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG51bWJlck9mSW5wdXRDaGFubmVscyA9IG9wdGlvbnMuY2hhbm5lbENvdW50ICogb3B0aW9ucy5udW1iZXJPZklucHV0cztcbiAgICAgICAgY29uc3QgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9IG91dHB1dENoYW5uZWxDb3VudC5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSArIHZhbHVlLCAwKTtcbiAgICAgICAgY29uc3QgbnVtYmVyT2ZQYXJhbWV0ZXJzID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZCA/IDAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5sZW5ndGg7XG4gICAgICAgIC8vIEJ1ZyAjNjE6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIGJ1dCByZXF1aXJlZCBmb3IgdGhlIGZha2VyIHRvIHdvcmsuXG4gICAgICAgIGlmIChudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnMgPiA2IHx8IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPiA2KSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lc3NhZ2VDaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlcyA9IFtdO1xuICAgICAgICBjb25zdCBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICBnYWluTm9kZXMucHVzaChjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICBnYWluOiAxXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IG9wdGlvbnMuY2hhbm5lbENvdW50XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlcyA9IFtdO1xuICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZm9yIChjb25zdCB7IGRlZmF1bHRWYWx1ZSwgbWF4VmFsdWUsIG1pblZhbHVlLCBuYW1lIH0gb2YgcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBvcHRpb25zLnBhcmFtZXRlckRhdGFbbmFtZV0gIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICAgICAgPyBvcHRpb25zLnBhcmFtZXRlckRhdGFbbmFtZV1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogZGVmYXVsdFZhbHVlID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQsIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IChkZWZhdWx0VmFsdWUgPT09IHVuZGVmaW5lZCA/IDAgOiBkZWZhdWx0VmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIG1heFZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IChtYXhWYWx1ZSA9PT0gdW5kZWZpbmVkID8gTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgOiBtYXhWYWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgbWluVmFsdWU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gKG1pblZhbHVlID09PSB1bmRlZmluZWQgPyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCA6IG1pblZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2Rlcy5wdXNoKGNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICBudW1iZXJPZklucHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzKVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgYnVmZmVyU2l6ZSA9IGNvbXB1dGVCdWZmZXJTaXplKGJhc2VMYXRlbmN5LCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCBidWZmZXJTaXplLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnMsIFxuICAgICAgICAvLyBCdWcgIzg3OiBPbmx5IEZpcmVmb3ggd2lsbCBmaXJlIGFuIEF1ZGlvUHJvY2Vzc2luZ0V2ZW50IGlmIHRoZXJlIGlzIG5vIGNvbm5lY3RlZCBvdXRwdXQuXG4gICAgICAgIE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpKTtcbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBvdXRwdXRDaGFubmVsQ291bnRbaV1cbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgZ2Fpbk5vZGVzW2ldLmNvbm5lY3QoaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXSk7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgaiwgaSAqIG9wdGlvbnMuY2hhbm5lbENvdW50ICsgaik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYW1ldGVyTWFwID0gbmV3IFJlYWRPbmx5TWFwKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gW11cbiAgICAgICAgICAgIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubWFwKCh7IG5hbWUgfSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjb25zdGFudFNvdXJjZU5vZGVzW2luZGV4XTtcbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCAwLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCk7XG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgIHJldHVybiBbbmFtZSwgY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldF07XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIGlucHV0Q2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgbGV0IGNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICBsZXQgb25wcm9jZXNzb3JlcnJvciA9IG51bGw7XG4gICAgICAgIC8vIEJ1ZyAjODc6IEV4cG9zZSBhdCBsZWFzdCBvbmUgb3V0cHV0IHRvIG1ha2UgdGhpcyBub2RlIGNvbm5lY3RhYmxlLlxuICAgICAgICBjb25zdCBvdXRwdXRBdWRpb05vZGVzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPT09IDAgPyBbc2NyaXB0UHJvY2Vzc29yTm9kZV0gOiBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXM7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXJTaXplO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQoXykge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNjE6IFRoaXMgaXMgbm90IHBhcnQgb2YgdGhlIHN0YW5kYXJkIGJ1dCByZXF1aXJlZCBmb3IgdGhlIGZha2VyIHRvIHdvcmsuXG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKF8pIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGdhaW5Ob2RlIG9mIGdhaW5Ob2Rlcykge1xuICAgICAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZXM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvbnByb2Nlc3NvcmVycm9yKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvbnByb2Nlc3NvcmVycm9yO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBvbnByb2Nlc3NvcmVycm9yKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlci5yZW1vdmVFdmVudExpc3RlbmVyKCdwcm9jZXNzb3JlcnJvcicsIG9ucHJvY2Vzc29yZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbnByb2Nlc3NvcmVycm9yID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIuYWRkRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhcmFtZXRlcnMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcmFtZXRlck1hcDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9ydCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZUNoYW5uZWwucG9ydDI7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb25uZWN0OiBjb25uZWN0TXVsdGlwbGVPdXRwdXRzLmJpbmQobnVsbCwgb3V0cHV0QXVkaW9Ob2RlcyksXG4gICAgICAgICAgICBkaXNjb25uZWN0OiBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLmJpbmQobnVsbCwgb3V0cHV0QXVkaW9Ob2RlcyksXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVycyA9IG5ldyBNYXAoKTtcbiAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lciA9ICgoYWRkRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnBhdGNoZWRFdmVudExpc3RlbmVyID0gdHlwZW9mIGFyZ3NbMV0gPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgID8gYXJnc1sxXVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgYXJnc1sxXSA9PT0gJ29iamVjdCcgJiYgYXJnc1sxXSAhPT0gbnVsbCAmJiB0eXBlb2YgYXJnc1sxXS5oYW5kbGVFdmVudCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXJnc1sxXS5oYW5kbGVFdmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhdGNoZWRFdmVudExpc3RlbmVyID0gcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmdldChhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IHBhdGNoZWRFdmVudExpc3RlbmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lLCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsICgpID0+IHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIoZXZlbnQpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5zZXQodW5wYXRjaGVkRXZlbnRMaXN0ZW5lciwgYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFkZEV2ZW50TGlzdGVuZXIuY2FsbChtZXNzYWdlQ2hhbm5lbC5wb3J0MSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShtZXNzYWdlQ2hhbm5lbC5wb3J0MS5hZGRFdmVudExpc3RlbmVyKTtcbiAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEucmVtb3ZlRXZlbnRMaXN0ZW5lciA9ICgocmVtb3ZlRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ3NbMF0gPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHBhdGNoZWRFdmVudExpc3RlbmVycy5nZXQoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IHBhdGNoZWRFdmVudExpc3RlbmVyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwobWVzc2FnZUNoYW5uZWwucG9ydDEsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobWVzc2FnZUNoYW5uZWwucG9ydDEucmVtb3ZlRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIGxldCBvbm1lc3NhZ2UgPSBudWxsO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobWVzc2FnZUNoYW5uZWwucG9ydDEsICdvbm1lc3NhZ2UnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IG9ubWVzc2FnZSxcbiAgICAgICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbm1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9ubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9ubWVzc2FnZSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ubWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQ2hhbm5lbC5wb3J0MS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgb25tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEuc3RhcnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wcm90b3R5cGUucG9ydCA9IG1lc3NhZ2VDaGFubmVsLnBvcnQxO1xuICAgICAgICBsZXQgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gbnVsbDtcbiAgICAgICAgY29uc3QgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSA9IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvcihuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKTtcbiAgICAgICAgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZS50aGVuKChkV3JrbHRQcmNzc3IpID0+IChhdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSBkV3JrbHRQcmNzc3IpKTtcbiAgICAgICAgY29uc3QgaW5wdXRzID0gY3JlYXRlTmVzdGVkQXJyYXlzKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMsIG9wdGlvbnMuY2hhbm5lbENvdW50KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0cyA9IGNyZWF0ZU5lc3RlZEFycmF5cyhvcHRpb25zLm51bWJlck9mT3V0cHV0cywgb3V0cHV0Q2hhbm5lbENvdW50KTtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gW11cbiAgICAgICAgICAgIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMucmVkdWNlKChwcm10cnMsIHsgbmFtZSB9KSA9PiAoeyAuLi5wcm10cnMsIFtuYW1lXTogbmV3IEZsb2F0MzJBcnJheSgxMjgpIH0pLCB7fSk7XG4gICAgICAgIGxldCBpc0FjdGl2ZSA9IHRydWU7XG4gICAgICAgIGNvbnN0IGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGggPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPiAwKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlID0gb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzW2ldO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3V0cHV0Q2hhbm5lbENvdW50W2ldOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KG91dHB1dENoYW5uZWxNZXJnZXJOb2RlLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaiwgaik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBhY3RpdmVJbnB1dEluZGV4ZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKHsgaW5wdXRCdWZmZXIsIG91dHB1dEJ1ZmZlciB9KSA9PiB7XG4gICAgICAgICAgICBpZiAoYXVkaW9Xb3JrbGV0UHJvY2Vzc29yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYWN0aXZlSW5wdXRzID0gZ2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmZmVyU2l6ZTsgaSArPSAxMjgpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChpbnB1dEJ1ZmZlciwgaW5wdXRzW2pdLCBrLCBrLCBpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMuZm9yRWFjaCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKGlucHV0QnVmZmVyLCBwYXJhbWV0ZXJzLCBuYW1lLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCwgaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG91dHB1dHNbal1ba10uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRzW2pdW2tdID0gbmV3IEZsb2F0MzJBcnJheSgxMjgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcG90ZW50aWFsbHlFbXB0eUlucHV0cyA9IGlucHV0cy5tYXAoKGlucHV0LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0ID0gYWN0aXZlSW5wdXRzW2luZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aXZlSW5wdXQuc2l6ZSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlSW5wdXRJbmRleGVzLnNldChpbmRleCwgYnVmZmVyU2l6ZSAvIDEyOCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY291bnQgPSBhY3RpdmVJbnB1dEluZGV4ZXMuZ2V0KGluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5ldmVyeSgoY2hhbm5lbERhdGEpID0+IGNoYW5uZWxEYXRhLmV2ZXJ5KChzYW1wbGUpID0+IHNhbXBsZSA9PT0gMCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlSW5wdXRJbmRleGVzLmRlbGV0ZShpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVJbnB1dEluZGV4ZXMuc2V0KGluZGV4LCBjb3VudCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWN0aXZlU291cmNlRmxhZyA9IGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKG5hdGl2ZUNvbnRleHQuY3VycmVudFRpbWUgKyBpIC8gbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGF1ZGlvV29ya2xldFByb2Nlc3Nvci5wcm9jZXNzKHBvdGVudGlhbGx5RW1wdHlJbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQWN0aXZlID0gYWN0aXZlU291cmNlRmxhZztcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG91dHB1dENoYW5uZWxDb3VudFtqXTsgayArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlUb0NoYW5uZWwob3V0cHV0QnVmZmVyLCBvdXRwdXRzW2pdLCBrLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaXNBY3RpdmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlci5kaXNwYXRjaEV2ZW50KG5ldyBFcnJvckV2ZW50KCdwcm9jZXNzb3JlcnJvcicsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xubzogZXJyb3IuY29sbm8sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IGVycm9yLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVubzogZXJyb3IubGluZW5vLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIWlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW5Ob2Rlc1tqXS5kaXNjb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbal0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldLmRpc2Nvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgaywgaiAqIG9wdGlvbnMuY2hhbm5lbENvdW50ICsgayk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsZW5ndGggPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25zdGFudFNvdXJjZU5vZGUgPSBjb25zdGFudFNvdXJjZU5vZGVzW2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuZGlzY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCAwLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBqKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxNZXJnZXJOb2RlLmRpc2Nvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gbnVsbDsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE91dHB1dHNHcmFwaCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdEZha2VHcmFwaCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAvLyBCdWcgIzg3OiBPbmx5IEZpcmVmb3ggd2lsbCBmaXJlIGFuIEF1ZGlvUHJvY2Vzc2luZ0V2ZW50IGlmIHRoZXJlIGlzIG5vIGNvbm5lY3RlZCBvdXRwdXQuXG4gICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIGdhaW46IDBcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNvbm5lY3RGYWtlR3JhcGggPSAoKSA9PiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIGNvbnN0IGRpc2Nvbm5lY3RGYWtlR3JhcGggPSAoKSA9PiB7XG4gICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdEZha2VHcmFwaCgpO1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mT3V0cHV0cyA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxNZXJnZXJOb2RlID0gb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG91dHB1dENoYW5uZWxDb3VudFtpXTsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKyBqLCBqKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtpXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0RmFrZUdyYXBoKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE91dHB1dHNHcmFwaCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgfTtcbiAgICAgICAgY29ubmVjdEZha2VHcmFwaCgpO1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnUScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnZGV0dW5lJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdmcmVxdWVuY3knKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ2dhaW4nKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ3R5cGUnKTtcbiAgICByZXR1cm4gbmF0aXZlQmlxdWFkRmlsdGVyTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYmlxdWFkLWZpbHRlci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZUZhY3RvcnkgPSAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHdyYXBDaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ2hhbm5lbE1lcmdlcihvcHRpb25zLm51bWJlck9mSW5wdXRzKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMyMDogU2FmYXJpIHJlcXVpcmVzIGEgY29ubmVjdGlvbiBvZiBhbnkga2luZCB0byB0cmVhdCB0aGUgaW5wdXQgc2lnbmFsIGNvcnJlY3RseS5cbiAgICAgICAgICogQHRvZG8gVW5mb3J0dW5hdGVseSB0aGVyZSBpcyBubyB3YXkgdG8gdGVzdCBmb3IgdGhpcyBiZWhhdmlvciBpbiBhIHN5bmNocm9ub3VzIGZhc2hpb24gd2hpY2ggaXMgd2h5IHRlc3RpbmcgZm9yIHRoZSBleGlzdGVuY2Ugb2ZcbiAgICAgICAgICogdGhlIHdlYmtpdEF1ZGlvQ29udGV4dCBpcyB1c2VkIGFzIGEgd29ya2Fyb3VuZCBoZXJlLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICB3cmFwQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY2hhbm5lbC1tZXJnZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBDaGFubmVsU3BsaXR0ZXJOb2RlID0gKGNoYW5uZWxTcGxpdHRlck5vZGUpID0+IHtcbiAgICBjb25zdCBjaGFubmVsQ291bnQgPSBjaGFubmVsU3BsaXR0ZXJOb2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAvLyBCdWcgIzk3OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbENvdW50IHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGl0cyBpbml0aWFsIHZhbHVlLlxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsU3BsaXR0ZXJOb2RlLCAnY2hhbm5lbENvdW50Jywge1xuICAgICAgICBnZXQ6ICgpID0+IGNoYW5uZWxDb3VudCxcbiAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gY2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIC8vIEJ1ZyAjMzA6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIGF0dGVtcHRpbmcgdG8gY2hhbmdlIHRoZSBjaGFubmVsQ291bnRNb2RlIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGV4cGxpY2l0LlxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsU3BsaXR0ZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiAnZXhwbGljaXQnLFxuICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSAnZXhwbGljaXQnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIC8vIEJ1ZyAjMzI6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIGF0dGVtcHRpbmcgdG8gY2hhbmdlIHRoZSBjaGFubmVsSW50ZXJwcmV0YXRpb24gdG8gc29tZXRoaW5nIG90aGVyIHRoYW4gZGlzY3JldGUuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxTcGxpdHRlck5vZGUsICdjaGFubmVsSW50ZXJwcmV0YXRpb24nLCB7XG4gICAgICAgIGdldDogKCkgPT4gJ2Rpc2NyZXRlJyxcbiAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gJ2Rpc2NyZXRlJykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWNoYW5uZWwtc3BsaXR0ZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1jaGFubmVsLXNwbGl0dGVyLW5vZGUnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNoYW5uZWxTcGxpdHRlcihvcHRpb25zLm51bWJlck9mT3V0cHV0cyk7XG4gICAgLy8gQnVnICM5NjogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50LlxuICAgIC8vIEJ1ZyAjMjk6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudE1vZGUuXG4gICAgLy8gQnVnICMzMTogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbEludGVycHJldGF0aW9uLlxuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgLy8gQnVnICMyOSwgIzMwLCAjMzEsICMzMiwgIzk2ICYgIzk3OiBPbmx5IENocm9tZSwgRWRnZSAmIEZpcmVmb3ggcGFydGlhbGx5IHN1cHBvcnQgdGhlIHNwZWMgeWV0LlxuICAgIHdyYXBDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgIHJldHVybiBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyLCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgLy8gQnVnICM2MjogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgQ29uc3RhbnRTb3VyY2VOb2Rlcy5cbiAgICAgICAgaWYgKG5hdGl2ZUNvbnRleHQuY3JlYXRlQ29uc3RhbnRTb3VyY2UgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ29uc3RhbnRTb3VyY2UoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBvcHRpb25zLCAnb2Zmc2V0Jyk7XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3NTogU2FmYXJpIHdpbGwgbm90IGZpcmUgYW4gZW5kZWQgZXZlbnQgaWYgdGhlIENvbnN0YW50U291cmNlTm9kZSBpcyB1bmNvbm5lY3RlZC5cbiAgICAgICAgYWRkU2lsZW50Q29ubmVjdGlvbihuYXRpdmVDb250ZXh0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGludGVyY2VwdENvbm5lY3Rpb25zID0gKG9yaWdpbmFsLCBpbnRlcmNlcHRvcikgPT4ge1xuICAgIG9yaWdpbmFsLmNvbm5lY3QgPSBpbnRlcmNlcHRvci5jb25uZWN0LmJpbmQoaW50ZXJjZXB0b3IpO1xuICAgIG9yaWdpbmFsLmRpc2Nvbm5lY3QgPSBpbnRlcmNlcHRvci5kaXNjb25uZWN0LmJpbmQoaW50ZXJjZXB0b3IpO1xuICAgIHJldHVybiBvcmlnaW5hbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbnRlcmNlcHQtY29ubmVjdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXJGYWN0b3J5ID0gKGFkZFNpbGVudENvbm5lY3Rpb24sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBvZmZzZXQsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDIsIDQ0MTAwKTtcbiAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2Fpbjogb2Zmc2V0IH0pO1xuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgIC8vIEJ1ZyAjOTU6IFNhZmFyaSBkb2VzIG5vdCBwbGF5IG9yIGxvb3Agb25lIHNhbXBsZSBidWZmZXJzLlxuICAgICAgICBjaGFubmVsRGF0YVswXSA9IDE7XG4gICAgICAgIGNoYW5uZWxEYXRhWzFdID0gMTtcbiAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IGF1ZGlvQnVmZmVyO1xuICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHRydWU7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvZmZzZXQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBvbmVuZGVkKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLm9uZW5kZWQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdGFydCh3aGVuID0gMCkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydC5jYWxsKGF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wLmNhbGwoYXVkaW9CdWZmZXJTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IGF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KGdhaW5Ob2RlKTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IGF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNjb25uZWN0KGdhaW5Ob2RlKTtcbiAgICAgICAgLy8gQnVnICMxNzU6IFNhZmFyaSB3aWxsIG5vdCBmaXJlIGFuIGVuZGVkIGV2ZW50IGlmIHRoZSBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgYXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciwgZ2Fpbk5vZGUpLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb252b2x2ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVDb252b2x2ZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgLy8gVGhlIG5vcm1hbGl6ZSBwcm9wZXJ0eSBuZWVkcyB0byBiZSBzZXQgYmVmb3JlIHNldHRpbmcgdGhlIGJ1ZmZlci5cbiAgICAgICAgaWYgKG9wdGlvbnMuZGlzYWJsZU5vcm1hbGl6YXRpb24gPT09IG5hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplKSB7XG4gICAgICAgICAgICBuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZSA9ICFvcHRpb25zLmRpc2FibGVOb3JtYWxpemF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVDb252b2x2ZXJOb2RlLCBvcHRpb25zLCAnYnVmZmVyJyk7XG4gICAgICAgIC8vIEJ1ZyAjMTEzOiBTYWZhcmkgZG9lcyBhbGxvdyB0byBzZXQgdGhlIGNoYW5uZWxDb3VudCB0byBhIHZhbHVlIGxhcmdlciB0aGFuIDIuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZUNvbnZvbHZlck5vZGUsICdjaGFubmVsQ291bnQnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPiAyKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzExNDogU2FmYXJpIGFsbG93cyB0byBzZXQgdGhlIGNoYW5uZWxDb3VudE1vZGUgdG8gJ21heCcuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVDb252b2x2ZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKG5hdGl2ZUNvbnZvbHZlck5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHNldC5jYWxsKG5hdGl2ZUNvbnZvbHZlck5vZGUsIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVDb252b2x2ZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNvbnZvbHZlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlRGVsYXlOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVEZWxheShvcHRpb25zLm1heERlbGF5VGltZSk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVEZWxheU5vZGUsIG9wdGlvbnMpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEZWxheU5vZGUsIG9wdGlvbnMsICdkZWxheVRpbWUnKTtcbiAgICByZXR1cm4gbmF0aXZlRGVsYXlOb2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1kZWxheS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlRmFjdG9yeSA9IChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgLy8gQnVnICMxMDg6IFNhZmFyaSBhbGxvd3MgYSBjaGFubmVsQ291bnQgb2YgdGhyZWUgYW5kIGFib3ZlLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnQgPiAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTA5OiBPbmx5IENocm9tZSBhbmQgRmlyZWZveCBkaXNhbGxvdyBhIGNoYW5uZWxDb3VudE1vZGUgb2YgJ21heCcuXG4gICAgICAgIGlmIChvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAnYXR0YWNrJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAna25lZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ3JhdGlvJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBvcHRpb25zLCAncmVsZWFzZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ3RocmVzaG9sZCcpO1xuICAgICAgICByZXR1cm4gbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlR2Fpbk5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVHYWluTm9kZSwgb3B0aW9ucyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUdhaW5Ob2RlLCBvcHRpb25zLCAnZ2FpbicpO1xuICAgIHJldHVybiBuYXRpdmVHYWluTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZ2Fpbi1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjOTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgSUlSRmlsdGVyTm9kZXMuXG4gICAgICAgIGlmIChuYXRpdmVDb250ZXh0LmNyZWF0ZUlJUkZpbHRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGRlZmluZXMgdGhlIHBhcmFtZXRlcnMgb2YgY3JlYXRlSUlSRmlsdGVyKCkgYXMgYXJyYXlzIG9mIG51bWJlcnMuXG4gICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihvcHRpb25zLmZlZWRmb3J3YXJkLCBvcHRpb25zLmZlZWRiYWNrKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVJSVJGaWx0ZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUlJUkZpbHRlck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgY29tcHV0ZUJ1ZmZlclNpemUgfSBmcm9tICcuLi9oZWxwZXJzL2NvbXB1dGUtYnVmZmVyLXNpemUnO1xuaW1wb3J0IHsgZmlsdGVyQnVmZmVyIH0gZnJvbSAnLi4vaGVscGVycy9maWx0ZXItYnVmZmVyJztcbmltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZnVuY3Rpb24gZGl2aWRlKGEsIGIpIHtcbiAgICBjb25zdCBkZW5vbWluYXRvciA9IGJbMF0gKiBiWzBdICsgYlsxXSAqIGJbMV07XG4gICAgcmV0dXJuIFsoYVswXSAqIGJbMF0gKyBhWzFdICogYlsxXSkgLyBkZW5vbWluYXRvciwgKGFbMV0gKiBiWzBdIC0gYVswXSAqIGJbMV0pIC8gZGVub21pbmF0b3JdO1xufVxuZnVuY3Rpb24gbXVsdGlwbHkoYSwgYikge1xuICAgIHJldHVybiBbYVswXSAqIGJbMF0gLSBhWzFdICogYlsxXSwgYVswXSAqIGJbMV0gKyBhWzFdICogYlswXV07XG59XG5mdW5jdGlvbiBldmFsdWF0ZVBvbHlub21pYWwoY29lZmZpY2llbnQsIHopIHtcbiAgICBsZXQgcmVzdWx0ID0gWzAsIDBdO1xuICAgIGZvciAobGV0IGkgPSBjb2VmZmljaWVudC5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICByZXN1bHQgPSBtdWx0aXBseShyZXN1bHQsIHopO1xuICAgICAgICByZXN1bHRbMF0gKz0gY29lZmZpY2llbnRbaV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIHsgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnRNb2RlLCBjaGFubmVsSW50ZXJwcmV0YXRpb24sIGZlZWRiYWNrLCBmZWVkZm9yd2FyZCB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGJ1ZmZlclNpemUgPSBjb21wdXRlQnVmZmVyU2l6ZShiYXNlTGF0ZW5jeSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkRmVlZGJhY2sgPSBmZWVkYmFjayBpbnN0YW5jZW9mIEZsb2F0NjRBcnJheSA/IGZlZWRiYWNrIDogbmV3IEZsb2F0NjRBcnJheShmZWVkYmFjayk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZEZlZWRmb3J3YXJkID0gZmVlZGZvcndhcmQgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBmZWVkZm9yd2FyZCA6IG5ldyBGbG9hdDY0QXJyYXkoZmVlZGZvcndhcmQpO1xuICAgICAgICBjb25zdCBmZWVkYmFja0xlbmd0aCA9IGNvbnZlcnRlZEZlZWRiYWNrLmxlbmd0aDtcbiAgICAgICAgY29uc3QgZmVlZGZvcndhcmRMZW5ndGggPSBjb252ZXJ0ZWRGZWVkZm9yd2FyZC5sZW5ndGg7XG4gICAgICAgIGNvbnN0IG1pbkxlbmd0aCA9IE1hdGgubWluKGZlZWRiYWNrTGVuZ3RoLCBmZWVkZm9yd2FyZExlbmd0aCk7XG4gICAgICAgIGlmIChmZWVkYmFja0xlbmd0aCA9PT0gMCB8fCBmZWVkYmFja0xlbmd0aCA+IDIwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmVlZGZvcndhcmRMZW5ndGggPT09IDAgfHwgZmVlZGZvcndhcmRMZW5ndGggPiAyMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udmVydGVkRmVlZGZvcndhcmRbMF0gPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnZlcnRlZEZlZWRiYWNrWzBdICE9PSAxKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZlZWRmb3J3YXJkTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0ZWRGZWVkZm9yd2FyZFtpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmVlZGJhY2tMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRiYWNrW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZUNvbnRleHQsIGJ1ZmZlclNpemUsIGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50KTtcbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnQgPSBjaGFubmVsQ291bnQ7XG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IGNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICBjb25zdCBidWZmZXJMZW5ndGggPSAzMjtcbiAgICAgICAgY29uc3QgYnVmZmVySW5kZXhlcyA9IFtdO1xuICAgICAgICBjb25zdCB4QnVmZmVycyA9IFtdO1xuICAgICAgICBjb25zdCB5QnVmZmVycyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5uZWxDb3VudDsgaSArPSAxKSB7XG4gICAgICAgICAgICBidWZmZXJJbmRleGVzLnB1c2goMCk7XG4gICAgICAgICAgICBjb25zdCB4QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgeUJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICAgICAgICAgIHhCdWZmZXIuZmlsbCgwKTtcbiAgICAgICAgICAgIHlCdWZmZXIuZmlsbCgwKTtcbiAgICAgICAgICAgIHhCdWZmZXJzLnB1c2goeEJ1ZmZlcik7XG4gICAgICAgICAgICB5QnVmZmVycy5wdXNoKHlCdWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbnB1dEJ1ZmZlciA9IGV2ZW50LmlucHV0QnVmZmVyO1xuICAgICAgICAgICAgY29uc3Qgb3V0cHV0QnVmZmVyID0gZXZlbnQub3V0cHV0QnVmZmVyO1xuICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZDaGFubmVscyA9IGlucHV0QnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mQ2hhbm5lbHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gaW5wdXRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0ID0gb3V0cHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlckluZGV4ZXNbaV0gPSBmaWx0ZXJCdWZmZXIoY29udmVydGVkRmVlZGJhY2ssIGZlZWRiYWNrTGVuZ3RoLCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCwgZmVlZGZvcndhcmRMZW5ndGgsIG1pbkxlbmd0aCwgeEJ1ZmZlcnNbaV0sIHlCdWZmZXJzW2ldLCBidWZmZXJJbmRleGVzW2ldLCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBueXF1aXN0ID0gbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlIC8gMjtcbiAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlclNpemU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW3NjcmlwdFByb2Nlc3Nvck5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBhZGRFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBEaXNzYWxsb3cgYWRkaW5nIGFuIGF1ZGlvcHJvY2VzcyBsaXN0ZW5lci5cbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc3BhdGNoRXZlbnQoYXJnc1swXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZyZXF1ZW5jeUh6Lmxlbmd0aCAhPT0gbWFnUmVzcG9uc2UubGVuZ3RoIHx8IG1hZ1Jlc3BvbnNlLmxlbmd0aCAhPT0gcGhhc2VSZXNwb25zZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGZyZXF1ZW5jeUh6Lmxlbmd0aDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9tZWdhID0gLU1hdGguUEkgKiAoZnJlcXVlbmN5SHpbaV0gLyBueXF1aXN0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeiA9IFtNYXRoLmNvcyhvbWVnYSksIE1hdGguc2luKG9tZWdhKV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyYXRvciA9IGV2YWx1YXRlUG9seW5vbWlhbChjb252ZXJ0ZWRGZWVkZm9yd2FyZCwgeik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlbm9taW5hdG9yID0gZXZhbHVhdGVQb2x5bm9taWFsKGNvbnZlcnRlZEZlZWRiYWNrLCB6KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBkaXZpZGUobnVtZXJhdG9yLCBkZW5vbWluYXRvcik7XG4gICAgICAgICAgICAgICAgICAgIG1hZ1Jlc3BvbnNlW2ldID0gTWF0aC5zcXJ0KHJlc3BvbnNlWzBdICogcmVzcG9uc2VbMF0gKyByZXNwb25zZVsxXSAqIHJlc3BvbnNlWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgcGhhc2VSZXNwb25zZVtpXSA9IE1hdGguYXRhbjIocmVzcG9uc2VbMV0sIHJlc3BvbnNlWzBdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlciwgc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSA9IChuYXRpdmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShvcHRpb25zLm1lZGlhRWxlbWVudCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSAobmF0aXZlQXVkaW9Db250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBvcHRpb25zKTtcbiAgICAvLyBCdWcgIzE3NDogU2FmYXJpIGRvZXMgZXhwb3NlIGEgd3JvbmcgbnVtYmVyT2ZPdXRwdXRzLlxuICAgIGlmIChuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLm51bWJlck9mT3V0cHV0cyA9PT0gMSkge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgJ251bWJlck9mT3V0cHV0cycsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgeyBtZWRpYVN0cmVhbSB9KSA9PiB7XG4gICAgY29uc3QgYXVkaW9TdHJlYW1UcmFja3MgPSBtZWRpYVN0cmVhbS5nZXRBdWRpb1RyYWNrcygpO1xuICAgIC8qXG4gICAgICogQnVnICMxNTE6IFNhZmFyaSBkb2VzIG5vdCB1c2UgdGhlIGF1ZGlvIHRyYWNrIGFzIGlucHV0IGFueW1vcmUgaWYgaXQgZ2V0cyByZW1vdmVkIGZyb20gdGhlIG1lZGlhU3RyZWFtIGFmdGVyIGNvbnN0cnVjdGlvbi5cbiAgICAgKiBCdWcgIzE1OTogU2FmYXJpIHBpY2tzIHRoZSBmaXJzdCBhdWRpbyB0cmFjayBpZiB0aGUgTWVkaWFTdHJlYW0gaGFzIG1vcmUgdGhhbiBvbmUgYXVkaW8gdHJhY2suXG4gICAgICovXG4gICAgYXVkaW9TdHJlYW1UcmFja3Muc29ydCgoYSwgYikgPT4gKGEuaWQgPCBiLmlkID8gLTEgOiBhLmlkID4gYi5pZCA/IDEgOiAwKSk7XG4gICAgY29uc3QgZmlsdGVyZWRBdWRpb1N0cmVhbVRyYWNrcyA9IGF1ZGlvU3RyZWFtVHJhY2tzLnNsaWNlKDAsIDEpO1xuICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKG5ldyBNZWRpYVN0cmVhbShmaWx0ZXJlZEF1ZGlvU3RyZWFtVHJhY2tzKSk7XG4gICAgLypcbiAgICAgKiBCdWcgIzE1MSAmICMxNTk6IFRoZSBnaXZlbiBtZWRpYVN0cmVhbSBnZXRzIHJlY29uc3RydWN0ZWQgYmVmb3JlIGl0IGdldHMgcGFzc2VkIHRvIHRoZSBuYXRpdmUgbm9kZSB3aGljaCBpcyB3aHkgdGhlIGFjY2Vzc29yIG5lZWRzXG4gICAgICogdG8gYmUgb3ZlcndyaXR0ZW4gYXMgaXQgd291bGQgb3RoZXJ3aXNlIGV4cG9zZSB0aGUgcmVjb25zdHJ1Y3RlZCB2ZXJzaW9uLlxuICAgICAqL1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgJ21lZGlhU3RyZWFtJywgeyB2YWx1ZTogbWVkaWFTdHJlYW0gfSk7XG4gICAgcmV0dXJuIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVGYWN0b3J5ID0gKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgeyBtZWRpYVN0cmVhbVRyYWNrIH0pID0+IHtcbiAgICAgICAgLy8gQnVnICMxMjE6IE9ubHkgRmlyZWZveCBkb2VzIHlldCBzdXBwb3J0IHRoZSBNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlLlxuICAgICAgICBpZiAodHlwZW9mIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVRyYWNrU291cmNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tTb3VyY2UobWVkaWFTdHJlYW1UcmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWVkaWFTdHJlYW0gPSBuZXcgTWVkaWFTdHJlYW0oW21lZGlhU3RyZWFtVHJhY2tdKTtcbiAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UobWVkaWFTdHJlYW0pO1xuICAgICAgICAvLyBCdWcgIzEyMDogRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgbWVkaWFTdHJlYW0gaGFzIG5vIGF1ZGlvIHRyYWNrLlxuICAgICAgICBpZiAobWVkaWFTdHJlYW1UcmFjay5raW5kICE9PSAnYXVkaW8nKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTcyOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgaWYgKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVBdWRpb0NvbnRleHQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAod2luZG93KSA9PiB7XG4gICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnT2ZmbGluZUF1ZGlvQ29udGV4dCcpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5oYXNPd25Qcm9wZXJ0eSgnd2Via2l0T2ZmbGluZUF1ZGlvQ29udGV4dCcpID8gd2luZG93LndlYmtpdE9mZmxpbmVBdWRpb0NvbnRleHQgOiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlT3NjaWxsYXRvck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlT3NjaWxsYXRvck5vZGUsIG9wdGlvbnMsICdkZXR1bmUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zLCAnZnJlcXVlbmN5Jyk7XG4gICAgICAgIGlmIChvcHRpb25zLnBlcmlvZGljV2F2ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZS5zZXRQZXJpb2RpY1dhdmUob3B0aW9ucy5wZXJpb2RpY1dhdmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zLCAndHlwZScpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgQ2hyb21lICYgRWRnZSB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE5OiBTYWZhcmkgZG9lcyBub3QgaWdub3JlIGNhbGxzIHRvIHN0b3AoKSBvZiBhbiBhbHJlYWR5IHN0b3BwZWQgQXVkaW9CdWZmZXJTb3VyY2VOb2RlLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzU6IFNhZmFyaSB3aWxsIG5vdCBmaXJlIGFuIGVuZGVkIGV2ZW50IGlmIHRoZSBPc2NpbGxhdG9yTm9kZSBpcyB1bmNvbm5lY3RlZC5cbiAgICAgICAgYWRkU2lsZW50Q29ubmVjdGlvbihuYXRpdmVDb250ZXh0LCBuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVPc2NpbGxhdG9yTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1vc2NpbGxhdG9yLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICAgICAgLy8gQnVnICMxMjQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmeWluZyB0aGUgb3JpZW50YXRpb24gYW5kIHRoZSBwb3NpdGlvbiB3aXRoIEF1ZGlvUGFyYW1zLlxuICAgICAgICBpZiAobmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ29yaWVudGF0aW9uWCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ29yaWVudGF0aW9uWScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ29yaWVudGF0aW9uWicpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3Bvc2l0aW9uWCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3Bvc2l0aW9uWScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3Bvc2l0aW9uWicpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2NvbmVJbm5lckFuZ2xlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnY29uZU91dGVyQW5nbGUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdjb25lT3V0ZXJHYWluJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnZGlzdGFuY2VNb2RlbCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ21heERpc3RhbmNlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncGFubmluZ01vZGVsJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncmVmRGlzdGFuY2UnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdyb2xsb2ZmRmFjdG9yJyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVQYW5uZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXBhbm5lci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IChjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEZpcnN0U2FtcGxlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY29uZUlubmVyQW5nbGUsIGNvbmVPdXRlckFuZ2xlLCBjb25lT3V0ZXJHYWluLCBkaXN0YW5jZU1vZGVsLCBtYXhEaXN0YW5jZSwgb3JpZW50YXRpb25YLCBvcmllbnRhdGlvblksIG9yaWVudGF0aW9uWiwgcGFubmluZ01vZGVsLCBwb3NpdGlvblgsIHBvc2l0aW9uWSwgcG9zaXRpb25aLCByZWZEaXN0YW5jZSwgcm9sbG9mZkZhY3RvciwgLi4uYXVkaW9Ob2RlT3B0aW9ucyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHBhbm5lck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgICAgICAvLyBCdWcgIzEyNTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgaWYgKGF1ZGlvTm9kZU9wdGlvbnMuY2hhbm5lbENvdW50ID4gMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzEyNjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgaWYgKGF1ZGlvTm9kZU9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhwYW5uZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgY29uc3QgU0lOR0xFX0NIQU5ORUxfT1BUSU9OUyA9IHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZSdcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDZcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uWEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBvcmllbnRhdGlvbllHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3Qgb3JpZW50YXRpb25aR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uWEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBwb3NpdGlvbllHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25aR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHNjcmlwdFByb2Nlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlKG5hdGl2ZUNvbnRleHQsIDI1NiwgNiwgMSk7XG4gICAgICAgIGNvbnN0IHdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUyxcbiAgICAgICAgICAgIGN1cnZlOiBuZXcgRmxvYXQzMkFycmF5KFsxLCAxXSksXG4gICAgICAgICAgICBvdmVyc2FtcGxlOiAnbm9uZSdcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBsYXN0T3JpZW50YXRpb24gPSBbb3JpZW50YXRpb25YLCBvcmllbnRhdGlvblksIG9yaWVudGF0aW9uWl07XG4gICAgICAgIGxldCBsYXN0UG9zaXRpb24gPSBbcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWl07XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoMSk7XG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKHsgaW5wdXRCdWZmZXIgfSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3JpZW50YXRpb24gPSBbXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMCksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMSksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMilcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAob3JpZW50YXRpb24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnNldE9yaWVudGF0aW9uKC4uLm9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgcG9zaXRvbiA9IFtcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAzKSxcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA0KSxcbiAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA1KVxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGlmIChwb3NpdG9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRQb3NpdGlvbiguLi5wb3NpdG9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbiA9IHBvc2l0b247XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvcmllbnRhdGlvbllHYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvcmllbnRhdGlvblpHYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwb3NpdGlvblhHYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwb3NpdGlvbllHYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwb3NpdGlvblpHYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZVBhbm5lck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI1OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA+IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyNjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbmVJbm5lckFuZ2xlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lSW5uZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY29uZUlubmVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29uZU91dGVyQW5nbGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29uZU91dGVyQW5nbGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNvbmVPdXRlckFuZ2xlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb25lT3V0ZXJHYWluKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbmVPdXRlckdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNvbmVPdXRlckdhaW4odmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyNzogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwIHx8IHZhbHVlID4gMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNvbmVPdXRlckdhaW4gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBkaXN0YW5jZU1vZGVsKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWw7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGRpc3RhbmNlTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWwgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbaW5wdXRHYWluTm9kZV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG1heERpc3RhbmNlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLm1heERpc3RhbmNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBtYXhEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5tYXhEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3JpZW50YXRpb25YKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvblhHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvcmllbnRhdGlvblkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWVudGF0aW9uWUdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9yaWVudGF0aW9uWigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb25aR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnBhbm5pbmdNb2RlbDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgcGFubmluZ01vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5wYW5uaW5nTW9kZWwgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25YKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblhHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblkoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWUdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25aR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcmVmRGlzdGFuY2UoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUucmVmRGlzdGFuY2U7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHJlZkRpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjk6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLnJlZkRpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHJvbGxvZmZGYWN0b3IoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUucm9sbG9mZkZhY3RvcjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgcm9sbG9mZkZhY3Rvcih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMwOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGlmIChjb25lSW5uZXJBbmdsZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVJbm5lckFuZ2xlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZUlubmVyQW5nbGUgPSBjb25lSW5uZXJBbmdsZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29uZU91dGVyQW5nbGUgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJBbmdsZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckFuZ2xlID0gY29uZU91dGVyQW5nbGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmVPdXRlckdhaW4gIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJHYWluKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyR2FpbiA9IGNvbmVPdXRlckdhaW47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRpc3RhbmNlTW9kZWwgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5kaXN0YW5jZU1vZGVsKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuZGlzdGFuY2VNb2RlbCA9IGRpc3RhbmNlTW9kZWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heERpc3RhbmNlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIubWF4RGlzdGFuY2UpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5tYXhEaXN0YW5jZSA9IG1heERpc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmllbnRhdGlvblggIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblgudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblgudmFsdWUgPSBvcmllbnRhdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yaWVudGF0aW9uWSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWS52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWS52YWx1ZSA9IG9yaWVudGF0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZW50YXRpb25aICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25aLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25aLnZhbHVlID0gb3JpZW50YXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYW5uaW5nTW9kZWwgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wYW5uaW5nTW9kZWwpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wYW5uaW5nTW9kZWwgPSBwYW5uaW5nTW9kZWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uWCAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWC52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWC52YWx1ZSA9IHBvc2l0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb25ZICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25ZLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25ZLnZhbHVlID0gcG9zaXRpb25ZO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvblogIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvbloudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvbloudmFsdWUgPSBwb3NpdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlZkRpc3RhbmNlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucmVmRGlzdGFuY2UpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yZWZEaXN0YW5jZSA9IHJlZkRpc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyb2xsb2ZmRmFjdG9yICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucm9sbG9mZkZhY3Rvcikge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnJvbGxvZmZGYWN0b3IgPSByb2xsb2ZmRmFjdG9yO1xuICAgICAgICB9XG4gICAgICAgIGlmIChsYXN0T3JpZW50YXRpb25bMF0gIT09IDEgfHwgbGFzdE9yaWVudGF0aW9uWzFdICE9PSAwIHx8IGxhc3RPcmllbnRhdGlvblsyXSAhPT0gMCkge1xuICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRPcmllbnRhdGlvbiguLi5sYXN0T3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhc3RQb3NpdGlvblswXSAhPT0gMCB8fCBsYXN0UG9zaXRpb25bMV0gIT09IDAgfHwgbGFzdFBvc2l0aW9uWzJdICE9PSAwKSB7XG4gICAgICAgICAgICBwYW5uZXJOb2RlLnNldFBvc2l0aW9uKC4uLmxhc3RQb3NpdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHBhbm5lck5vZGUpO1xuICAgICAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgICAgIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZShpbnB1dEdhaW5Ob2RlLCB3YXZlU2hhcGVyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KG9yaWVudGF0aW9uWEdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3Qob3JpZW50YXRpb25ZR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChvcmllbnRhdGlvblpHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMik7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KHBvc2l0aW9uWEdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAzKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocG9zaXRpb25ZR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDQpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChwb3NpdGlvblpHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgNSk7XG4gICAgICAgICAgICBjaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocGFubmVyTm9kZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUoaW5wdXRHYWluTm9kZSwgd2F2ZVNoYXBlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvcmllbnRhdGlvblhHYWluTm9kZSk7XG4gICAgICAgICAgICBvcmllbnRhdGlvblhHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3JpZW50YXRpb25ZR2Fpbk5vZGUpO1xuICAgICAgICAgICAgb3JpZW50YXRpb25ZR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG9yaWVudGF0aW9uWkdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWkdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwb3NpdGlvblhHYWluTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGlvblhHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocG9zaXRpb25ZR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpb25ZR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBvc2l0aW9uWkdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHBvc2l0aW9uWkdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuZGlzY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVQYW5uZXJOb2RlRmFrZXIsIHBhbm5lck5vZGUpLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmVGYWN0b3J5ID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGRpc2FibGVOb3JtYWxpemF0aW9uLCBpbWFnLCByZWFsIH0pID0+IHtcbiAgICAgICAgLy8gQnVnICMxODA6IFNhZmFyaSBkb2VzIG5vdCBhbGxvdyB0byB1c2Ugb3JkaW5hcnkgYXJyYXlzLlxuICAgICAgICBjb25zdCBjb252ZXJ0ZWRJbWFnID0gaW1hZyBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IGltYWcgOiBuZXcgRmxvYXQzMkFycmF5KGltYWcpO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRSZWFsID0gcmVhbCBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IHJlYWwgOiBuZXcgRmxvYXQzMkFycmF5KHJlYWwpO1xuICAgICAgICBjb25zdCBuYXRpdmVQZXJpb2RpY1dhdmUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZShjb252ZXJ0ZWRSZWFsLCBjb252ZXJ0ZWRJbWFnLCB7IGRpc2FibGVOb3JtYWxpemF0aW9uIH0pO1xuICAgICAgICAvLyBCdWcgIzE4MTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEluZGV4U2l6ZUVycm9yIHNvIGZhciBpZiB0aGUgZ2l2ZW4gYXJyYXlzIGhhdmUgbGVzcyB0aGFuIHR3byB2YWx1ZXMuXG4gICAgICAgIGlmIChBcnJheS5mcm9tKGltYWcpLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hdGl2ZVBlcmlvZGljV2F2ZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1wZXJpb2RpYy13YXZlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUgPSAobmF0aXZlQ29udGV4dCwgYnVmZmVyU2l6ZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSA9PiB7XG4gICAgcmV0dXJuIG5hdGl2ZUNvbnRleHQuY3JlYXRlU2NyaXB0UHJvY2Vzc29yKGJ1ZmZlclNpemUsIG51bWJlck9mSW5wdXRDaGFubmVscywgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmUgZGVwcmVjYXRpb25cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc2NyaXB0LXByb2Nlc3Nvci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXIsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxDb3VudE1vZGUgPSBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMTA1OiBUaGUgY2hhbm5lbENvdW50TW9kZSBvZiAnY2xhbXBlZC1tYXgnIHNob3VsZCBiZSBzdXBwb3J0ZWQuIEhvd2V2ZXIgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHdyaXRlIGEgcG9seWZpbGwgZm9yIFNhZmFyaVxuICAgICAgICAgKiB3aGljaCBzdXBwb3J0cyBpdCBhbmQgdGhlcmVmb3JlIGl0IGNhbid0IGJlIHN1cHBvcnRlZCBhdCBhbGwuXG4gICAgICAgICAqL1xuICAgICAgICBpZiAoY2hhbm5lbENvdW50TW9kZSA9PT0gJ2NsYW1wZWQtbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzEwNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgdGhlIFN0ZXJlb1Bhbm5lck5vZGUuXG4gICAgICAgIGlmIChuYXRpdmVDb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgb3B0aW9ucywgJ3BhbicpO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzEwNTogVGhlIGNoYW5uZWxDb3VudE1vZGUgb2YgJ2NsYW1wZWQtbWF4JyBzaG91bGQgYmUgc3VwcG9ydGVkLiBIb3dldmVyIGl0IGlzIG5vdCBwb3NzaWJsZSB0byB3cml0ZSBhIHBvbHlmaWxsIGZvciBTYWZhcmlcbiAgICAgICAgICogd2hpY2ggc3VwcG9ydHMgaXQgYW5kIHRoZXJlZm9yZSBpdCBjYW4ndCBiZSBzdXBwb3J0ZWQgYXQgYWxsLlxuICAgICAgICAgKi9cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsICdjaGFubmVsQ291bnRNb2RlJywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiBjaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IGNoYW5uZWxDb3VudE1vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmF0aXZlU3RlcmVvUGFubmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICAvLyBUaGUgY3VydmUgaGFzIGEgc2l6ZSBvZiAxNGJpdCBwbHVzIDEgdmFsdWUgdG8gaGF2ZSBhbiBleGFjdCByZXByZXNlbnRhdGlvbiBmb3IgemVyby4gVGhpcyB2YWx1ZSBoYXMgYmVlbiBkZXRlcm1pbmVkIGV4cGVyaW1lbnRhbGx5LlxuICAgIGNvbnN0IENVUlZFX1NJWkUgPSAxNjM4NTtcbiAgICBjb25zdCBEQ19DVVJWRSA9IG5ldyBGbG9hdDMyQXJyYXkoWzEsIDFdKTtcbiAgICBjb25zdCBIQUxGX1BJID0gTWF0aC5QSSAvIDI7XG4gICAgY29uc3QgU0lOR0xFX0NIQU5ORUxfT1BUSU9OUyA9IHsgY2hhbm5lbENvdW50OiAxLCBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLCBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScgfTtcbiAgICBjb25zdCBTSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TID0geyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBvdmVyc2FtcGxlOiAnbm9uZScgfTtcbiAgICBjb25zdCBidWlsZEludGVybmFsR3JhcGhGb3JNb25vID0gKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBsZWZ0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgcmlnaHRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IENVUlZFX1NJWkU7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29uc3QgeCA9IChpIC8gKENVUlZFX1NJWkUgLSAxKSkgKiBIQUxGX1BJO1xuICAgICAgICAgICAgbGVmdFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguY29zKHgpO1xuICAgICAgICAgICAgcmlnaHRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLnNpbih4KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBsZWZ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IGxlZnRXYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiBsZWZ0V2F2ZVNoYXBlckN1cnZlIH0pKTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcGFuV2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogRENfQ1VSVkUgfSkpO1xuICAgICAgICBjb25zdCByaWdodEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCByaWdodFdhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IHJpZ2h0V2F2ZVNoYXBlckN1cnZlIH0pKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QobGVmdEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHJpZ2h0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmNvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QobGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gbGVmdFdhdmVTaGFwZXJOb2RlIDogbGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChyaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcmlnaHRXYXZlU2hhcGVyTm9kZSA6IHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChsZWZ0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KHJpZ2h0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBsZWZ0V2F2ZVNoYXBlck5vZGUgOiBsZWZ0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyByaWdodFdhdmVTaGFwZXJOb2RlIDogcmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGxlZnRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KGxlZnRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xuICAgIGNvbnN0IGJ1aWxkSW50ZXJuYWxHcmFwaEZvclN0ZXJlbyA9IChuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCBjZW50ZXJJbmRleCA9IE1hdGguZmxvb3IoQ1VSVkVfU0laRSAvIDIpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IENVUlZFX1NJWkU7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKGkgPiBjZW50ZXJJbmRleCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHggPSAoKGkgLSBjZW50ZXJJbmRleCkgLyAoQ1VSVkVfU0laRSAtIDEgLSBjZW50ZXJJbmRleCkpICogSEFMRl9QSTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5jb3MoeCk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLnNpbih4KTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDA7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHggPSAoaSAvIChDVVJWRV9TSVpFIC0gMSAtIGNlbnRlckluZGV4KSkgKiBIQUxGX1BJO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAxO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMDtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguY29zKHgpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguc2luKHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IDJcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyxcbiAgICAgICAgICAgIGN1cnZlOiBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyxcbiAgICAgICAgICAgIGN1cnZlOiBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcGFuV2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogRENfQ1VSVkUgfSkpO1xuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyxcbiAgICAgICAgICAgIGN1cnZlOiByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyxcbiAgICAgICAgICAgIGN1cnZlOiByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBjb25zdCBidWlsZEludGVybmFsR3JhcGggPSAobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudCA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIGJ1aWxkSW50ZXJuYWxHcmFwaEZvck1vbm8obmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhbm5lbENvdW50ID09PSAyKSB7XG4gICAgICAgICAgICByZXR1cm4gYnVpbGRJbnRlcm5hbEdyYXBoRm9yU3RlcmVvKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICB9O1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudE1vZGUsIHBhbiwgLi4uYXVkaW9Ob2RlT3B0aW9ucyB9KSA9PiB7XG4gICAgICAgIGlmIChjaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLmF1ZGlvTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDJcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50TW9kZSwgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgcGFuR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgZ2FpbjogcGFuXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgeyBjb25uZWN0R3JhcGgsIGRpc2Nvbm5lY3RHcmFwaCB9ID0gYnVpbGRJbnRlcm5hbEdyYXBoKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhbkdhaW5Ob2RlLmdhaW4sICdkZWZhdWx0VmFsdWUnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhbkdhaW5Ob2RlLmdhaW4sICdtYXhWYWx1ZScsIHsgZ2V0OiAoKSA9PiAxIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocGFuR2Fpbk5vZGUuZ2FpbiwgJ21pblZhbHVlJywgeyBnZXQ6ICgpID0+IC0xIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5ID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICh7IGNvbm5lY3RHcmFwaCwgZGlzY29ubmVjdEdyYXBoIH0gPSBidWlsZEludGVybmFsR3JhcGgobmF0aXZlQ29udGV4dCwgdmFsdWUsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ2NsYW1wZWQtbWF4JyB8fCB2YWx1ZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgaW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbaW5wdXRHYWluTm9kZV07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUubnVtYmVyT2ZPdXRwdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwYW4oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSwgY2hhbm5lbE1lcmdlck5vZGUpLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLCBpc0RDQ3VydmUsIG1vbml0b3JDb25uZWN0aW9ucywgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVXYXZlU2hhcGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGNvcnJlY3RseSBtYXAgdGhlIHZhbHVlcy5cbiAgICAgICAgICogQHRvZG8gVW5mb3J0dW5hdGVseSB0aGVyZSBpcyBubyB3YXkgdG8gdGVzdCBmb3IgdGhpcyBiZWhhdmlvciBpbiBhIHN5bmNocm9ub3VzIGZhc2hpb24gd2hpY2ggaXMgd2h5IHRlc3RpbmcgZm9yIHRoZSBleGlzdGVuY2Ugb2ZcbiAgICAgICAgICogdGhlIHdlYmtpdEF1ZGlvQ29udGV4dCBpcyB1c2VkIGFzIGEgd29ya2Fyb3VuZCBoZXJlLiBUZXN0aW5nIGZvciB0aGUgYXV0b21hdGlvblJhdGUgcHJvcGVydHkgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhpcyB3b3JrYXJvdW5kXG4gICAgICAgICAqIGlzbid0IG5lY2Vzc2FyeSBhbnltb3JlIHNpbmNlIHYxNC4wLjIgb2YgU2FmYXJpLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmXG4gICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0JyAmJlxuICAgICAgICAgICAgbmF0aXZlQ29udGV4dC5jcmVhdGVHYWluKCkuZ2Fpbi5hdXRvbWF0aW9uUmF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgY29uc3QgY3VydmUgPSBvcHRpb25zLmN1cnZlID09PSBudWxsIHx8IG9wdGlvbnMuY3VydmUgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBvcHRpb25zLmN1cnZlIDogbmV3IEZsb2F0MzJBcnJheShvcHRpb25zLmN1cnZlKTtcbiAgICAgICAgLy8gQnVnICMxMDQ6IENocm9tZSBhbmQgRWRnZSB3aWxsIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICBpZiAoY3VydmUgIT09IG51bGwgJiYgY3VydmUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBPbmx5IHZhbHVlcyBvZiB0eXBlIEZsb2F0MzJBcnJheSBjYW4gYmUgYXNzaWduZWQgdG8gdGhlIGN1cnZlIHByb3BlcnR5LlxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlV2F2ZVNoYXBlck5vZGUsIHsgY3VydmUgfSwgJ2N1cnZlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVXYXZlU2hhcGVyTm9kZSwgb3B0aW9ucywgJ292ZXJzYW1wbGUnKTtcbiAgICAgICAgbGV0IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCAnY3VydmUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChuYXRpdmVXYXZlU2hhcGVyTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwobmF0aXZlV2F2ZVNoYXBlck5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodmFsdWUpICYmIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFpc0RDQ3VydmUodmFsdWUpICYmIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKGlzRENDdXJ2ZShuYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSkpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXJGYWN0b3J5ID0gKGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBpc0RDQ3VydmUsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBjdXJ2ZSwgb3ZlcnNhbXBsZSwgLi4uYXVkaW9Ob2RlT3B0aW9ucyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgY29uc3QgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUsIGF1ZGlvTm9kZU9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUsIGF1ZGlvTm9kZU9wdGlvbnMpO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBpbnZlcnRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogLTEgfSk7XG4gICAgICAgIGNvbnN0IG91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCByZXZlcnRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogLTEgfSk7XG4gICAgICAgIGxldCBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIGxldCB1bm1vZGlmaWVkQ3VydmUgPSBudWxsO1xuICAgICAgICBjb25zdCBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyID0ge1xuICAgICAgICAgICAgZ2V0IGJ1ZmZlclNpemUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICByZXZlcnRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5tb2RpZmllZEN1cnZlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjdXJ2ZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTAyOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gSW52YWxpZFN0YXRlRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJ2ZUxlbmd0aCA9IHZhbHVlLmxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmVnYXRpdmVDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoY3VydmVMZW5ndGggKyAyIC0gKGN1cnZlTGVuZ3RoICUgMikpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdGl2ZUN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShjdXJ2ZUxlbmd0aCArIDIgLSAoY3VydmVMZW5ndGggJSAyKSk7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlQ3VydmVbMF0gPSB2YWx1ZVswXTtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVDdXJ2ZVswXSA9IC12YWx1ZVtjdXJ2ZUxlbmd0aCAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsZW5ndGggPSBNYXRoLmNlaWwoKGN1cnZlTGVuZ3RoICsgMSkgLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2VudGVySW5kZXggPSAoY3VydmVMZW5ndGggKyAxKSAvIDIgLSAxO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aGVvcmV0aWNJbmRleCA9IChpIC8gbGVuZ3RoKSAqIGNlbnRlckluZGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbG93ZXJJbmRleCA9IE1hdGguZmxvb3IodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXBwZXJJbmRleCA9IE1hdGguY2VpbCh0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlW2ldID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlckluZGV4ID09PSB1cHBlckluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gdmFsdWVbbG93ZXJJbmRleF1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoMSAtICh0aGVvcmV0aWNJbmRleCAtIGxvd2VySW5kZXgpKSAqIHZhbHVlW2xvd2VySW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIC0gKHVwcGVySW5kZXggLSB0aGVvcmV0aWNJbmRleCkpICogdmFsdWVbdXBwZXJJbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZUN1cnZlW2ldID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb3dlckluZGV4ID09PSB1cHBlckluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gLXZhbHVlW2N1cnZlTGVuZ3RoIC0gMSAtIGxvd2VySW5kZXhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogLSgoMSAtICh0aGVvcmV0aWNJbmRleCAtIGxvd2VySW5kZXgpKSAqIHZhbHVlW2N1cnZlTGVuZ3RoIC0gMSAtIGxvd2VySW5kZXhdKSAtXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIHZhbHVlW2N1cnZlTGVuZ3RoIC0gMSAtIHVwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlQ3VydmVbbGVuZ3RoXSA9IGN1cnZlTGVuZ3RoICUgMiA9PT0gMSA/IHZhbHVlW2xlbmd0aCAtIDFdIDogKHZhbHVlW2xlbmd0aCAtIDJdICsgdmFsdWVbbGVuZ3RoIC0gMV0pIC8gMjtcbiAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IG5lZ2F0aXZlQ3VydmU7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBwb3NpdGl2ZUN1cnZlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB1bm1vZGlmaWVkQ3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzRENDdXJ2ZSh1bm1vZGlmaWVkQ3VydmUpICYmIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3ZlcnNhbXBsZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBvdmVyc2FtcGxlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGlmIChjdXJ2ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gT25seSB2YWx1ZXMgb2YgdHlwZSBGbG9hdDMyQXJyYXkgY2FuIGJlIGFzc2lnbmVkIHRvIHRoZSBjdXJ2ZSBwcm9wZXJ0eS5cbiAgICAgICAgICAgIG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIuY3VydmUgPSBjdXJ2ZSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSA/IGN1cnZlIDogbmV3IEZsb2F0MzJBcnJheShjdXJ2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG92ZXJzYW1wbGUgIT09IG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIub3ZlcnNhbXBsZSkge1xuICAgICAgICAgICAgbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlci5vdmVyc2FtcGxlID0gb3ZlcnNhbXBsZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUpLmNvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGludmVydEdhaW5Ob2RlKS5jb25uZWN0KHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUpLmNvbm5lY3QocmV2ZXJ0R2Fpbk5vZGUpLmNvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKGlzRENDdXJ2ZSh1bm1vZGlmaWVkQ3VydmUpKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkRpc2Nvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoaW52ZXJ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuZGlzY29ubmVjdChwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyZXZlcnRHYWluTm9kZSk7XG4gICAgICAgICAgICByZXZlcnRHYWluTm9kZS5kaXNjb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLCBvdXRwdXRHYWluTm9kZSksIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnTm90U3VwcG9ydGVkRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5vdC1zdXBwb3J0ZWQtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbnVtYmVyT2ZDaGFubmVsczogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSAoYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzdGFydFJlbmRlcmluZykgPT4ge1xuICAgIHJldHVybiBjbGFzcyBPZmZsaW5lQXVkaW9Db250ZXh0IGV4dGVuZHMgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoYSwgYiwgYykge1xuICAgICAgICAgICAgbGV0IG9wdGlvbnM7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGEgPT09ICdudW1iZXInICYmIGIgIT09IHVuZGVmaW5lZCAmJiBjICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0geyBsZW5ndGg6IGIsIG51bWJlck9mQ2hhbm5lbHM6IGEsIHNhbXBsZVJhdGU6IGMgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZ2l2ZW4gcGFyYW1ldGVycyBhcmUgbm90IHZhbGlkLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgLy8gIzIxIFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIGFuZCB0aGVyZWZvcmUgd291bGQgZmlyZSB0aGUgc3RhdGVjaGFuZ2UgZXZlbnQgYmVmb3JlIHRoZSBwcm9taXNlIGNhbiBiZSByZXNvbHZlZC5cbiAgICAgICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RQcm9taXNlU3VwcG9ydCwgKCkgPT4gdGVzdFByb21pc2VTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCAoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlbGF5U3RhdGVDaGFuZ2VFdmVudCA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIGRlbGF5U3RhdGVDaGFuZ2VFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl93YWl0Rm9yVGhlUHJvbWlzZVRvU2V0dGxlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWxheVN0YXRlQ2hhbmdlRXZlbnQ7XG4gICAgICAgICAgICAgICAgfSkoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuX2xlbmd0aCA9IGxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZSA9PT0gbnVsbCA/IHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhdGUgOiB0aGlzLl9zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydFJlbmRlcmluZygpIHtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzkgJiAjNTk6IEl0IGlzIHRoZW9yZXRpY2FsbHkgcG9zc2libGUgdGhhdCBzdGFydFJlbmRlcmluZygpIHdpbGwgZmlyc3QgcmVuZGVyIGEgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuIFRoZXJlZm9yZVxuICAgICAgICAgICAgICogdGhlIHN0YXRlIG9mIHRoZSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IG1pZ2h0IG5vIHRyYW5zaXRpb24gdG8gcnVubmluZyBpbW1lZGlhdGVseS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdydW5uaW5nJztcbiAgICAgICAgICAgIHJldHVybiBzdGFydFJlbmRlcmluZyh0aGlzLmRlc3RpbmF0aW9uLCB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KS5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUF1ZGlvR3JhcGgodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBfd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBkZXR1bmU6IDAsXG4gICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgcGVyaW9kaWNXYXZlOiB1bmRlZmluZWQsXG4gICAgdHlwZTogJ3NpbmUnXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE9zY2lsbGF0b3JOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG9zY2lsbGF0b3JOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBjb25zdCBueXF1aXN0ID0gY29udGV4dC5zYW1wbGVSYXRlIC8gMjtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3NjaWxsYXRvck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzgxOiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9kZXR1bmUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZGV0dW5lLCAxNTM2MDAsIC0xNTM2MDApO1xuICAgICAgICAgICAgLy8gQnVnICM3NjogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3ksIG55cXVpc3QsIC1ueXF1aXN0KTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbmF0aXZlT3NjaWxsYXRvck5vZGU7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgPSBvc2NpbGxhdG9yTm9kZVJlbmRlcmVyO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwgJiYgbWVyZ2VkT3B0aW9ucy5wZXJpb2RpY1dhdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIucGVyaW9kaWNXYXZlID1cbiAgICAgICAgICAgICAgICAgICAgbWVyZ2VkT3B0aW9ucy5wZXJpb2RpY1dhdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRldHVuZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXR1bmU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZyZXF1ZW5jeSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLm9uZW5kZWQgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPbkVuZGVkID0gdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBuYXRpdmVPbkVuZGVkICE9PSBudWxsICYmIG5hdGl2ZU9uRW5kZWQgPT09IHdyYXBwZWRMaXN0ZW5lciA/IHZhbHVlIDogbmF0aXZlT25FbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS50eXBlO1xuICAgICAgICB9XG4gICAgICAgIHNldCB0eXBlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS50eXBlID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIucGVyaW9kaWNXYXZlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzZXRQZXJpb2RpY1dhdmUocGVyaW9kaWNXYXZlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zZXRQZXJpb2RpY1dhdmUocGVyaW9kaWNXYXZlKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5wZXJpb2RpY1dhdmUgPSBwZXJpb2RpY1dhdmU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnQod2hlbiA9IDApIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0YXJ0KHdoZW4pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnN0YXJ0ID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnKSB7XG4gICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUodGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdG9wKHdoZW4pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vc2NpbGxhdG9yLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgcGVyaW9kaWNXYXZlID0gbnVsbDtcbiAgICAgICAgbGV0IHN0YXJ0ID0gbnVsbDtcbiAgICAgICAgbGV0IHN0b3AgPSBudWxsO1xuICAgICAgICBjb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVPc2NpbGxhdG9yTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9zY2lsbGF0b3JOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlT3NjaWxsYXRvck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVPc2NpbGxhdG9yTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlT3NjaWxsYXRvck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRldHVuZTogbmF0aXZlT3NjaWxsYXRvck5vZGUuZGV0dW5lLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBmcmVxdWVuY3k6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlOiBwZXJpb2RpY1dhdmUgPT09IG51bGwgPyB1bmRlZmluZWQgOiBwZXJpb2RpY1dhdmUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnR5cGVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0YXJ0KHN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHN0b3AgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcChzdG9wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVPc2NpbGxhdG9yTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRldHVuZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmZyZXF1ZW5jeSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRldHVuZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZU9zY2lsbGF0b3JOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2V0IHBlcmlvZGljV2F2ZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0b3AodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdG9wID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZSA9IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVPc2NpbGxhdG9yTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vc2NpbGxhdG9yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnY2xhbXBlZC1tYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBjb25lSW5uZXJBbmdsZTogMzYwLFxuICAgIGNvbmVPdXRlckFuZ2xlOiAzNjAsXG4gICAgY29uZU91dGVyR2FpbjogMCxcbiAgICBkaXN0YW5jZU1vZGVsOiAnaW52ZXJzZScsXG4gICAgbWF4RGlzdGFuY2U6IDEwMDAwLFxuICAgIG9yaWVudGF0aW9uWDogMSxcbiAgICBvcmllbnRhdGlvblk6IDAsXG4gICAgb3JpZW50YXRpb25aOiAwLFxuICAgIHBhbm5pbmdNb2RlbDogJ2VxdWFscG93ZXInLFxuICAgIHBvc2l0aW9uWDogMCxcbiAgICBwb3NpdGlvblk6IDAsXG4gICAgcG9zaXRpb25aOiAwLFxuICAgIHJlZkRpc3RhbmNlOiAxLFxuICAgIHJvbGxvZmZGYWN0b3I6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlUGFubmVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlLCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgUGFubmVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgcGFubmVyTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlUGFubmVyTm9kZSwgcGFubmVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUgPSBuYXRpdmVQYW5uZXJOb2RlO1xuICAgICAgICAgICAgLy8gQnVnICM3NDogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX29yaWVudGF0aW9uWCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX29yaWVudGF0aW9uWSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWSwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX29yaWVudGF0aW9uWiA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWiwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uWCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uWSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWSwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIHRoaXMuX3Bvc2l0aW9uWiA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWiwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNvbmVJbm5lckFuZ2xlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZUlubmVyQW5nbGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNvbmVJbm5lckFuZ2xlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyQW5nbGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNvbmVPdXRlckFuZ2xlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNvbmVPdXRlckdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lT3V0ZXJHYWluKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckdhaW4gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGlzdGFuY2VNb2RlbCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWw7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGRpc3RhbmNlTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtYXhEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLm1heERpc3RhbmNlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBtYXhEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvcmllbnRhdGlvblgoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvcmllbnRhdGlvblkoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb25ZO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvcmllbnRhdGlvblooKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3JpZW50YXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYW5uaW5nTW9kZWwoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5wYW5uaW5nTW9kZWw7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHBhbm5pbmdNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5wYW5uaW5nTW9kZWwgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcG9zaXRpb25YKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcG9zaXRpb25ZKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcG9zaXRpb25aKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc2l0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmVmRGlzdGFuY2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yZWZEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgcmVmRGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucmVmRGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcm9sbG9mZkZhY3RvcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHJvbGxvZmZGYWN0b3IodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucm9sbG9mZkZhY3RvciA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgcmVuZGVyZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlR2Fpbk5vZGUgPSBudWxsO1xuICAgICAgICAgICAgbGV0IG5hdGl2ZVBhbm5lck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgY29uc3QgY29tbW9uQXVkaW9Ob2RlT3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVBhbm5lck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZVBhbm5lck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZVBhbm5lck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICBjb25lSW5uZXJBbmdsZTogbmF0aXZlUGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZSxcbiAgICAgICAgICAgICAgICBjb25lT3V0ZXJBbmdsZTogbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZSxcbiAgICAgICAgICAgICAgICBjb25lT3V0ZXJHYWluOiBuYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckdhaW4sXG4gICAgICAgICAgICAgICAgZGlzdGFuY2VNb2RlbDogbmF0aXZlUGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsLFxuICAgICAgICAgICAgICAgIG1heERpc3RhbmNlOiBuYXRpdmVQYW5uZXJOb2RlLm1heERpc3RhbmNlLFxuICAgICAgICAgICAgICAgIHBhbm5pbmdNb2RlbDogbmF0aXZlUGFubmVyTm9kZS5wYW5uaW5nTW9kZWwsXG4gICAgICAgICAgICAgICAgcmVmRGlzdGFuY2U6IG5hdGl2ZVBhbm5lck5vZGUucmVmRGlzdGFuY2UsXG4gICAgICAgICAgICAgICAgcm9sbG9mZkZhY3RvcjogbmF0aXZlUGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZVBhbm5lck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlUGFubmVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAvLyBCdWcgIzEyNDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgbW9kaWZ5aW5nIHRoZSBvcmllbnRhdGlvbiBhbmQgdGhlIHBvc2l0aW9uIHdpdGggQXVkaW9QYXJhbXMuXG4gICAgICAgICAgICBpZiAoJ2J1ZmZlclNpemUnIGluIG5hdGl2ZVBhbm5lck5vZGUpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHsgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFuYXRpdmVQYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblg6IG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblk6IG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblo6IG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25aLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblg6IG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25YLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblk6IG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblo6IG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25aLnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUgPT09IG51bGwgPyBuYXRpdmVQYW5uZXJOb2RlIDogbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUdhaW5Ob2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkQnVmZmVyUHJvbWlzZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcig2LCBcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgICAgICAgICAgcHJveHkuY29udGV4dC5sZW5ndGgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogNlxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIHJlbmRlcmVkQnVmZmVyUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5Lm9yaWVudGF0aW9uWCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5vcmllbnRhdGlvblksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkub3JpZW50YXRpb25aLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5LnBvc2l0aW9uWCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3NpdGlvblksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkucG9zaXRpb25aXG4gICAgICAgICAgICAgICAgICAgICAgICBdLm1hcChhc3luYyAoYXVkaW9QYXJhbSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZnNldDogaW5kZXggPT09IDAgPyAxIDogMFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24ocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXNbaV0uY29ubmVjdChuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgMCwgaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlc1tpXS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWRCdWZmZXIgPSBhd2FpdCByZW5kZXJlZEJ1ZmZlclByb21pc2U7XG4gICAgICAgICAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHsgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgaW5wdXRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGFzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW5kZXJlZEJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbERhdGFzLnB1c2gocmVuZGVyZWRCdWZmZXIuZ2V0Q2hhbm5lbERhdGEoaSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgbGFzdE9yaWVudGF0aW9uID0gW2NoYW5uZWxEYXRhc1swXVswXSwgY2hhbm5lbERhdGFzWzFdWzBdLCBjaGFubmVsRGF0YXNbMl1bMF1dO1xuICAgICAgICAgICAgICAgIGxldCBsYXN0UG9zaXRpb24gPSBbY2hhbm5lbERhdGFzWzNdWzBdLCBjaGFubmVsRGF0YXNbNF1bMF0sIGNoYW5uZWxEYXRhc1s1XVswXV07XG4gICAgICAgICAgICAgICAgbGV0IGdhdGVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHsgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgICAgICAgICBsZXQgcGFydGlhbFBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWDogbGFzdE9yaWVudGF0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblk6IGxhc3RPcmllbnRhdGlvblsxXSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBsYXN0T3JpZW50YXRpb25bMl0sXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWDogbGFzdFBvc2l0aW9uWzBdLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblk6IGxhc3RQb3NpdGlvblsxXSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBsYXN0UG9zaXRpb25bMl1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QoZ2F0ZUdhaW5Ob2RlKS5jb25uZWN0KHBhcnRpYWxQYW5uZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFydGlhbFBhbm5lck5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDEyODsgaSA8IHJlbmRlcmVkQnVmZmVyLmxlbmd0aDsgaSArPSAxMjgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3JpZW50YXRpb24gPSBbY2hhbm5lbERhdGFzWzBdW2ldLCBjaGFubmVsRGF0YXNbMV1baV0sIGNoYW5uZWxEYXRhc1syXVtpXV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0b24gPSBbY2hhbm5lbERhdGFzWzNdW2ldLCBjaGFubmVsRGF0YXNbNF1baV0sIGNoYW5uZWxEYXRhc1s1XVtpXV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdE9yaWVudGF0aW9uID0gb3JpZW50YXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3NpdG9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBpIC8gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2F0ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2F0ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgeyAuLi5jb21tb25BdWRpb05vZGVPcHRpb25zLCBnYWluOiAwIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGlhbFBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5jb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblg6IGxhc3RPcmllbnRhdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblk6IGxhc3RPcmllbnRhdGlvblsxXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblo6IGxhc3RPcmllbnRhdGlvblsyXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblg6IGxhc3RQb3NpdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblk6IGxhc3RQb3NpdGlvblsxXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblo6IGxhc3RQb3NpdGlvblsyXVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBnYXRlR2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QoZ2F0ZUdhaW5Ob2RlKS5jb25uZWN0KHBhcnRpYWxQYW5uZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsUGFubmVyTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlR2Fpbk5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVBhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblgsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblkpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWik7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblgsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25YKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblkpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblgsIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblksIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblosIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25aKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblgsIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25YKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblksIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblosIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25aKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZVBhbm5lck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVBhbm5lck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVQYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVQYW5uZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZU9yTmF0aXZlUGFubmVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVPck5hdGl2ZVBhbm5lck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVPck5hdGl2ZVBhbm5lck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBhbm5lci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGRpc2FibGVOb3JtYWxpemF0aW9uOiBmYWxzZVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVQZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciA9IChjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUsIGdldE5hdGl2ZUNvbnRleHQsIHBlcmlvZGljV2F2ZVN0b3JlLCBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgUGVyaW9kaWNXYXZlIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zKHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH0pO1xuICAgICAgICAgICAgY29uc3QgcGVyaW9kaWNXYXZlID0gY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgcGVyaW9kaWNXYXZlU3RvcmUuYWRkKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgICAgICAvLyBUaGlzIGRvZXMgdmlvbGF0ZSBhbGwgZ29vZCBwcmF0aWNlcyBidXQgaXQgaXMgdXNlZCBoZXJlIHRvIHNpbXBsaWZ5IHRoZSBoYW5kbGluZyBvZiBwZXJpb2RpYyB3YXZlcy5cbiAgICAgICAgICAgIHJldHVybiBwZXJpb2RpY1dhdmU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGljIFtTeW1ib2wuaGFzSW5zdGFuY2VdKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gKChpbnN0YW5jZSAhPT0gbnVsbCAmJiB0eXBlb2YgaW5zdGFuY2UgPT09ICdvYmplY3QnICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnN0YW5jZSkgPT09IFBlcmlvZGljV2F2ZS5wcm90b3R5cGUpIHx8XG4gICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlU3RvcmUuaGFzKGluc3RhbmNlKSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXBlcmlvZGljLXdhdmUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVJlbmRlckF1dG9tYXRpb24gPSAoZ2V0QXVkaW9QYXJhbVJlbmRlcmVyLCByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIG5hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbVJlbmRlcmVyID0gZ2V0QXVkaW9QYXJhbVJlbmRlcmVyKGF1ZGlvUGFyYW0pO1xuICAgICAgICBhdWRpb1BhcmFtUmVuZGVyZXIucmVwbGF5KG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgICAgICByZXR1cm4gcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKGF1ZGlvUGFyYW0sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWF1dG9tYXRpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9Ob2RlID0gKGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRBdWRpb05vZGVSZW5kZXJlciwgaXNQYXJ0T2ZBQ3ljbGUpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoYXVkaW9Ob2RlQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzXG4gICAgICAgICAgICAubWFwKChjb25uZWN0aW9ucywgaW5wdXQpID0+IEFycmF5LmZyb20oY29ubmVjdGlvbnMpLm1hcChhc3luYyAoW3NvdXJjZSwgb3V0cHV0XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Ob2RlUmVuZGVyZXIgPSBnZXRBdWRpb05vZGVSZW5kZXJlcihzb3VyY2UpO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSBhd2FpdCBhdWRpb05vZGVSZW5kZXJlci5yZW5kZXIoc291cmNlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGRlc3RpbmF0aW9uID0gYXVkaW9Ob2RlLmNvbnRleHQuZGVzdGluYXRpb247XG4gICAgICAgICAgICBpZiAoIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkgJiYgKGF1ZGlvTm9kZSAhPT0gZGVzdGluYXRpb24gfHwgIWlzUGFydE9mQUN5Y2xlKGF1ZGlvTm9kZSkpKSB7XG4gICAgICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSlcbiAgICAgICAgICAgIC5yZWR1Y2UoKGFsbFJlbmRlcmluZ1Byb21pc2VzLCByZW5kZXJpbmdQcm9taXNlcykgPT4gWy4uLmFsbFJlbmRlcmluZ1Byb21pc2VzLCAuLi5yZW5kZXJpbmdQcm9taXNlc10sIFtdKSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbSA9IChnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBpc1BhcnRPZkFDeWNsZSkgPT4ge1xuICAgIHJldHVybiBhc3luYyAoYXVkaW9QYXJhbSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb1BhcmFtQ29ubmVjdGlvbnMgPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSk7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKEFycmF5LmZyb20oYXVkaW9QYXJhbUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0cykubWFwKGFzeW5jIChbc291cmNlLCBvdXRwdXRdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhdWRpb05vZGVSZW5kZXJlciA9IGdldEF1ZGlvTm9kZVJlbmRlcmVyKHNvdXJjZSk7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSA9IGF3YWl0IGF1ZGlvTm9kZVJlbmRlcmVyLnJlbmRlcihzb3VyY2UsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSAoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgdGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgLy8gQnVnICMyMTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgcHJvbWlzZXMgeWV0LlxuICAgICAgICBpZiAoY2FjaGVUZXN0UmVzdWx0KHRlc3RQcm9taXNlU3VwcG9ydCwgKCkgPT4gdGVzdFByb21pc2VTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKSkge1xuICAgICAgICAgICAgLy8gQnVnICMxNTg6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgYWR2YW5jZSBjdXJyZW50VGltZSBpZiBpdCBpcyBub3QgYWNjZXNzZWQgd2hpbGUgcmVuZGVyaW5nIHRoZSBhdWRpby5cbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY2FjaGVUZXN0UmVzdWx0KHRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0LCB0ZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCkpLnRoZW4oKGlzT2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydGVkKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCA1MTIsIDAsIDEpO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lm9uY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gbnVsbDsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoKSA9PiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmN1cnJlbnRUaW1lOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29ubmVjdChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgLy8gQnVnICM0ODogU2FmYXJpIGRvZXMgbm90IHJlbmRlciBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGhvdXQgYW55IGNvbm5lY3RlZCBub2RlLlxuICAgICAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgIGdhaW46IDBcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgZ2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoZXZlbnQucmVuZGVyZWRCdWZmZXIpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGdhaW5Ob2RlLmNvbm5lY3QobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSAoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhY3RpdmVJbnB1dHMpID0+IHtcbiAgICAgICAgYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlLnNldChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhY3RpdmVJbnB1dHMpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVTZXRBdWRpb05vZGVUYWlsVGltZSA9IChhdWRpb05vZGVUYWlsVGltZVN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIHRhaWxUaW1lKSA9PiBhdWRpb05vZGVUYWlsVGltZVN0b3JlLnNldChhdWRpb05vZGUsIHRhaWxUaW1lKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUuanMubWFwIiwiaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kJztcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGFydFJlbmRlcmluZyA9IChhdWRpb0J1ZmZlclN0b3JlLCBjYWNoZVRlc3RSZXN1bHQsIGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcykgPT4ge1xuICAgIHJldHVybiAoZGVzdGluYXRpb24sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IGdldEF1ZGlvTm9kZVJlbmRlcmVyKGRlc3RpbmF0aW9uKVxuICAgICAgICAucmVuZGVyKGRlc3RpbmF0aW9uLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KVxuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzg2ICYgIzg3OiBJbnZva2luZyB0aGUgcmVuZGVyZXIgb2YgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBtaWdodCBiZSBuZWNlc3NhcnkgaWYgaXQgaGFzIG5vIGRpcmVjdCBvciBpbmRpcmVjdCBjb25uZWN0aW9uIHRvIHRoZVxuICAgICAgICAgKiBkZXN0aW5hdGlvbi5cbiAgICAgICAgICovXG4gICAgICAgIC50aGVuKCgpID0+IFByb21pc2UuYWxsKEFycmF5LmZyb20oZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKS5tYXAoKGF1ZGlvV29ya2xldE5vZGUpID0+IGdldEF1ZGlvTm9kZVJlbmRlcmVyKGF1ZGlvV29ya2xldE5vZGUpLnJlbmRlcihhdWRpb1dvcmtsZXROb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpKVxuICAgICAgICAudGhlbigoKSA9PiByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpKVxuICAgICAgICAudGhlbigoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICAvLyBCdWcgIzEwMDogU2FmYXJpIGRvZXMgdGhyb3cgYSB3cm9uZyBlcnJvciB3aGVuIGNhbGxpbmcgZ2V0Q2hhbm5lbERhdGEoKSB3aXRoIGFuIG91dC1vZi1ib3VuZHMgdmFsdWUuXG4gICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgLy8gQnVnICMxNTc6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdGhlIGJ1ZmZlck9mZnNldCB0byBiZSBvdXQtb2YtYm91bmRzLlxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQoYXVkaW9CdWZmZXIpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyO1xuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0YXJ0LXJlbmRlcmluZy5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIC8qXG4gICAgICogQnVnICMxMDU6IFRoZSBjaGFubmVsQ291bnRNb2RlIHNob3VsZCBiZSAnY2xhbXBlZC1tYXgnIGFjY29yZGluZyB0byB0aGUgc3BlYyBidXQgaXMgc2V0IHRvICdleHBsaWNpdCcgdG8gYWNoaWV2ZSBjb25zaXN0ZW50XG4gICAgICogYmVoYXZpb3IuXG4gICAgICovXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgcGFuOiAwXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgU3RlcmVvUGFubmVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgc3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgc3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX3BhbiA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLnBhbik7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBhbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYW47XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0ZXJlby1wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVTdGVyZW9QYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgcGFuOiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLnBhbi52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlU3RlcmVvUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBhbiwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGFuLCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLnBhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVTdGVyZW9QYW5uZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlU3RlcmVvUGFubmVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZSA9IHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlU3RlcmVvUGFubmVyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0ZXJlby1wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsIi8vIEJ1ZyAjMzM6IFNhZmFyaSBleHBvc2VzIGFuIEF1ZGlvQnVmZmVyIGJ1dCBpdCBjYW4ndCBiZSB1c2VkIGFzIGEgY29uc3RydWN0b3IuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXcgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3Rvcih7IGxlbmd0aDogMSwgc2FtcGxlUmF0ZTogNDQxMDAgfSk7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tdW51c2VkLWV4cHJlc3Npb25cbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci1zdXBwb3J0LmpzLm1hcCIsIi8vIEJ1ZyAjMTc5OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRvIHRyYW5zZmVyIGFueSBidWZmZXIgd2hpY2ggaGFzIGJlZW4gcGFzc2VkIHRvIHRoZSBwcm9jZXNzKCkgbWV0aG9kIGFzIGFuIGFyZ3VtZW50LlxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQgPSAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBCdWcgIzYxOiBJZiB0aGVyZSBpcyBubyBuYXRpdmUgQXVkaW9Xb3JrbGV0Tm9kZSBpdCBnZXRzIGZha2VkIGFuZCB0aGVyZWZvcmUgaXQgaXMgbm8gcHJvYmxlbSBpZiB0aGUgaXQgZG9lc24ndCBleGlzdC5cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbJ2NsYXNzIEEgZXh0ZW5kcyBBdWRpb1dvcmtsZXRQcm9jZXNzb3J7cHJvY2VzcyhpKXt0aGlzLnBvcnQucG9zdE1lc3NhZ2UoaSxbaVswXVswXS5idWZmZXJdKX19cmVnaXN0ZXJQcm9jZXNzb3IoXCJhXCIsQSknXSwge1xuICAgICAgICAgICAgdHlwZTogJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLTgnXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzE0MTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY3JlYXRpbmcgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRoIGxlc3MgdGhhbiA0NDEwMCBIei5cbiAgICAgICAgY29uc3Qgb2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoMSwgMTI4LCA0NDEwMCk7XG4gICAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGxldCBpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyA9IGZhbHNlO1xuICAgICAgICBsZXQgaXNFbWl0dGluZ1Byb2Nlc3NvckVycm9yRXZlbnRzID0gZmFsc2U7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBvZmZsaW5lQXVkaW9Db250ZXh0LmF1ZGlvV29ya2xldC5hZGRNb2R1bGUodXJsKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldE5vZGUgPSBuZXcgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKG9mZmxpbmVBdWRpb0NvbnRleHQsICdhJywgeyBudW1iZXJPZk91dHB1dHM6IDAgfSk7XG4gICAgICAgICAgICBjb25zdCBvc2NpbGxhdG9yID0gb2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgICAgICBhdWRpb1dvcmtsZXROb2RlLnBvcnQub25tZXNzYWdlID0gKCkgPT4gKGlzRW1pdHRpbmdNZXNzYWdlRXZlbnRzID0gdHJ1ZSk7XG4gICAgICAgICAgICBhdWRpb1dvcmtsZXROb2RlLm9ucHJvY2Vzc29yZXJyb3IgPSAoKSA9PiAoaXNFbWl0dGluZ1Byb2Nlc3NvckVycm9yRXZlbnRzID0gdHJ1ZSk7XG4gICAgICAgICAgICBvc2NpbGxhdG9yLmNvbm5lY3QoYXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgICAgICAgICBvc2NpbGxhdG9yLnN0YXJ0KDApO1xuICAgICAgICAgICAgYXdhaXQgb2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIC8vIElnbm9yZSBlcnJvcnMuXG4gICAgICAgIH1cbiAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGlzRW1pdHRpbmdNZXNzYWdlRXZlbnRzICYmICFpc0VtaXR0aW5nUHJvY2Vzc29yRXJyb3JFdmVudHM7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXBvc3QtbWVzc2FnZS1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVUZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCA9IChjcmVhdGVOYXRpdmVHYWluTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoMSwgMSwgNDQxMDApO1xuICAgICAgICAvLyBCdWcgIzQ4OiBTYWZhcmkgZG9lcyBub3QgcmVuZGVyIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aG91dCBhbnkgY29ubmVjdGVkIG5vZGUuXG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIGdhaW46IDBcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIHlldC5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lm9uY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgZ2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jdXJyZW50VGltZSAhPT0gMCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3Qtb2ZmbGluZS1hdWRpby1jb250ZXh0LWN1cnJlbnQtdGltZS1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVVbmtub3duRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnVW5rbm93bkVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD11bmtub3duLWVycm9yLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGN1cnZlOiBudWxsLFxuICAgIG92ZXJzYW1wbGU6ICdub25lJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgV2F2ZVNoYXBlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgd2F2ZVNoYXBlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyKCkgOiBudWxsKTtcbiAgICAgICAgICAgIC8vIEB0b2RvIEFkZCBhIG1lY2hhbmlzbSB0byBvbmx5IHN3aXRjaCBhIFdhdmVTaGFwZXJOb2RlIHRvIGFjdGl2ZSB3aGlsZSBpdCBpcyBjb25uZWN0ZWQuXG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVXYXZlU2hhcGVyTm9kZSwgd2F2ZVNoYXBlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9pc0N1cnZlTnVsbGlmaWVkID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZSA9IG5hdGl2ZVdhdmVTaGFwZXJOb2RlO1xuICAgICAgICAgICAgLy8gQHRvZG8gRGV0ZXJtaW5lIGEgbWVhbmluZ2Z1bCB0YWlsLXRpbWUgaW5zdGVhZCBvZiBqdXN0IHVzaW5nIG9uZSBzZWNvbmQuXG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAxKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNDdXJ2ZU51bGxpZmllZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjdXJ2ZSh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxMDM6IFNhZmFyaSBkb2VzIG5vdCBhbGxvdyB0byBzZXQgdGhlIGN1cnZlIHRvIG51bGwuXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0N1cnZlTnVsbGlmaWVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoWzAsIDBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTAyOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gSW52YWxpZFN0YXRlRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwNDogQ2hyb21lIGFuZCBFZGdlIHdpbGwgdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb3ZlcnNhbXBsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13YXZlLXNoYXBlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZVdhdmVTaGFwZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVXYXZlU2hhcGVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVdhdmVTaGFwZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgY3VydmU6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlLFxuICAgICAgICAgICAgICAgICAgICBvdmVyc2FtcGxlOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5vdmVyc2FtcGxlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZVdhdmVTaGFwZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVXYXZlU2hhcGVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGUgPSByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlV2F2ZVNoYXBlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2F2ZS1zaGFwZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXaW5kb3cgPSAoKSA9PiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogd2luZG93KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdpbmRvdy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzID0gKGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZywgY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9IChkZXN0aW5hdGlvbiwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTnVtYmVyID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGNoYW5uZWxOdW1iZXJBc051bWJlcik7XG4gICAgICAgICAgICBpZiAoY2hhbm5lbE51bWJlciA+PSBhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyTGVuZ3RoID0gYXVkaW9CdWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGRlc3RpbmF0aW9uTGVuZ3RoID0gZGVzdGluYXRpb24ubGVuZ3RoO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGJ1ZmZlck9mZnNldCA8IDAgPyAtYnVmZmVyT2Zmc2V0IDogMDsgaSArIGJ1ZmZlck9mZnNldCA8IGF1ZGlvQnVmZmVyTGVuZ3RoICYmIGkgPCBkZXN0aW5hdGlvbkxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25baV0gPSBjaGFubmVsRGF0YVtpICsgYnVmZmVyT2Zmc2V0XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXVkaW9CdWZmZXIuY29weVRvQ2hhbm5lbCA9IChzb3VyY2UsIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxOdW1iZXIgPj0gYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlckxlbmd0aCA9IGF1ZGlvQnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcik7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VMZW5ndGggPSBzb3VyY2UubGVuZ3RoO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGJ1ZmZlck9mZnNldCA8IDAgPyAtYnVmZmVyT2Zmc2V0IDogMDsgaSArIGJ1ZmZlck9mZnNldCA8IGF1ZGlvQnVmZmVyTGVuZ3RoICYmIGkgPCBzb3VyY2VMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxEYXRhW2kgKyBidWZmZXJPZmZzZXRdID0gc291cmNlW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzID0gKGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZykgPT4ge1xuICAgIHJldHVybiAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsID0gKChjb3B5RnJvbUNoYW5uZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoZGVzdGluYXRpb24sIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsTnVtYmVyID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGNoYW5uZWxOdW1iZXJBc051bWJlcik7XG4gICAgICAgICAgICAgICAgaWYgKGJ1ZmZlck9mZnNldCA8IGF1ZGlvQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29weUZyb21DaGFubmVsLmNhbGwoYXVkaW9CdWZmZXIsIGRlc3RpbmF0aW9uLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCk7XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwgPSAoKGNvcHlUb0NoYW5uZWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoc291cmNlLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGlmIChidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvcHlUb0NoYW5uZWwuY2FsbChhdWRpb0J1ZmZlciwgc291cmNlLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIgPSAob3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbnVsbGlmaWVkQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgNDQxMDApO1xuICAgICAgICBpZiAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG51bGxpZmllZEJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCAnYnVmZmVyJywgKGdldCkgPT4gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsaWZpZWRCdWZmZXIgPyBudWxsIDogdmFsdWU7XG4gICAgICAgIH0sIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHNldC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgdmFsdWUgPT09IG51bGwgPyBudWxsaWZpZWRCdWZmZXIgOiB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV3JhcENoYW5uZWxNZXJnZXJOb2RlID0gKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTU6IFNhZmFyaSBkb2VzIG5vdCByZXR1cm4gdGhlIGRlZmF1bHQgcHJvcGVydGllcy5cbiAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY2hhbm5lbENvdW50ID0gMTtcbiAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY2hhbm5lbENvdW50TW9kZSA9ICdleHBsaWNpdCc7XG4gICAgICAgIC8vIEJ1ZyAjMTY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB3aGVuIHNldHRpbmcgYSBkaWZmZXJlbnQgY2hhbm5lbENvdW50IG9yIGNoYW5uZWxDb3VudE1vZGUuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsTWVyZ2VyTm9kZSwgJ2NoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gMSxcbiAgICAgICAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbE1lcmdlck5vZGUsICdjaGFubmVsQ291bnRNb2RlJywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgc2V0OiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMjA6IFNhZmFyaSByZXF1aXJlcyBhIGNvbm5lY3Rpb24gb2YgYW55IGtpbmQgdG8gdHJlYXQgdGhlIGlucHV0IHNpZ25hbCBjb3JyZWN0bHkuXG4gICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsZW5ndGggPSBjaGFubmVsTWVyZ2VyTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIG1vbml0b3JDb25uZWN0aW9ucyhjaGFubmVsTWVyZ2VyTm9kZSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWNoYW5uZWwtbWVyZ2VyLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGdldEZpcnN0U2FtcGxlID0gKGF1ZGlvQnVmZmVyLCBidWZmZXIsIGNoYW5uZWxOdW1iZXIpID0+IHtcbiAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpIGFuZCBjb3B5VG9DaGFubmVsKCkuXG4gICAgaWYgKGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKVswXTtcbiAgICB9XG4gICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsKGJ1ZmZlciwgY2hhbm5lbE51bWJlcik7XG4gICAgcmV0dXJuIGJ1ZmZlclswXTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtZmlyc3Qtc2FtcGxlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0RDQ3VydmUgPSAoY3VydmUpID0+IHtcbiAgICBpZiAoY3VydmUgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBjdXJ2ZS5sZW5ndGg7XG4gICAgaWYgKGxlbmd0aCAlIDIgIT09IDApIHtcbiAgICAgICAgcmV0dXJuIGN1cnZlW01hdGguZmxvb3IobGVuZ3RoIC8gMildICE9PSAwO1xuICAgIH1cbiAgICByZXR1cm4gY3VydmVbbGVuZ3RoIC8gMiAtIDFdICsgY3VydmVbbGVuZ3RoIC8gMl0gIT09IDA7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtZGMtY3VydmUuanMubWFwIiwiZXhwb3J0IGNvbnN0IG92ZXJ3cml0ZUFjY2Vzc29ycyA9IChvYmplY3QsIHByb3BlcnR5LCBjcmVhdGVHZXR0ZXIsIGNyZWF0ZVNldHRlcikgPT4ge1xuICAgIGxldCBwcm90b3R5cGUgPSBvYmplY3Q7XG4gICAgd2hpbGUgKCFwcm90b3R5cGUuaGFzT3duUHJvcGVydHkocHJvcGVydHkpKSB7XG4gICAgICAgIHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90b3R5cGUpO1xuICAgIH1cbiAgICBjb25zdCB7IGdldCwgc2V0IH0gPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvdHlwZSwgcHJvcGVydHkpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmplY3QsIHByb3BlcnR5LCB7IGdldDogY3JlYXRlR2V0dGVyKGdldCksIHNldDogY3JlYXRlU2V0dGVyKHNldCkgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3ZlcndyaXRlLWFjY2Vzc29ycy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgICAgb3V0cHV0Q2hhbm5lbENvdW50OiBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50XG4gICAgICAgICAgICA6IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMgPT09IDEgJiYgb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPT09IDFcbiAgICAgICAgICAgICAgICA/IC8qXG4gICAgICAgICAgICAgICAgICAgKiBCdWcgIzYxOiBUaGlzIHNob3VsZCBiZSB0aGUgY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzLCBidXQgdW5mb3J0dW5hdGVseSB0aGF0IGlzIGFsbW9zdCBpbXBvc3NpYmxlIHRvIGZha2UuIFRoYXQncyB3aHlcbiAgICAgICAgICAgICAgICAgICAqIHRoZSBjaGFubmVsQ291bnRNb2RlIGlzIHJlcXVpcmVkIHRvIGJlICdleHBsaWNpdCcgYXMgbG9uZyBhcyB0aGVyZSBpcyBub3QgYSBuYXRpdmUgaW1wbGVtZW50YXRpb24gaW4gZXZlcnkgYnJvd3Nlci4gVGhhdFxuICAgICAgICAgICAgICAgICAgICogbWFrZXMgc3VyZSB0aGUgY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzIGlzIGVxdWl2aWxhbnQgdG8gdGhlIGNoYW5uZWxDb3VudCB3aGljaCBtYWtlcyBpdCBtdWNoIGVhc2llciB0byBjb21wdXRlLlxuICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgIFtvcHRpb25zLmNoYW5uZWxDb3VudF1cbiAgICAgICAgICAgICAgICA6IEFycmF5LmZyb20oeyBsZW5ndGg6IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzIH0sICgpID0+IDEpXG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zYW5pdGl6ZS1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4geyAuLi5vcHRpb25zLCBjaGFubmVsQ291bnQ6IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2FuaXRpemUtY2hhbm5lbC1zcGxpdHRlci1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMgPSAob3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgaW1hZywgcmVhbCB9ID0gb3B0aW9ucztcbiAgICBpZiAoaW1hZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChyZWFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWc6IFswLCAwXSwgcmVhbDogWzAsIDBdIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgaW1hZzogQXJyYXkuZnJvbShyZWFsLCAoKSA9PiAwKSwgcmVhbCB9O1xuICAgIH1cbiAgICBpZiAocmVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWcsIHJlYWw6IEFycmF5LmZyb20oaW1hZywgKCkgPT4gMCkgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgaW1hZywgcmVhbCB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNhbml0aXplLXBlcmlvZGljLXdhdmUtb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlID0gKGF1ZGlvUGFyYW0sIHZhbHVlLCBzdGFydFRpbWUpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChlcnIuY29kZSAhPT0gOSkge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZShhdWRpb1BhcmFtLCB2YWx1ZSwgc3RhcnRUaW1lICsgMWUtNyk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC12YWx1ZS1hdC10aW1lLXVudGlsLXBvc3NpYmxlLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCA0NDEwMCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgwLCAxKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmctc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKCk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgtMSk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIGVyciBpbnN0YW5jZW9mIFJhbmdlRXJyb3I7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIDQ0MTAwKTtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlcjtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgIHRyeSB7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdG9wKCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgtMSk7XG4gICAgfVxuICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIGVyciBpbnN0YW5jZW9mIFJhbmdlRXJyb3I7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5ID0gKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKSA9PiB7XG4gICAgY29uc3QgeyBwb3J0MSwgcG9ydDIgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDEucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgcG9ydDIuY2xvc2UoKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy1jbG9uYWJpbGl0eS5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmcgPSAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0ID0gKChzdGFydCkgPT4ge1xuICAgICAgICByZXR1cm4gKHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlcjtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU0OiBTYWZhcmkgZG9lcyBub3QgY2xhbXAgdGhlIG9mZnNldCBpZiBpdCBpcyBlcXVhbCB0byBvciBncmVhdGVyIHRoYW4gdGhlIGR1cmF0aW9uIG9mIHRoZSBidWZmZXIuXG4gICAgICAgICAgICBjb25zdCBjbGFtcGVkT2Zmc2V0ID0gYnVmZmVyID09PSBudWxsID8gb2Zmc2V0IDogTWF0aC5taW4oYnVmZmVyLmR1cmF0aW9uLCBvZmZzZXQpO1xuICAgICAgICAgICAgLy8gQnVnICMxNTU6IFNhZmFyaSBkb2VzIG5vdCBoYW5kbGUgdGhlIG9mZnNldCBjb3JyZWN0bHkgaWYgaXQgd291bGQgY2F1c2UgdGhlIGJ1ZmZlciB0byBiZSBub3QgYmUgcGxheWVkIGF0IGFsbC5cbiAgICAgICAgICAgIGlmIChidWZmZXIgIT09IG51bGwgJiYgY2xhbXBlZE9mZnNldCA+IGJ1ZmZlci5kdXJhdGlvbiAtIDAuNSAvIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb250ZXh0LnNhbXBsZVJhdGUpIHtcbiAgICAgICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbiwgMCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbiwgY2xhbXBlZE9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy5qcy5tYXAiLCJpbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4vaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMgPSAobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgY29uc3QgZGlzY29ubmVjdEdhaW5Ob2RlID0gKChkaXNjb25uZWN0KSA9PiB7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAxIGFyZ3VtZW50IHlldC5cbiAgICAgICAgICAgIGRpc2Nvbm5lY3QuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIGRpc2Nvbm5lY3RHYWluTm9kZSk7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QpO1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIGRpc2Nvbm5lY3RHYWluTm9kZSk7XG4gICAgaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCBuYXRpdmVHYWluTm9kZSk7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3AgPSAoKHN0b3ApID0+IHtcbiAgICAgICAgbGV0IGlzU3RvcHBlZCA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gKHdoZW4gPSAwKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNTdG9wcGVkKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgc3RvcC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB3aGVuKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdG9wLmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCB3aGVuKTtcbiAgICAgICAgICAgICAgICBpc1N0b3BwZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEV2ZW50TGlzdGVuZXIgPSAodGFyZ2V0LCBldmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIChldmVudCkgPT4ge1xuICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0geyB2YWx1ZTogdGFyZ2V0IH07XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGV2ZW50LCB7XG4gICAgICAgICAgICBjdXJyZW50VGFyZ2V0OiBkZXNjcmlwdG9yLFxuICAgICAgICAgICAgdGFyZ2V0OiBkZXNjcmlwdG9yXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodHlwZW9mIGV2ZW50TGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudExpc3RlbmVyLmNhbGwodGFyZ2V0LCBldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV2ZW50TGlzdGVuZXIuaGFuZGxlRXZlbnQuY2FsbCh0YXJnZXQsIGV2ZW50KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtZXZlbnQtbGlzdGVuZXIuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudCwgY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudCB9IGZyb20gJ2F1dG9tYXRpb24tZXZlbnRzJztcbmltcG9ydCB7IGNyZWF0ZUFib3J0RXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hYm9ydC1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVBZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGNyZWF0ZUFkZEF1ZGlvV29ya2xldE1vZHVsZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby13b3JrbGV0LW1vZHVsZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRTaWxlbnRDb25uZWN0aW9uIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLXNpbGVudC1jb25uZWN0aW9uJztcbmltcG9ydCB7IGNyZWF0ZUFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYW5hbHlzZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hbmFseXNlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0xpc3RlbmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLWxpc3RlbmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Ob2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvUGFyYW1GYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tcGFyYW0tZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1wYXJhbS1yZW5kZXJlcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXdvcmtsZXQtbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2Jhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2JpcXVhZC1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNhY2hlVGVzdFJlc3VsdCB9IGZyb20gJy4vZmFjdG9yaWVzL2NhY2hlLXRlc3QtcmVzdWx0JztcbmltcG9ydCB7IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLW1lcmdlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1zcGxpdHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ29ubmVjdEF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25uZWN0LWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RNdWx0aXBsZU91dHB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25uZWN0LW11bHRpcGxlLW91dHB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2Nvbm5lY3RlZC1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25zdGFudC1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25zdGFudC1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnZlcnQtbnVtYmVyLXRvLXVuc2lnbmVkLWxvbmcnO1xuaW1wb3J0IHsgY3JlYXRlQ29udm9sdmVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29udm9sdmVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnZvbHZlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQ3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2NyZWF0ZS1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZURhdGFDbG9uZUVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGF0YS1jbG9uZS1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVEZWNvZGVBdWRpb0RhdGEgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWNvZGUtYXVkaW8tZGF0YSc7XG5pbXBvcnQgeyBjcmVhdGVEZWNyZW1lbnRDeWNsZUNvdW50ZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWNyZW1lbnQtY3ljbGUtY291bnRlcic7XG5pbXBvcnQgeyBjcmVhdGVEZWxheU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGF5LW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsYXktbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZURlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsZXRlLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlRGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxldGUtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlRGV0ZWN0Q3ljbGVzIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGV0ZWN0LWN5Y2xlcyc7XG5pbXBvcnQgeyBjcmVhdGVEaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGlzY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzJztcbmltcG9ydCB7IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2R5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlRW5jb2RpbmdFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2VuY29kaW5nLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUV2YWx1YXRlU291cmNlIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXZhbHVhdGUtc291cmNlJztcbmltcG9ydCB7IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9ldmVudC10YXJnZXQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlRXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUgfSBmcm9tICcuL2ZhY3Rvcmllcy9leHBvc2UtY3VycmVudC1mcmFtZS1hbmQtY3VycmVudC10aW1lJztcbmltcG9ydCB7IGNyZWF0ZUZldGNoU291cmNlIH0gZnJvbSAnLi9mYWN0b3JpZXMvZmV0Y2gtc291cmNlJztcbmltcG9ydCB7IGNyZWF0ZUdhaW5Ob2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9nYWluLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9nYWluLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVHZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWFjdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtaW5wdXRzJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvTm9kZVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtcmVuZGVyZXInO1xuaW1wb3J0IHsgY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlR2V0QXVkaW9QYXJhbVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWF1ZGlvLXBhcmFtLXJlbmRlcmVyJztcbmltcG9ydCB7IGNyZWF0ZUdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVHZXROYXRpdmVDb250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LW5hdGl2ZS1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1vci1jcmVhdGUtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVHZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGVzJztcbmltcG9ydCB7IGNyZWF0ZUlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvaWlyLWZpbHRlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2luY3JlbWVudC1jeWNsZS1jb3VudGVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlSW5kZXhTaXplRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbmRleC1zaXplLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2ludmFsaWQtYWNjZXNzLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaW52YWxpZC1zdGF0ZS1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJc0FueUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzQW55QXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtYW55LWF1ZGlvLXBhcmFtJztcbmltcG9ydCB7IGNyZWF0ZUlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLW5hdGl2ZS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUNvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLXNlY3VyZS1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzU3VwcG9ydGVkUHJvbWlzZSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLXN1cHBvcnRlZC1wcm9taXNlJztcbmltcG9ydCB7IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLXN0cmVhbS10cmFjay1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9taW5pbWFsLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21pbmltYWwtYmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9taW5pbWFsLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNb25pdG9yQ29ubmVjdGlvbnMgfSBmcm9tICcuL2ZhY3Rvcmllcy9tb25pdG9yLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYW5hbHlzZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8tZGVzdGluYXRpb24tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYXVkaW8td29ya2xldC1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1iaXF1YWQtZmlsdGVyLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNoYW5uZWwtbWVyZ2VyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNoYW5uZWwtc3BsaXR0ZXItbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNvbnN0YW50LXNvdXJjZS1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtY29udm9sdmVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVEZWxheU5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZGVsYXktbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVHYWluTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1nYWluLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1paXItZmlsdGVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtZWxlbWVudC1hdWRpby1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1vc2NpbGxhdG9yLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1wYW5uZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXBlcmlvZGljLXdhdmUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXNjcmlwdC1wcm9jZXNzb3Itbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXN0ZXJlby1wYW5uZXItbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbm90LXN1cHBvcnRlZC1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlT3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL29zY2lsbGF0b3Itbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL29zY2lsbGF0b3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZVBhbm5lck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3Bhbm5lci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZVBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvcGVyaW9kaWMtd2F2ZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVSZW5kZXJBdXRvbWF0aW9uIH0gZnJvbSAnLi9mYWN0b3JpZXMvcmVuZGVyLWF1dG9tYXRpb24nO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9yZW5kZXItaW5wdXRzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvcmVuZGVyLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlU2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL3NldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVTZXRBdWRpb05vZGVUYWlsVGltZSB9IGZyb20gJy4vZmFjdG9yaWVzL3NldC1hdWRpby1ub2RlLXRhaWwtdGltZSc7XG5pbXBvcnQgeyBjcmVhdGVTdGFydFJlbmRlcmluZyB9IGZyb20gJy4vZmFjdG9yaWVzL3N0YXJ0LXJlbmRlcmluZyc7XG5pbXBvcnQgeyBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGVyZW8tcGFubmVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL3N0ZXJlby1wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvbnN0cnVjdG9yLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzU3ViYXJyYXlTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtc3ViYXJyYXktc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Db250ZXh0Q2xvc2VNZXRob2RTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1jb250ZXh0LWNsb3NlLW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0NvbnRleHREZWNvZGVBdWRpb0RhdGFNZXRob2RUeXBlRXJyb3JTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1jb250ZXh0LWRlY29kZS1hdWRpby1kYXRhLW1ldGhvZC10eXBlLWVycm9yLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dE9wdGlvbnNTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1jb250ZXh0LW9wdGlvbnMtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Ob2RlQ29ubmVjdE1ldGhvZFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLW5vZGUtY29ubmVjdC1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yTm9PdXRwdXRzU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8td29ya2xldC1wcm9jZXNzb3Itbm8tb3V0cHV0cy1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXBvc3QtbWVzc2FnZS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDaGFubmVsTWVyZ2VyTm9kZUNoYW5uZWxDb3VudFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWNoYW5uZWwtbWVyZ2VyLW5vZGUtY2hhbm5lbC1jb3VudC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb25zdGFudFNvdXJjZU5vZGVBY2N1cmF0ZVNjaGVkdWxpbmdTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1jb25zdGFudC1zb3VyY2Utbm9kZS1hY2N1cmF0ZS1zY2hlZHVsaW5nLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVCdWZmZXJSZWFzc2lnbmFiaWxpdHlTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1jb252b2x2ZXItbm9kZS1idWZmZXItcmVhc3NpZ25hYmlsaXR5LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1jb252b2x2ZXItbm9kZS1jaGFubmVsLWNvdW50LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdElzU2VjdXJlQ29udGV4dFN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWlzLXNlY3VyZS1jb250ZXh0LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlTWVkaWFTdHJlYW1XaXRob3V0QXVkaW9UcmFja1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LW1lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1tZWRpYS1zdHJlYW0td2l0aG91dC1hdWRpby10cmFjay1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY3VycmVudC10aW1lLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdFN0ZXJlb1Bhbm5lck5vZGVEZWZhdWx0VmFsdWVTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1zdGVyZW8tcGFubmVyLW5vZGUtZGVmYXVsdC12YWx1ZS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVVua25vd25FcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL3Vua25vd24tZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3dhdmUtc2hhcGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlV2luZG93IH0gZnJvbSAnLi9mYWN0b3JpZXMvd2luZG93JztcbmltcG9ydCB7IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzJztcbmltcG9ydCB7IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvd3JhcC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlciB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXInO1xuaW1wb3J0IHsgY3JlYXRlV3JhcENoYW5uZWxNZXJnZXJOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvd3JhcC1jaGFubmVsLW1lcmdlci1ub2RlJztcbmltcG9ydCB7IEFVRElPX05PREVfQ09OTkVDVElPTlNfU1RPUkUsIEFVRElPX05PREVfU1RPUkUsIEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFLCBBVURJT19QQVJBTV9TVE9SRSwgQ09OVEVYVF9TVE9SRSwgQ1lDTEVfQ09VTlRFUlMgfSBmcm9tICcuL2dsb2JhbHMnO1xuaW1wb3J0IHsgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvZGlzY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS1mcm9tLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyB9IGZyb20gJy4vaGVscGVycy9nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0Rmlyc3RTYW1wbGUgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWZpcnN0LXNhbXBsZSc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldE5hdGl2ZUF1ZGlvUGFyYW0gfSBmcm9tICcuL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vaGVscGVycy9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuL2hlbHBlcnMvaW5zZXJ0LWVsZW1lbnQtaW4tc2V0JztcbmltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGlzRENDdXJ2ZSB9IGZyb20gJy4vaGVscGVycy9pcy1kYy1jdXJ2ZSc7XG5pbXBvcnQgeyBpc1BhcnRPZkFDeWNsZSB9IGZyb20gJy4vaGVscGVycy9pcy1wYXJ0LW9mLWEtY3ljbGUnO1xuaW1wb3J0IHsgaXNQYXNzaXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2lzLXBhc3NpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBvdmVyd3JpdGVBY2Nlc3NvcnMgfSBmcm9tICcuL2hlbHBlcnMvb3ZlcndyaXRlLWFjY2Vzc29ycyc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL2hlbHBlcnMvcGljay1lbGVtZW50LWZyb20tc2V0JztcbmltcG9ydCB7IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvc2FuaXRpemUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLWNoYW5uZWwtc3BsaXR0ZXItb3B0aW9ucyc7XG5pbXBvcnQgeyBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvc2FuaXRpemUtcGVyaW9kaWMtd2F2ZS1vcHRpb25zJztcbmltcG9ydCB7IHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSB9IGZyb20gJy4vaGVscGVycy9zZXQtdmFsdWUtYXQtdGltZS11bnRpbC1wb3NzaWJsZSc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItY29weS1jaGFubmVsLW1ldGhvZHMtb3V0LW9mLWJvdW5kcy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXItc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1jb25zZWN1dGl2ZS1jYWxscy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHkgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy1jbG9uYWJpbGl0eSc7XG5pbXBvcnQgeyB0ZXN0RG9tRXhjZXB0aW9uQ29uc3RydWN0b3JTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtZG9tLWV4Y2VwdGlvbi1jb25zdHJ1Y3Rvci1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0VHJhbnNmZXJhYmxlc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC10cmFuc2ZlcmFibGVzLXN1cHBvcnQnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmcgfSBmcm9tICcuL2hlbHBlcnMvd3JhcC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMgfSBmcm9tICcuL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMnO1xuaW1wb3J0IHsgd3JhcEV2ZW50TGlzdGVuZXIgfSBmcm9tICcuL2hlbHBlcnMvd3JhcC1ldmVudC1saXN0ZW5lcic7XG4vKlxuICogQHRvZG8gRXhwbGljaXRseSByZWZlcmVuY2luZyB0aGUgYmFycmVsIGZpbGUgc2VlbXMgdG8gYmUgbmVjZXNzYXJ5IHdoZW4gZW5hYmxpbmcgdGhlXG4gKiBpc29sYXRlZE1vZHVsZXMgY29tcGlsZXIgb3B0aW9uLlxuICovXG5leHBvcnQgKiBmcm9tICcuL2ludGVyZmFjZXMvaW5kZXgnO1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcy9pbmRleCc7XG5jb25zdCBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGNyZWF0ZUFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGluc2VydEVsZW1lbnRJblNldCk7XG5jb25zdCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBjcmVhdGVBZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoaW5zZXJ0RWxlbWVudEluU2V0KTtcbmNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gY3JlYXRlRGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUocGlja0VsZW1lbnRGcm9tU2V0KTtcbmNvbnN0IGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgZ2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSBjcmVhdGVHZXRBdWRpb05vZGVUYWlsVGltZShhdWRpb05vZGVUYWlsVGltZVN0b3JlKTtcbmNvbnN0IGNhY2hlVGVzdFJlc3VsdCA9IGNyZWF0ZUNhY2hlVGVzdFJlc3VsdChuZXcgTWFwKCksIG5ldyBXZWFrTWFwKCkpO1xuY29uc3Qgd2luZG93ID0gY3JlYXRlV2luZG93KCk7XG5jb25zdCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUgPSBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5KGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIgPSBjcmVhdGVHZXRBdWRpb05vZGVSZW5kZXJlcihnZXRBdWRpb05vZGVDb25uZWN0aW9ucyk7XG5jb25zdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSA9IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9Ob2RlKGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRBdWRpb05vZGVSZW5kZXJlciwgaXNQYXJ0T2ZBQ3ljbGUpO1xuY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGdldE5hdGl2ZUNvbnRleHQgPSBjcmVhdGVHZXROYXRpdmVDb250ZXh0KENPTlRFWFRfU1RPUkUpO1xuY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKHdpbmRvdyk7XG5jb25zdCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmNvbnN0IGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSA9IG5ldyBXZWFrTWFwKCk7XG5jb25zdCBldmVudFRhcmdldENvbnN0cnVjdG9yID0gY3JlYXRlRXZlbnRUYXJnZXRDb25zdHJ1Y3Rvcih3cmFwRXZlbnRMaXN0ZW5lcik7XG5jb25zdCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKHdpbmRvdyk7XG5jb25zdCBpc05hdGl2ZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmNvbnN0IGlzTmF0aXZlQXVkaW9Ob2RlID0gY3JlYXRlSXNOYXRpdmVBdWRpb05vZGUod2luZG93KTtcbmNvbnN0IGlzTmF0aXZlQXVkaW9QYXJhbSA9IGNyZWF0ZUlzTmF0aXZlQXVkaW9QYXJhbSh3aW5kb3cpO1xuY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKHdpbmRvdyk7XG5jb25zdCBhdWRpb05vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yKGNyZWF0ZUFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zKEFVRElPX05PREVfQ09OTkVDVElPTlNfU1RPUkUpLCBjcmVhdGVBZGRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRBdWRpb05vZGVUYWlsVGltZSwgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBpbnNlcnRFbGVtZW50SW5TZXQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc1BhcnRPZkFDeWNsZSwgaXNQYXNzaXZlQXVkaW9Ob2RlKSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbmNyZW1lbnRDeWNsZUNvdW50ZXJGYWN0b3J5KENZQ0xFX0NPVU5URVJTLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgaXNBY3RpdmVBdWRpb05vZGUpLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlRGVjcmVtZW50Q3ljbGVDb3VudGVyKGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgQ1lDTEVfQ09VTlRFUlMsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGdldE5hdGl2ZUNvbnRleHQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpLCBjcmVhdGVEZXRlY3RDeWNsZXMoYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0VmFsdWVGb3JLZXkpLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVBdWRpb05vZGUsIGlzTmF0aXZlQXVkaW9QYXJhbSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpO1xuY29uc3QgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBbmFseXNlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgeyBhbmFseXNlck5vZGVDb25zdHJ1Y3RvciBhcyBBbmFseXNlck5vZGUgfTtcbmNvbnN0IGF1ZGlvQnVmZmVyU3RvcmUgPSBuZXcgV2Vha1NldCgpO1xuY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3Iod2luZG93KTtcbmNvbnN0IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyA9IGNyZWF0ZUNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhuZXcgVWludDMyQXJyYXkoMSkpO1xuY29uc3Qgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzID0gY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZywgY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3Qgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMgPSBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyhjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcpO1xuY29uc3QgYXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQobmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciksIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpO1xuZXhwb3J0IHsgYXVkaW9CdWZmZXJDb25zdHJ1Y3RvciBhcyBBdWRpb0J1ZmZlciB9O1xuY29uc3QgYWRkU2lsZW50Q29ubmVjdGlvbiA9IGNyZWF0ZUFkZFNpbGVudENvbm5lY3Rpb24oY3JlYXRlTmF0aXZlR2Fpbk5vZGUpO1xuY29uc3QgcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtID0gY3JlYXRlUmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKGdldEF1ZGlvTm9kZVJlbmRlcmVyLCBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMsIGlzUGFydE9mQUN5Y2xlKTtcbmNvbnN0IGNvbm5lY3RBdWRpb1BhcmFtID0gY3JlYXRlQ29ubmVjdEF1ZGlvUGFyYW0ocmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlclN1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmcsIGNyZWF0ZVdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyKG92ZXJ3cml0ZUFjY2Vzc29ycyksIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyk7XG5jb25zdCByZW5kZXJBdXRvbWF0aW9uID0gY3JlYXRlUmVuZGVyQXV0b21hdGlvbihjcmVhdGVHZXRBdWRpb1BhcmFtUmVuZGVyZXIoZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKSwgcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyID0gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY3JlYXRlQXVkaW9QYXJhbSA9IGNyZWF0ZUF1ZGlvUGFyYW1GYWN0b3J5KGNyZWF0ZUFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSksIGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgQVVESU9fUEFSQU1fU1RPUkUsIGNyZWF0ZUF1ZGlvUGFyYW1SZW5kZXJlciwgY3JlYXRlQ2FuY2VsQW5kSG9sZEF1dG9tYXRpb25FdmVudCwgY3JlYXRlQ2FuY2VsU2NoZWR1bGVkVmFsdWVzQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVFeHBvbmVudGlhbFJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVMaW5lYXJSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VGFyZ2V0QXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVDdXJ2ZUF1dG9tYXRpb25FdmVudCwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSk7XG5jb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcik7XG5leHBvcnQgeyBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgfTtcbmNvbnN0IGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlRmFjdG9yeShjcmVhdGVOYXRpdmVHYWluTm9kZSwgb3ZlcndyaXRlQWNjZXNzb3JzKSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IHNldEF1ZGlvTm9kZVRhaWxUaW1lID0gY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSk7XG5jb25zdCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IG1vbml0b3JDb25uZWN0aW9ucyA9IGNyZWF0ZU1vbml0b3JDb25uZWN0aW9ucyhpbnNlcnRFbGVtZW50SW5TZXQsIGlzTmF0aXZlQXVkaW9Ob2RlKTtcbmNvbnN0IHdyYXBDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZShjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGVGYWN0b3J5KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUpO1xuY29uc3QgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlckZhY3RvcnkoYWRkU2lsZW50Q29ubmVjdGlvbiwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZhY3RvcnkoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KTtcbmNvbnN0IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyID0gY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcik7XG5jb25zdCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZUZhY3RvcnkoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG92ZXJ3cml0ZUFjY2Vzc29ycyk7XG5jb25zdCBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY29udm9sdmVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ29udm9sdmVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIgPSBjcmVhdGVEZWxheU5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBkZWxheU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZURlbGF5Tm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEZWxheU5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRGVsYXlOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlRmFjdG9yeShjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcik7XG5jb25zdCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIgPSBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVHYWluTm9kZVJlbmRlcmVyID0gY3JlYXRlR2Fpbk5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGdhaW5Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVHYWluTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZVJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlVGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikpO1xuY29uc3QgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyKTtcbmNvbnN0IGlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZSwgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvTGlzdGVuZXIgPSBjcmVhdGVBdWRpb0xpc3RlbmVyRmFjdG9yeShjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0Rmlyc3RTYW1wbGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3ZlcndyaXRlQWNjZXNzb3JzKTtcbmNvbnN0IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9MaXN0ZW5lciwgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlLCB3cmFwRXZlbnRMaXN0ZW5lcik7XG5jb25zdCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlRmFjdG9yeShhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzKTtcbmNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIgPSBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3Qgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHdyYXBFdmVudExpc3RlbmVyKTtcbmNvbnN0IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyRmFjdG9yeShjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZha2VyRmFjdG9yeShjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEZpcnN0U2FtcGxlLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlcik7XG5jb25zdCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IHBhbm5lck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZVBhbm5lck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZSA9IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZUZhY3RvcnkoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgPSBjcmVhdGVQZXJpb2RpY1dhdmVDb25zdHJ1Y3RvcihjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUsIGdldE5hdGl2ZUNvbnRleHQsIG5ldyBXZWFrU2V0KCksIHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyk7XG5jb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5ID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeShjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFjdG9yeShuYXRpdmVTdGVyZW9QYW5uZXJOb2RlRmFrZXJGYWN0b3J5LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcik7XG5jb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlciA9IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IHdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVXYXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUsIGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgaXNTZWN1cmVDb250ZXh0ID0gY3JlYXRlSXNTZWN1cmVDb250ZXh0KHdpbmRvdyk7XG5jb25zdCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSA9IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lKHdpbmRvdyk7XG5jb25zdCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlR2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbi8vIFRoZSBhZGRBdWRpb1dvcmtsZXRNb2R1bGUoKSBmdW5jdGlvbiBpcyBvbmx5IGF2YWlsYWJsZSBpbiBhIFNlY3VyZUNvbnRleHQuXG5leHBvcnQgY29uc3QgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlID0gaXNTZWN1cmVDb250ZXh0XG4gICAgPyBjcmVhdGVBZGRBdWRpb1dvcmtsZXRNb2R1bGUoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlRXZhbHVhdGVTb3VyY2Uod2luZG93KSwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGNyZWF0ZUZldGNoU291cmNlKGNyZWF0ZUFib3J0RXJyb3IpLCBnZXROYXRpdmVDb250ZXh0LCBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuZXcgV2Vha01hcCgpLCBuZXcgV2Vha01hcCgpLCBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgXG4gICAgLy8gQHRvZG8gd2luZG93IGlzIGd1YXJhbnRlZWQgdG8gYmUgZGVmaW5lZCBiZWNhdXNlIGlzU2VjdXJlQ29udGV4dCBjaGVja3MgdGhhdCBhcyB3ZWxsLlxuICAgIHdpbmRvdylcbiAgICA6IHVuZGVmaW5lZDtcbmNvbnN0IGlzTmF0aXZlQ29udGV4dCA9IGNyZWF0ZUlzTmF0aXZlQ29udGV4dChpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmV4cG9ydCBjb25zdCBkZWNvZGVBdWRpb0RhdGEgPSBjcmVhdGVEZWNvZGVBdWRpb0RhdGEoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVEYXRhQ2xvbmVFcnJvciwgY3JlYXRlRW5jb2RpbmdFcnJvciwgbmV3IFdlYWtTZXQoKSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVDb250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHRlc3RQcm9taXNlU3VwcG9ydCwgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyk7XG5jb25zdCBiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoYWRkQXVkaW9Xb3JrbGV0TW9kdWxlLCBhbmFseXNlck5vZGVDb25zdHJ1Y3RvciwgYXVkaW9CdWZmZXJDb25zdHJ1Y3RvciwgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciwgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciwgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yLCBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciwgY29udm9sdmVyTm9kZUNvbnN0cnVjdG9yLCBkZWNvZGVBdWRpb0RhdGEsIGRlbGF5Tm9kZUNvbnN0cnVjdG9yLCBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IsIGdhaW5Ob2RlQ29uc3RydWN0b3IsIGlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3RvciwgcGFubmVyTm9kZUNvbnN0cnVjdG9yLCBwZXJpb2RpY1dhdmVDb25zdHJ1Y3Rvciwgc3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yLCB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yKTtcbmNvbnN0IG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlRmFjdG9yeShjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCk7XG5jb25zdCBhdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpO1xuZXhwb3J0IHsgYXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgQXVkaW9Db250ZXh0IH07XG5jb25zdCBnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMgPSBjcmVhdGVHZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXModW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSk7XG5jb25zdCBhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSA9IGNyZWF0ZUFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2Rlcyk7XG5jb25zdCBjb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gY3JlYXRlQ29ubmVjdE11bHRpcGxlT3V0cHV0cyhjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCBkZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSA9IGNyZWF0ZURlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2Rlcyk7XG5jb25zdCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gY3JlYXRlRGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyhjcmVhdGVJbmRleFNpemVFcnJvcik7XG5jb25zdCBhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgZ2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IGNyZWF0ZUdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlLCBnZXRWYWx1ZUZvcktleSk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5KGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeShjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIgPSBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBkZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGdldEJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVHZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZSk7XG5jb25zdCBzZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gY3JlYXRlU2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyhhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUpO1xuLy8gVGhlIEF1ZGlvV29ya2xldE5vZGUgY29uc3RydWN0b3IgaXMgb25seSBhdmFpbGFibGUgaW4gYSBTZWN1cmVDb250ZXh0LlxuY29uc3QgYXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yID0gaXNTZWN1cmVDb250ZXh0XG4gICAgPyBjcmVhdGVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IoYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvciwgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucywgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHksIHdyYXBFdmVudExpc3RlbmVyKVxuICAgIDogdW5kZWZpbmVkO1xuZXhwb3J0IHsgYXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIGFzIEF1ZGlvV29ya2xldE5vZGUgfTtcbmV4cG9ydCB7IGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3RvciBhcyBCaXF1YWRGaWx0ZXJOb2RlIH07XG5leHBvcnQgeyBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yIGFzIENoYW5uZWxNZXJnZXJOb2RlIH07XG5leHBvcnQgeyBjaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgYXMgQ2hhbm5lbFNwbGl0dGVyTm9kZSB9O1xuZXhwb3J0IHsgY29udm9sdmVyTm9kZUNvbnN0cnVjdG9yIGFzIENvbnZvbHZlck5vZGUgfTtcbmV4cG9ydCB7IGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIENvbnN0YW50U291cmNlTm9kZSB9O1xuZXhwb3J0IHsgZGVsYXlOb2RlQ29uc3RydWN0b3IgYXMgRGVsYXlOb2RlIH07XG5leHBvcnQgeyBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgYXMgRHluYW1pY3NDb21wcmVzc29yTm9kZSB9O1xuZXhwb3J0IHsgZ2Fpbk5vZGVDb25zdHJ1Y3RvciBhcyBHYWluTm9kZSB9O1xuZXhwb3J0IHsgaUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yIGFzIElJUkZpbHRlck5vZGUgfTtcbmV4cG9ydCB7IG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSB9O1xuZXhwb3J0IHsgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgfTtcbmV4cG9ydCB7IG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlIH07XG5jb25zdCBtaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmV4cG9ydCB7IG1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBNaW5pbWFsQXVkaW9Db250ZXh0IH07XG5jb25zdCBjcmVhdGVOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlQ3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmNvbnN0IHN0YXJ0UmVuZGVyaW5nID0gY3JlYXRlU3RhcnRSZW5kZXJpbmcoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpO1xuY29uc3QgbWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc3RhcnRSZW5kZXJpbmcpO1xuZXhwb3J0IHsgbWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dCB9O1xuY29uc3Qgb2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc3RhcnRSZW5kZXJpbmcpO1xuZXhwb3J0IHsgb2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIE9mZmxpbmVBdWRpb0NvbnRleHQgfTtcbmV4cG9ydCB7IG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgYXMgT3NjaWxsYXRvck5vZGUgfTtcbmV4cG9ydCB7IHBhbm5lck5vZGVDb25zdHJ1Y3RvciBhcyBQYW5uZXJOb2RlIH07XG5leHBvcnQgeyBwZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciBhcyBQZXJpb2RpY1dhdmUgfTtcbmV4cG9ydCB7IHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3RvciBhcyBTdGVyZW9QYW5uZXJOb2RlIH07XG5leHBvcnQgeyB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yIGFzIFdhdmVTaGFwZXJOb2RlIH07XG5leHBvcnQgY29uc3QgaXNBbnlBdWRpb0NvbnRleHQgPSBjcmVhdGVJc0FueUF1ZGlvQ29udGV4dChDT05URVhUX1NUT1JFLCBpc05hdGl2ZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgY29uc3QgaXNBbnlBdWRpb05vZGUgPSBjcmVhdGVJc0FueUF1ZGlvTm9kZShBVURJT19OT0RFX1NUT1JFLCBpc05hdGl2ZUF1ZGlvTm9kZSk7XG5leHBvcnQgY29uc3QgaXNBbnlBdWRpb1BhcmFtID0gY3JlYXRlSXNBbnlBdWRpb1BhcmFtKEFVRElPX1BBUkFNX1NUT1JFLCBpc05hdGl2ZUF1ZGlvUGFyYW0pO1xuZXhwb3J0IGNvbnN0IGlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dChDT05URVhUX1NUT1JFLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IGlzU3VwcG9ydGVkID0gKCkgPT4gY3JlYXRlSXNTdXBwb3J0ZWRQcm9taXNlKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzU3ViYXJyYXlTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRDbG9zZU1ldGhvZFN1cHBvcnQobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Db250ZXh0RGVjb2RlQXVkaW9EYXRhTWV0aG9kVHlwZUVycm9yU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Db250ZXh0T3B0aW9uc1N1cHBvcnQobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Ob2RlQ29ubmVjdE1ldGhvZFN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3Nvck5vT3V0cHV0c1N1cHBvcnQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q2hhbm5lbE1lcmdlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RDb25zdGFudFNvdXJjZU5vZGVBY2N1cmF0ZVNjaGVkdWxpbmdTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQnVmZmVyUmVhc3NpZ25hYmlsaXR5U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUNoYW5uZWxDb3VudFN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgdGVzdERvbUV4Y2VwdGlvbkNvbnN0cnVjdG9yU3VwcG9ydCwgY3JlYXRlVGVzdElzU2VjdXJlQ29udGV4dFN1cHBvcnQod2luZG93KSwgY3JlYXRlVGVzdE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlTWVkaWFTdHJlYW1XaXRob3V0QXVkaW9UcmFja1N1cHBvcnQobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0U3RlcmVvUGFubmVyTm9kZURlZmF1bHRWYWx1ZVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgdGVzdFRyYW5zZmVyYWJsZXNTdXBwb3J0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vZHVsZS5qcy5tYXAiLCIvKipcbiAqIEFzc2VydCB0aGF0IHRoZSBzdGF0ZW1lbnQgaXMgdHJ1ZSwgb3RoZXJ3aXNlIGludm9rZSB0aGUgZXJyb3IuXG4gKiBAcGFyYW0gc3RhdGVtZW50XG4gKiBAcGFyYW0gZXJyb3IgVGhlIG1lc3NhZ2Ugd2hpY2ggaXMgcGFzc2VkIGludG8gYW4gRXJyb3JcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydChzdGF0ZW1lbnQsIGVycm9yKSB7XG4gICAgaWYgKCFzdGF0ZW1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBnaXZlbiB2YWx1ZSBpcyB3aXRoaW4gdGhlIHJhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRSYW5nZSh2YWx1ZSwgZ3RlLCBsdGUgPSBJbmZpbml0eSkge1xuICAgIGlmICghKGd0ZSA8PSB2YWx1ZSAmJiB2YWx1ZSA8PSBsdGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBWYWx1ZSBtdXN0IGJlIHdpdGhpbiBbJHtndGV9LCAke2x0ZX1dLCBnb3Q6ICR7dmFsdWV9YCk7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgaXMgd2l0aGluIHRoZSByYW5nZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0Q29udGV4dFJ1bm5pbmcoY29udGV4dCkge1xuICAgIC8vIGFkZCBhIHdhcm5pbmcgaWYgdGhlIGNvbnRleHQgaXMgbm90IHN0YXJ0ZWRcbiAgICBpZiAoIWNvbnRleHQuaXNPZmZsaW5lICYmIGNvbnRleHQuc3RhdGUgIT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIHdhcm4oXCJUaGUgQXVkaW9Db250ZXh0IGlzIFxcXCJzdXNwZW5kZWRcXFwiLiBJbnZva2UgVG9uZS5zdGFydCgpIGZyb20gYSB1c2VyIGFjdGlvbiB0byBzdGFydCB0aGUgYXVkaW8uXCIpO1xuICAgIH1cbn1cbi8qKlxuICogVGhlIGRlZmF1bHQgbG9nZ2VyIGlzIHRoZSBjb25zb2xlXG4gKi9cbmxldCBkZWZhdWx0TG9nZ2VyID0gY29uc29sZTtcbi8qKlxuICogU2V0IHRoZSBsb2dnaW5nIGludGVyZmFjZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TG9nZ2VyKGxvZ2dlcikge1xuICAgIGRlZmF1bHRMb2dnZXIgPSBsb2dnZXI7XG59XG4vKipcbiAqIExvZyBhbnl0aGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gbG9nKC4uLmFyZ3MpIHtcbiAgICBkZWZhdWx0TG9nZ2VyLmxvZyguLi5hcmdzKTtcbn1cbi8qKlxuICogV2FybiBhbnl0aGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gd2FybiguLi5hcmdzKSB7XG4gICAgZGVmYXVsdExvZ2dlci53YXJuKC4uLmFyZ3MpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVidWcuanMubWFwIiwiLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgdW5kZWZpbmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1VuZGVmKGFyZykge1xuICAgIHJldHVybiB0eXBlb2YgYXJnID09PSBcInVuZGVmaW5lZFwiO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgbm90IHVuZGVmaW5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEZWZpbmVkKGFyZykge1xuICAgIHJldHVybiAhaXNVbmRlZihhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgYSBmdW5jdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNGdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJmdW5jdGlvblwiO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhIG51bWJlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTnVtYmVyKGFyZykge1xuICAgIHJldHVybiAodHlwZW9mIGFyZyA9PT0gXCJudW1iZXJcIik7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGdpdmVuIGFyZ3VtZW50IGlzIGFuIG9iamVjdCBsaXRlcmFsIChpLmUuIGB7fWApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gICAgcmV0dXJuIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJnKSA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIiAmJiBhcmcuY29uc3RydWN0b3IgPT09IE9iamVjdCk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGEgYm9vbGVhbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwiYm9vbGVhblwiKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYW4gQXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXJyYXkoYXJnKSB7XG4gICAgcmV0dXJuIChBcnJheS5pc0FycmF5KGFyZykpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKGFyZykge1xuICAgIHJldHVybiAodHlwZW9mIGFyZyA9PT0gXCJzdHJpbmdcIik7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGluIHRoZSBmb3JtIG9mIGEgbm90ZSBpbiBzY2llbnRpZmljIHBpdGNoIG5vdGF0aW9uLlxuICogZS5nLiBcIkM0XCJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTm90ZShhcmcpIHtcbiAgICByZXR1cm4gaXNTdHJpbmcoYXJnKSAmJiAvXihbYS1nXXsxfSg/OmJ8I3x4fGJiKT8pKC0/WzAtOV0rKS9pLnRlc3QoYXJnKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVR5cGVDaGVjay5qcy5tYXAiLCJpbXBvcnQgeyBBdWRpb0NvbnRleHQgYXMgc3RkQXVkaW9Db250ZXh0LCBBdWRpb1dvcmtsZXROb2RlIGFzIHN0ZEF1ZGlvV29ya2xldE5vZGUsIE9mZmxpbmVBdWRpb0NvbnRleHQgYXMgc3RkT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gXCJzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBDcmVhdGUgYSBuZXcgQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBdWRpb0NvbnRleHQob3B0aW9ucykge1xuICAgIHJldHVybiBuZXcgc3RkQXVkaW9Db250ZXh0KG9wdGlvbnMpO1xufVxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dChjaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSB7XG4gICAgcmV0dXJuIG5ldyBzdGRPZmZsaW5lQXVkaW9Db250ZXh0KGNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xufVxuLyoqXG4gKiBBIHJlZmVyZW5jZSB0byB0aGUgd2luZG93IG9iamVjdFxuICogQGhpZGRlblxuICovXG5leHBvcnQgY29uc3QgdGhlV2luZG93ID0gdHlwZW9mIHNlbGYgPT09IFwib2JqZWN0XCIgPyBzZWxmIDogbnVsbDtcbi8qKlxuICogSWYgdGhlIGJyb3dzZXIgaGFzIGEgd2luZG93IG9iamVjdCB3aGljaCBoYXMgYW4gQXVkaW9Db250ZXh0XG4gKiBAaGlkZGVuXG4gKi9cbmV4cG9ydCBjb25zdCBoYXNBdWRpb0NvbnRleHQgPSB0aGVXaW5kb3cgJiZcbiAgICAodGhlV2luZG93Lmhhc093blByb3BlcnR5KFwiQXVkaW9Db250ZXh0XCIpIHx8IHRoZVdpbmRvdy5oYXNPd25Qcm9wZXJ0eShcIndlYmtpdEF1ZGlvQ29udGV4dFwiKSk7XG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZShjb250ZXh0LCBuYW1lLCBvcHRpb25zKSB7XG4gICAgYXNzZXJ0KGlzRGVmaW5lZChzdGRBdWRpb1dvcmtsZXROb2RlKSwgXCJUaGlzIG5vZGUgb25seSB3b3JrcyBpbiBhIHNlY3VyZSBjb250ZXh0IChodHRwcyBvciBsb2NhbGhvc3QpXCIpO1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gbmV3IHN0ZEF1ZGlvV29ya2xldE5vZGUoY29udGV4dCwgbmFtZSwgb3B0aW9ucyk7XG59XG4vKipcbiAqIFRoaXMgcHJvbWlzZSByZXNvbHZlcyB0byBhIGJvb2xlYW4gd2hpY2ggaW5kaWNhdGVzIGlmIHRoZVxuICogZnVuY3Rpb25hbGl0eSBpcyBzdXBwb3J0ZWQgd2l0aGluIHRoZSBjdXJyZW50bHkgdXNlZCBicm93c2UuXG4gKiBUYWtlbiBmcm9tIFtzdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dF0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0I2lzc3VwcG9ydGVkKVxuICovXG5leHBvcnQgeyBpc1N1cHBvcnRlZCBhcyBzdXBwb3J0ZWQgfSBmcm9tIFwic3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1ZGlvQ29udGV4dC5qcy5tYXAiLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy5wdXNoKF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoZyAmJiAoZyA9IDAsIG9wWzBdICYmIChfID0gMCkpLCBfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIHZhciBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihtLCBrKTtcclxuICAgIGlmICghZGVzYyB8fCAoXCJnZXRcIiBpbiBkZXNjID8gIW0uX19lc01vZHVsZSA6IGRlc2Mud3JpdGFibGUgfHwgZGVzYy5jb25maWd1cmFibGUpKSB7XHJcbiAgICAgICAgZGVzYyA9IHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgZGVzYyk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG4vKiogQGRlcHJlY2F0ZWQgKi9cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXlzKCkge1xyXG4gICAgZm9yICh2YXIgcyA9IDAsIGkgPSAwLCBpbCA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBpbDsgaSsrKSBzICs9IGFyZ3VtZW50c1tpXS5sZW5ndGg7XHJcbiAgICBmb3IgKHZhciByID0gQXJyYXkocyksIGsgPSAwLCBpID0gMDsgaSA8IGlsOyBpKyspXHJcbiAgICAgICAgZm9yICh2YXIgYSA9IGFyZ3VtZW50c1tpXSwgaiA9IDAsIGpsID0gYS5sZW5ndGg7IGogPCBqbDsgaisrLCBrKyspXHJcbiAgICAgICAgICAgIHJba10gPSBhW2pdO1xyXG4gICAgcmV0dXJuIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5KHRvLCBmcm9tLCBwYWNrKSB7XHJcbiAgICBpZiAocGFjayB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSBmb3IgKHZhciBpID0gMCwgbCA9IGZyb20ubGVuZ3RoLCBhcjsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgIGlmIChhciB8fCAhKGkgaW4gZnJvbSkpIHtcclxuICAgICAgICAgICAgaWYgKCFhcikgYXIgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tLCAwLCBpKTtcclxuICAgICAgICAgICAgYXJbaV0gPSBmcm9tW2ldO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0by5jb25jYXQoYXIgfHwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSkpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEluKHN0YXRlLCByZWNlaXZlcikge1xyXG4gICAgaWYgKHJlY2VpdmVyID09PSBudWxsIHx8ICh0eXBlb2YgcmVjZWl2ZXIgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlY2VpdmVyICE9PSBcImZ1bmN0aW9uXCIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHVzZSAnaW4nIG9wZXJhdG9yIG9uIG5vbi1vYmplY3RcIik7XHJcbiAgICByZXR1cm4gdHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciA9PT0gc3RhdGUgOiBzdGF0ZS5oYXMocmVjZWl2ZXIpO1xyXG59XHJcbiIsIi8qKlxuICogQSBjbGFzcyB3aGljaCBwcm92aWRlcyBhIHJlbGlhYmxlIGNhbGxiYWNrIHVzaW5nIGVpdGhlclxuICogYSBXZWIgV29ya2VyLCBvciBpZiB0aGF0IGlzbid0IHN1cHBvcnRlZCwgZmFsbHMgYmFjayB0byBzZXRUaW1lb3V0LlxuICovXG5leHBvcnQgY2xhc3MgVGlja2VyIHtcbiAgICBjb25zdHJ1Y3RvcihjYWxsYmFjaywgdHlwZSwgdXBkYXRlSW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fY2FsbGJhY2sgPSBjYWxsYmFjaztcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUludGVydmFsID0gdXBkYXRlSW50ZXJ2YWw7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgY2xvY2sgc291cmNlIGZvciB0aGUgZmlyc3QgdGltZVxuICAgICAgICB0aGlzLl9jcmVhdGVDbG9jaygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHdlYiB3b3JrZXJcbiAgICAgKi9cbiAgICBfY3JlYXRlV29ya2VyKCkge1xuICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW1xuICAgICAgICAgICAgLyogamF2YXNjcmlwdCAqLyBgXG5cdFx0XHQvLyB0aGUgaW5pdGlhbCB0aW1lb3V0IHRpbWVcblx0XHRcdGxldCB0aW1lb3V0VGltZSA9ICAkeyh0aGlzLl91cGRhdGVJbnRlcnZhbCAqIDEwMDApLnRvRml4ZWQoMSl9O1xuXHRcdFx0Ly8gb25tZXNzYWdlIGNhbGxiYWNrXG5cdFx0XHRzZWxmLm9ubWVzc2FnZSA9IGZ1bmN0aW9uKG1zZyl7XG5cdFx0XHRcdHRpbWVvdXRUaW1lID0gcGFyc2VJbnQobXNnLmRhdGEpO1xuXHRcdFx0fTtcblx0XHRcdC8vIHRoZSB0aWNrIGZ1bmN0aW9uIHdoaWNoIHBvc3RzIGEgbWVzc2FnZVxuXHRcdFx0Ly8gYW5kIHNjaGVkdWxlcyBhIG5ldyB0aWNrXG5cdFx0XHRmdW5jdGlvbiB0aWNrKCl7XG5cdFx0XHRcdHNldFRpbWVvdXQodGljaywgdGltZW91dFRpbWUpO1xuXHRcdFx0XHRzZWxmLnBvc3RNZXNzYWdlKCd0aWNrJyk7XG5cdFx0XHR9XG5cdFx0XHQvLyBjYWxsIHRpY2sgaW5pdGlhbGx5XG5cdFx0XHR0aWNrKCk7XG5cdFx0XHRgXG4gICAgICAgIF0sIHsgdHlwZTogXCJ0ZXh0L2phdmFzY3JpcHRcIiB9KTtcbiAgICAgICAgY29uc3QgYmxvYlVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0IHdvcmtlciA9IG5ldyBXb3JrZXIoYmxvYlVybCk7XG4gICAgICAgIHdvcmtlci5vbm1lc3NhZ2UgPSB0aGlzLl9jYWxsYmFjay5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLl93b3JrZXIgPSB3b3JrZXI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIHRpbWVvdXQgbG9vcFxuICAgICAqL1xuICAgIF9jcmVhdGVUaW1lb3V0KCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVUaW1lb3V0KCk7XG4gICAgICAgICAgICB0aGlzLl9jYWxsYmFjaygpO1xuICAgICAgICB9LCB0aGlzLl91cGRhdGVJbnRlcnZhbCAqIDEwMDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgdGhlIGNsb2NrIHNvdXJjZS5cbiAgICAgKi9cbiAgICBfY3JlYXRlQ2xvY2soKSB7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcIndvcmtlclwiKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVdvcmtlcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyB3b3JrZXJzIG5vdCBzdXBwb3J0ZWQsIGZhbGxiYWNrIHRvIHRpbWVvdXRcbiAgICAgICAgICAgICAgICB0aGlzLl90eXBlID0gXCJ0aW1lb3V0XCI7XG4gICAgICAgICAgICAgICAgdGhpcy5fY3JlYXRlQ2xvY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl90eXBlID09PSBcInRpbWVvdXRcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVGltZW91dCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwIHRoZSBjdXJyZW50IGNsb2NrIHNvdXJjZVxuICAgICAqL1xuICAgIF9kaXNwb3NlQ2xvY2soKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lb3V0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fd29ya2VyKSB7XG4gICAgICAgICAgICB0aGlzLl93b3JrZXIudGVybWluYXRlKCk7XG4gICAgICAgICAgICB0aGlzLl93b3JrZXIub25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcmF0ZSBpbiBzZWNvbmRzIHRoZSB0aWNrZXIgd2lsbCB1cGRhdGVcbiAgICAgKi9cbiAgICBnZXQgdXBkYXRlSW50ZXJ2YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl91cGRhdGVJbnRlcnZhbDtcbiAgICB9XG4gICAgc2V0IHVwZGF0ZUludGVydmFsKGludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX3VwZGF0ZUludGVydmFsID0gTWF0aC5tYXgoaW50ZXJ2YWwsIDEyOCAvIDQ0MTAwKTtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwid29ya2VyXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtlci5wb3N0TWVzc2FnZShNYXRoLm1heChpbnRlcnZhbCAqIDEwMDAsIDEpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgdGlja2VyLCBlaXRoZXIgYSB3b3JrZXIgb3IgYSB0aW1lb3V0XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VDbG9jaygpO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fY3JlYXRlQ2xvY2soKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICB0aGlzLl9kaXNwb3NlQ2xvY2soKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrZXIuanMubWFwIiwiaW1wb3J0IHsgaXNBbnlBdWRpb0NvbnRleHQsIGlzQW55QXVkaW9Ob2RlLCBpc0FueUF1ZGlvUGFyYW0sIGlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dCwgfSBmcm9tIFwic3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcIjtcbi8qKlxuICogVGVzdCBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb1BhcmFtXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0F1ZGlvUGFyYW0oYXJnKSB7XG4gICAgcmV0dXJuIGlzQW55QXVkaW9QYXJhbShhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBhbiBpbnN0YW5jZW9mIEF1ZGlvTm9kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb05vZGUoYXJnKSB7XG4gICAgcmV0dXJuIGlzQW55QXVkaW9Ob2RlKGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBpbnN0YW5jZW9mIGFuIE9mZmxpbmVBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmcpIHtcbiAgICByZXR1cm4gaXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0KGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBhbiBpbnN0YW5jZW9mIEF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb0NvbnRleHQoYXJnKSB7XG4gICAgcmV0dXJuIGlzQW55QXVkaW9Db250ZXh0KGFyZyk7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZyBpcyBpbnN0YW5jZW9mIGFuIEF1ZGlvQnVmZmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0F1ZGlvQnVmZmVyKGFyZykge1xuICAgIHJldHVybiBhcmcgaW5zdGFuY2VvZiBBdWRpb0J1ZmZlcjtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFkdmFuY2VkVHlwZUNoZWNrLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9CdWZmZXIsIGlzQXVkaW9Ob2RlLCBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgaXNEZWZpbmVkLCBpc09iamVjdCwgaXNVbmRlZiB9IGZyb20gXCIuL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBTb21lIG9iamVjdHMgc2hvdWxkIG5vdCBiZSBtZXJnZWRcbiAqL1xuZnVuY3Rpb24gbm9Db3B5KGtleSwgYXJnKSB7XG4gICAgcmV0dXJuIGtleSA9PT0gXCJ2YWx1ZVwiIHx8IGlzQXVkaW9QYXJhbShhcmcpIHx8IGlzQXVkaW9Ob2RlKGFyZykgfHwgaXNBdWRpb0J1ZmZlcihhcmcpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRlZXBNZXJnZSh0YXJnZXQsIC4uLnNvdXJjZXMpIHtcbiAgICBpZiAoIXNvdXJjZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZXMuc2hpZnQoKTtcbiAgICBpZiAoaXNPYmplY3QodGFyZ2V0KSAmJiBpc09iamVjdChzb3VyY2UpKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIHNvdXJjZSkge1xuICAgICAgICAgICAgaWYgKG5vQ29weShrZXksIHNvdXJjZVtrZXldKSkge1xuICAgICAgICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc09iamVjdChzb3VyY2Vba2V5XSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRhcmdldFtrZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odGFyZ2V0LCB7IFtrZXldOiB7fSB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVlcE1lcmdlKHRhcmdldFtrZXldLCBzb3VyY2Vba2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRhcmdldCwgeyBba2V5XTogc291cmNlW2tleV0gfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBkZWVwTWVyZ2UodGFyZ2V0LCAuLi5zb3VyY2VzKTtcbn1cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSB0d28gYXJyYXlzIGhhdmUgdGhlIHNhbWUgdmFsdWUgZm9yIGVhY2ggb2YgdGhlIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwRXF1YWxzKGFycmF5QSwgYXJyYXlCKSB7XG4gICAgcmV0dXJuIGFycmF5QS5sZW5ndGggPT09IGFycmF5Qi5sZW5ndGggJiYgYXJyYXlBLmV2ZXJ5KChlbGVtZW50LCBpbmRleCkgPT4gYXJyYXlCW2luZGV4XSA9PT0gZWxlbWVudCk7XG59XG4vKipcbiAqIENvbnZlcnQgYW4gYXJncyBhcnJheSBpbnRvIGFuIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wdGlvbnNGcm9tQXJndW1lbnRzKGRlZmF1bHRzLCBhcmdzQXJyYXksIGtleXMgPSBbXSwgb2JqS2V5KSB7XG4gICAgY29uc3Qgb3B0cyA9IHt9O1xuICAgIGNvbnN0IGFyZ3MgPSBBcnJheS5mcm9tKGFyZ3NBcnJheSk7XG4gICAgLy8gaWYgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIGFuIG9iamVjdCBhbmQgaGFzIGFuIG9iamVjdCBrZXlcbiAgICBpZiAoaXNPYmplY3QoYXJnc1swXSkgJiYgb2JqS2V5ICYmICFSZWZsZWN0LmhhcyhhcmdzWzBdLCBvYmpLZXkpKSB7XG4gICAgICAgIC8vIGlmIGl0J3Mgbm90IHBhcnQgb2YgdGhlIGRlZmF1bHRzXG4gICAgICAgIGNvbnN0IHBhcnRPZkRlZmF1bHRzID0gT2JqZWN0LmtleXMoYXJnc1swXSkuc29tZShrZXkgPT4gUmVmbGVjdC5oYXMoZGVmYXVsdHMsIGtleSkpO1xuICAgICAgICBpZiAoIXBhcnRPZkRlZmF1bHRzKSB7XG4gICAgICAgICAgICAvLyBtZXJnZSB0aGF0IGtleVxuICAgICAgICAgICAgZGVlcE1lcmdlKG9wdHMsIHsgW29iaktleV06IGFyZ3NbMF0gfSk7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIG9iaiBrZXkgZnJvbSB0aGUga2V5c1xuICAgICAgICAgICAga2V5cy5zcGxpY2Uoa2V5cy5pbmRleE9mKG9iaktleSksIDEpO1xuICAgICAgICAgICAgLy8gc2hpZnQgdGhlIGZpcnN0IGFyZ3VtZW50IG9mZlxuICAgICAgICAgICAgYXJncy5zaGlmdCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiBpc09iamVjdChhcmdzWzBdKSkge1xuICAgICAgICBkZWVwTWVyZ2Uob3B0cywgYXJnc1swXSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChpc0RlZmluZWQoYXJnc1tpXSkpIHtcbiAgICAgICAgICAgICAgICBvcHRzW2tleXNbaV1dID0gYXJnc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVlcE1lcmdlKGRlZmF1bHRzLCBvcHRzKTtcbn1cbi8qKlxuICogUmV0dXJuIHRoaXMgaW5zdGFuY2VzIGRlZmF1bHQgdmFsdWVzIGJ5IGNhbGxpbmcgQ29uc3RydWN0b3IuZ2V0RGVmYXVsdHMoKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdHNGcm9tSW5zdGFuY2UoaW5zdGFuY2UpIHtcbiAgICByZXR1cm4gaW5zdGFuY2UuY29uc3RydWN0b3IuZ2V0RGVmYXVsdHMoKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgZmFsbGJhY2sgaWYgdGhlIGdpdmVuIG9iamVjdCBpcyB1bmRlZmluZWQuXG4gKiBUYWtlIGFuIGFycmF5IG9mIGFyZ3VtZW50cyBhbmQgcmV0dXJuIGEgZm9ybWF0dGVkIG9wdGlvbnMgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdEFyZyhnaXZlbiwgZmFsbGJhY2spIHtcbiAgICBpZiAoaXNVbmRlZihnaXZlbikpIHtcbiAgICAgICAgcmV0dXJuIGZhbGxiYWNrO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGdpdmVuO1xuICAgIH1cbn1cbi8qKlxuICogUmVtb3ZlIGFsbCBvZiB0aGUgcHJvcGVydGllcyBiZWxvbmdpbmcgdG8gb21pdCBmcm9tIG9iai5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9taXRGcm9tT2JqZWN0KG9iaiwgb21pdCkge1xuICAgIG9taXQuZm9yRWFjaChwcm9wID0+IHtcbiAgICAgICAgaWYgKFJlZmxlY3QuaGFzKG9iaiwgcHJvcCkpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBvYmpbcHJvcF07XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gb2JqO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVmYXVsdHMuanMubWFwIiwiLyoqXG4gKiBUb25lLmpzXG4gKiBAYXV0aG9yIFlvdGFtIE1hbm5cbiAqIEBsaWNlbnNlIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9NSVQgTUlUIExpY2Vuc2VcbiAqIEBjb3B5cmlnaHQgMjAxNC0yMDE5IFlvdGFtIE1hbm5cbiAqL1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gXCIuLi92ZXJzaW9uXCI7XG5pbXBvcnQgeyB0aGVXaW5kb3cgfSBmcm9tIFwiLi9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBAY2xhc3MgIFRvbmUgaXMgdGhlIGJhc2UgY2xhc3Mgb2YgYWxsIG90aGVyIGNsYXNzZXMuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFx0REVCVUdHSU5HXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogU2V0IHRoaXMgZGVidWcgZmxhZyB0byBsb2cgYWxsIGV2ZW50cyB0aGF0IGhhcHBlbiBpbiB0aGlzIGNsYXNzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kZWJ1ZyA9IGZhbHNlO1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLy8gXHRESVNQT1NJTkdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGluc3RhbmNlIHdhcyBkaXNwb3NlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fd2FzRGlzcG9zZWQgPSBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbGwgb2YgdGhlIGRlZmF1bHQgb3B0aW9ucyBiZWxvbmdpbmcgdG8gdGhlIGNsYXNzLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQcmludHMgdGhlIG91dHB1dHMgdG8gdGhlIGNvbnNvbGUgbG9nIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuXG4gICAgICogUHJpbnRzIHRoZSBjb250ZW50cyBvbmx5IGlmIGVpdGhlciB0aGUgb2JqZWN0IGhhcyBhIHByb3BlcnR5XG4gICAgICogY2FsbGVkIGBkZWJ1Z2Agc2V0IHRvIHRydWUsIG9yIGEgdmFyaWFibGUgY2FsbGVkIFRPTkVfREVCVUdfQ0xBU1NcbiAgICAgKiBpcyBzZXQgdG8gdGhlIG5hbWUgb2YgdGhlIGNsYXNzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpO1xuICAgICAqIC8vIHByaW50cyBhbGwgbG9ncyBvcmlnaW5hdGluZyBmcm9tIHRoaXMgb3NjaWxsYXRvclxuICAgICAqIG9zYy5kZWJ1ZyA9IHRydWU7XG4gICAgICogLy8gY2FsbHMgdG8gc3RhcnQvc3RvcCB3aWxsIHByaW50IGluIHRoZSBjb25zb2xlXG4gICAgICogb3NjLnN0YXJ0KCk7XG4gICAgICovXG4gICAgbG9nKC4uLmFyZ3MpIHtcbiAgICAgICAgLy8gaWYgdGhlIG9iamVjdCBpcyBlaXRoZXIgc2V0IHRvIGRlYnVnID0gdHJ1ZVxuICAgICAgICAvLyBvciBpZiB0aGVyZSBpcyBhIHN0cmluZyBvbiB0aGUgVG9uZS5nbG9iYWwud2l0aCB0aGUgY2xhc3MgbmFtZVxuICAgICAgICBpZiAodGhpcy5kZWJ1ZyB8fCAodGhlV2luZG93ICYmIHRoaXMudG9TdHJpbmcoKSA9PT0gdGhlV2luZG93LlRPTkVfREVCVUdfQ0xBU1MpKSB7XG4gICAgICAgICAgICBsb2codGhpcywgLi4uYXJncyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogZGlzY29ubmVjdCBhbmQgZGlzcG9zZS5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICB0aGlzLl93YXNEaXNwb3NlZCA9IHRydWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIGluc3RhbmNlIHdhcyBkaXNwb3NlZC4gJ0Rpc3Bvc2luZycgYW5cbiAgICAgKiBpbnN0YW5jZSBtZWFucyB0aGF0IGFsbCBvZiB0aGUgV2ViIEF1ZGlvIG5vZGVzIHRoYXQgd2VyZVxuICAgICAqIGNyZWF0ZWQgZm9yIHRoZSBpbnN0YW5jZSBhcmUgZGlzY29ubmVjdGVkIGFuZCBmcmVlZCBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLlxuICAgICAqL1xuICAgIGdldCBkaXNwb3NlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dhc0Rpc3Bvc2VkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBjbGFzcyB0byBhIHN0cmluZ1xuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpO1xuICAgICAqIGNvbnNvbGUubG9nKG9zYy50b1N0cmluZygpKTtcbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmFtZTtcbiAgICB9XG59XG4vKipcbiAqIFRoZSB2ZXJzaW9uIG51bWJlciBzZW12ZXJcbiAqL1xuVG9uZS52ZXJzaW9uID0gdmVyc2lvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmUuanMubWFwIiwiLyoqXG4gKiBUaGUgdGhyZXNob2xkIGZvciBjb3JyZWN0bmVzcyBmb3Igb3BlcmF0b3JzLiBMZXNzIHRoYW4gb25lIHNhbXBsZSBldmVuXG4gKiBhdCB2ZXJ5IGhpZ2ggc2FtcGxpbmcgcmF0ZXMgKGUuZy4gYDFlLTYgPCAxIC8gMTkyMDAwYCkuXG4gKi9cbmNvbnN0IEVQU0lMT04gPSAxZS02O1xuLyoqXG4gKiBUZXN0IGlmIEEgaXMgZ3JlYXRlciB0aGFuIEJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEdUKGEsIGIpIHtcbiAgICByZXR1cm4gYSA+IGIgKyBFUFNJTE9OO1xufVxuLyoqXG4gKiBUZXN0IGlmIEEgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIEJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEdURShhLCBiKSB7XG4gICAgcmV0dXJuIEdUKGEsIGIpIHx8IEVRKGEsIGIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIEEgaXMgbGVzcyB0aGFuIEJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExUKGEsIGIpIHtcbiAgICByZXR1cm4gYSArIEVQU0lMT04gPCBiO1xufVxuLyoqXG4gKiBUZXN0IGlmIEEgaXMgbGVzcyB0aGFuIEJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEVRKGEsIGIpIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoYSAtIGIpIDwgRVBTSUxPTjtcbn1cbi8qKlxuICogQ2xhbXAgdGhlIHZhbHVlIHdpdGhpbiB0aGUgZ2l2ZW4gcmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsYW1wKHZhbHVlLCBtaW4sIG1heCkge1xuICAgIHJldHVybiBNYXRoLm1heChNYXRoLm1pbih2YWx1ZSwgbWF4KSwgbWluKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1hdGguanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi9EZWJ1Z1wiO1xuaW1wb3J0IHsgRVEsIEdULCBHVEUsIExUIH0gZnJvbSBcIi4vTWF0aFwiO1xuLyoqXG4gKiBBIFRpbWVsaW5lIGNsYXNzIGZvciBzY2hlZHVsaW5nIGFuZCBtYWludGFpbmluZyBzdGF0ZVxuICogYWxvbmcgYSB0aW1lbGluZS4gQWxsIGV2ZW50cyBtdXN0IGhhdmUgYSBcInRpbWVcIiBwcm9wZXJ0eS5cbiAqIEludGVybmFsbHksIGV2ZW50cyBhcmUgc3RvcmVkIGluIHRpbWUgb3JkZXIgZm9yIGZhc3RcbiAqIHJldHJpZXZhbC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVsaW5lIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGltZWxpbmVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhcnJheSBvZiBzY2hlZHVsZWQgdGltZWxpbmUgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lbGluZSA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGltZWxpbmUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtZW1vcnlcIl0pO1xuICAgICAgICB0aGlzLm1lbW9yeSA9IG9wdGlvbnMubWVtb3J5O1xuICAgICAgICB0aGlzLmluY3JlYXNpbmcgPSBvcHRpb25zLmluY3JlYXNpbmc7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1lbW9yeTogSW5maW5pdHksXG4gICAgICAgICAgICBpbmNyZWFzaW5nOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGUgdGltZWxpbmUuXG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zZXJ0IGFuIGV2ZW50IG9iamVjdCBvbnRvIHRoZSB0aW1lbGluZS4gRXZlbnRzIG11c3QgaGF2ZSBhIFwidGltZVwiIGF0dHJpYnV0ZS5cbiAgICAgKiBAcGFyYW0gZXZlbnQgIFRoZSBldmVudCBvYmplY3QgdG8gaW5zZXJ0IGludG8gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGFkZChldmVudCkge1xuICAgICAgICAvLyB0aGUgZXZlbnQgbmVlZHMgdG8gaGF2ZSBhIHRpbWUgYXR0cmlidXRlXG4gICAgICAgIGFzc2VydChSZWZsZWN0LmhhcyhldmVudCwgXCJ0aW1lXCIpLCBcIlRpbWVsaW5lOiBldmVudHMgbXVzdCBoYXZlIGEgdGltZSBhdHRyaWJ1dGVcIik7XG4gICAgICAgIGV2ZW50LnRpbWUgPSBldmVudC50aW1lLnZhbHVlT2YoKTtcbiAgICAgICAgaWYgKHRoaXMuaW5jcmVhc2luZyAmJiB0aGlzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgbGFzdFZhbHVlID0gdGhpcy5fdGltZWxpbmVbdGhpcy5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgIGFzc2VydChHVEUoZXZlbnQudGltZSwgbGFzdFZhbHVlLnRpbWUpLCBcIlRoZSB0aW1lIG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBsYXN0IHNjaGVkdWxlZCB0aW1lXCIpO1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUucHVzaChldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaChldmVudC50aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZShpbmRleCArIDEsIDAsIGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiB0aGUgbGVuZ3RoIGlzIG1vcmUgdGhhbiB0aGUgbWVtb3J5LCByZW1vdmUgdGhlIHByZXZpb3VzIG9uZXNcbiAgICAgICAgaWYgKHRoaXMubGVuZ3RoID4gdGhpcy5tZW1vcnkpIHtcbiAgICAgICAgICAgIGNvbnN0IGRpZmYgPSB0aGlzLmxlbmd0aCAtIHRoaXMubWVtb3J5O1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUuc3BsaWNlKDAsIGRpZmYpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYW4gZXZlbnQgZnJvbSB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgZXZlbnQgIFRoZSBldmVudCBvYmplY3QgdG8gcmVtb3ZlIGZyb20gdGhlIGxpc3QuXG4gICAgICogQHJldHVybnMge1RpbWVsaW5lfSB0aGlzXG4gICAgICovXG4gICAgcmVtb3ZlKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdGltZWxpbmUuaW5kZXhPZihldmVudCk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgbmVhcmVzdCBldmVudCB3aG9zZSB0aW1lIGlzIGxlc3MgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGdldCh0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUsIHBhcmFtKTtcbiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4XTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZmlyc3QgZXZlbnQgaW4gdGhlIHRpbWVsaW5lIHdpdGhvdXQgcmVtb3ZpbmcgaXRcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgZmlyc3QgZXZlbnQgb2JqZWN0XG4gICAgICovXG4gICAgcGVlaygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lWzBdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGV2ZW50IGluIHRoZSB0aW1lbGluZSBhbmQgcmVtb3ZlIGl0XG4gICAgICovXG4gICAgc2hpZnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZS5zaGlmdCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGV2ZW50IHdoaWNoIGlzIHNjaGVkdWxlZCBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGdldEFmdGVyKHRpbWUsIHBhcmFtID0gXCJ0aW1lXCIpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSwgcGFyYW0pO1xuICAgICAgICBpZiAoaW5kZXggKyAxIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXggKyAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZXZlbnQgYmVmb3JlIHRoZSBldmVudCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGdldEJlZm9yZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGxlbiA9IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDtcbiAgICAgICAgLy8gaWYgaXQncyBhZnRlciB0aGUgbGFzdCBpdGVtLCByZXR1cm4gdGhlIGxhc3QgaXRlbVxuICAgICAgICBpZiAobGVuID4gMCAmJiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXS50aW1lIDwgdGltZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2xlbiAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggLSAxID49IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGV2ZW50cyBhdCBhbmQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIGFmdGVyICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGxldCBpbmRleCA9IHRoaXMuX3NlYXJjaChhZnRlcik7XG4gICAgICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgICAgIGlmIChFUSh0aGlzLl90aW1lbGluZVtpbmRleF0udGltZSwgYWZ0ZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgZmlyc3QgaXRlbSB3aXRoIHRoYXQgdGltZVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoRVEodGhpcy5fdGltZWxpbmVbaV0udGltZSwgYWZ0ZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZSgwLCBpbmRleCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IHRoaXMuX3RpbWVsaW5lLnNsaWNlKDAsIGluZGV4ICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIC8vIHRoZSBmaXJzdCBpdGVtJ3MgdGltZVxuICAgICAgICAgICAgaWYgKEdURSh0aGlzLl90aW1lbGluZVswXS50aW1lLCBhZnRlcikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgZXZlbnRzIGJlZm9yZSBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIGNhbmNlbCBiZWZvcmUuXG4gICAgICovXG4gICAgY2FuY2VsQmVmb3JlKHRpbWUpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZSA9IHRoaXMuX3RpbWVsaW5lLnNsaWNlKGluZGV4ICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHByZXZpb3VzIGV2ZW50IGlmIHRoZXJlIGlzIG9uZS4gbnVsbCBvdGhlcndpc2VcbiAgICAgKiBAcGFyYW0gIGV2ZW50IFRoZSBldmVudCB0byBmaW5kIHRoZSBwcmV2aW91cyBvbmUgb2ZcbiAgICAgKiBAcmV0dXJuIFRoZSBldmVudCByaWdodCBiZWZvcmUgdGhlIGdpdmVuIGV2ZW50XG4gICAgICovXG4gICAgcHJldmlvdXNFdmVudChldmVudCkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3RpbWVsaW5lLmluZGV4T2YoZXZlbnQpO1xuICAgICAgICBpZiAoaW5kZXggPiAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERvZXMgYSBiaW5hcnkgc2VhcmNoIG9uIHRoZSB0aW1lbGluZSBhcnJheSBhbmQgcmV0dXJucyB0aGVcbiAgICAgKiBuZWFyZXN0IGV2ZW50IGluZGV4IHdob3NlIHRpbWUgaXMgYWZ0ZXIgb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogSWYgYSB0aW1lIGlzIHNlYXJjaGVkIGJlZm9yZSB0aGUgZmlyc3QgaW5kZXggaW4gdGhlIHRpbWVsaW5lLCAtMSBpcyByZXR1cm5lZC5cbiAgICAgKiBJZiB0aGUgdGltZSBpcyBhZnRlciB0aGUgZW5kLCB0aGUgaW5kZXggb2YgdGhlIGxhc3QgaXRlbSBpcyByZXR1cm5lZC5cbiAgICAgKi9cbiAgICBfc2VhcmNoKHRpbWUsIHBhcmFtID0gXCJ0aW1lXCIpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIGxldCBiZWdpbm5pbmcgPSAwO1xuICAgICAgICBjb25zdCBsZW4gPSB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgICAgIGxldCBlbmQgPSBsZW47XG4gICAgICAgIGlmIChsZW4gPiAwICYmIHRoaXMuX3RpbWVsaW5lW2xlbiAtIDFdW3BhcmFtXSA8PSB0aW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gbGVuIC0gMTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoYmVnaW5uaW5nIDwgZW5kKSB7XG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIG1pZHBvaW50IGZvciByb3VnaGx5IGVxdWFsIHBhcnRpdGlvblxuICAgICAgICAgICAgbGV0IG1pZFBvaW50ID0gTWF0aC5mbG9vcihiZWdpbm5pbmcgKyAoZW5kIC0gYmVnaW5uaW5nKSAvIDIpO1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl90aW1lbGluZVttaWRQb2ludF07XG4gICAgICAgICAgICBjb25zdCBuZXh0RXZlbnQgPSB0aGlzLl90aW1lbGluZVttaWRQb2ludCArIDFdO1xuICAgICAgICAgICAgaWYgKEVRKGV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBjaG9vc2UgdGhlIGxhc3Qgb25lIHRoYXQgaGFzIHRoZSBzYW1lIHRpbWVcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gbWlkUG9pbnQ7IGkgPCB0aGlzLl90aW1lbGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZXN0RXZlbnQgPSB0aGlzLl90aW1lbGluZVtpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKEVRKHRlc3RFdmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtaWRQb2ludCA9IGk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbWlkUG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChMVChldmVudFtwYXJhbV0sIHRpbWUpICYmIEdUKG5leHRFdmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pZFBvaW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoR1QoZXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgIC8vIHNlYXJjaCBsb3dlclxuICAgICAgICAgICAgICAgIGVuZCA9IG1pZFBvaW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gc2VhcmNoIHVwcGVyXG4gICAgICAgICAgICAgICAgYmVnaW5uaW5nID0gbWlkUG9pbnQgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgaXRlcmF0b3IuIEFwcGxpZXMgZXh0cmEgc2FmZXR5IGNoZWNrcyBmb3JcbiAgICAgKiByZW1vdmluZyBpdGVtcyBmcm9tIHRoZSBhcnJheS5cbiAgICAgKi9cbiAgICBfaXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCA9IDAsIHVwcGVyQm91bmQgPSB0aGlzLl90aW1lbGluZS5sZW5ndGggLSAxKSB7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLnNsaWNlKGxvd2VyQm91bmQsIHVwcGVyQm91bmQgKyAxKS5mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5XG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYXQgb3IgYmVmb3JlIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hCZWZvcmUodGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuICAgICAgICBjb25zdCB1cHBlckJvdW5kID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAodXBwZXJCb3VuZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIDAsIHVwcGVyQm91bmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEFmdGVyKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgY29uc3QgbG93ZXJCb3VuZCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGJldHdlZW4gdGhlIHN0YXJ0VGltZSBhbmQgZW5kVGltZS5cbiAgICAgKiBUaGUgdGltZXJhbmdlIGlzIGluY2x1c2l2ZSBvZiB0aGUgc3RhcnRUaW1lLCBidXQgZXhjbHVzaXZlIG9mIHRoZSBlbmRUaW1lLlxuICAgICAqIHJhbmdlID0gW3N0YXJ0VGltZSwgZW5kVGltZSkuXG4gICAgICogQHBhcmFtICBzdGFydFRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgZW5kVGltZSBUaGUgZW5kIG9mIHRoZSB0ZXN0IGludGVydmFsLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGxldCBsb3dlckJvdW5kID0gdGhpcy5fc2VhcmNoKHN0YXJ0VGltZSk7XG4gICAgICAgIGxldCB1cHBlckJvdW5kID0gdGhpcy5fc2VhcmNoKGVuZFRpbWUpO1xuICAgICAgICBpZiAobG93ZXJCb3VuZCAhPT0gLTEgJiYgdXBwZXJCb3VuZCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl90aW1lbGluZVtsb3dlckJvdW5kXS50aW1lICE9PSBzdGFydFRpbWUpIHtcbiAgICAgICAgICAgICAgICBsb3dlckJvdW5kICs9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBleGNsdXNpdmUgb2YgdGhlIGVuZCB0aW1lXG4gICAgICAgICAgICBpZiAodGhpcy5fdGltZWxpbmVbdXBwZXJCb3VuZF0udGltZSA9PT0gZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIHVwcGVyQm91bmQgLT0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQsIHVwcGVyQm91bmQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGxvd2VyQm91bmQgPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCAwLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IG9yIGFmdGVyIHRoZSBnaXZlbiB0aW1lLiBTaW1pbGFyIHRvXG4gICAgICogZm9yRWFjaEFmdGVyLCBidXQgaW5jbHVkZXMgdGhlIGl0ZW0ocykgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEZyb20odGltZSwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gaXRlcmF0ZSBvdmVyIHRoZSBpdGVtcyBpbiByZXZlcnNlIHNvIHRoYXQgcmVtb3ZpbmcgYW4gaXRlbSBkb2Vzbid0IGJyZWFrIHRoaW5nc1xuICAgICAgICBsZXQgbG93ZXJCb3VuZCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgLy8gd29yayBiYWNrd2FyZHMgdW50aWwgdGhlIGV2ZW50IHRpbWUgaXMgbGVzcyB0aGFuIHRpbWVcbiAgICAgICAgd2hpbGUgKGxvd2VyQm91bmQgPj0gMCAmJiB0aGlzLl90aW1lbGluZVtsb3dlckJvdW5kXS50aW1lID49IHRpbWUpIHtcbiAgICAgICAgICAgIGxvd2VyQm91bmQtLTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kICsgMSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJdGVyYXRlIG92ZXIgZXZlcnl0aGluZyBpbiB0aGUgYXJyYXkgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQXRUaW1lKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgY29uc3QgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKHVwcGVyQm91bmQgIT09IC0xICYmIEVRKHRoaXMuX3RpbWVsaW5lW3VwcGVyQm91bmRdLnRpbWUsIHRpbWUpKSB7XG4gICAgICAgICAgICBsZXQgbG93ZXJCb3VuZCA9IHVwcGVyQm91bmQ7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdXBwZXJCb3VuZDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBpZiAoRVEodGhpcy5fdGltZWxpbmVbaV0udGltZSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbG93ZXJCb3VuZCA9IGk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhldmVudCk7XG4gICAgICAgICAgICB9LCBsb3dlckJvdW5kLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aW1lbGluZSA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lbGluZS5qcy5tYXAiLCIvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIElOSVRJQUxJWklORyBORVcgQ09OVEVYVFxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIEFycmF5IG9mIGNhbGxiYWNrcyB0byBpbnZva2Ugd2hlbiBhIG5ldyBjb250ZXh0IGlzIGNyZWF0ZWRcbiAqL1xuY29uc3Qgbm90aWZ5TmV3Q29udGV4dCA9IFtdO1xuLyoqXG4gKiBVc2VkIGludGVybmFsbHkgdG8gc2V0dXAgYSBuZXcgQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gb25Db250ZXh0SW5pdChjYikge1xuICAgIG5vdGlmeU5ld0NvbnRleHQucHVzaChjYik7XG59XG4vKipcbiAqIEludm9rZSBhbnkgY2xhc3NlcyB3aGljaCBuZWVkIHRvIGFsc28gYmUgaW5pdGlhbGl6ZWQgd2hlbiBhIG5ldyBjb250ZXh0IGlzIGNyZWF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0aWFsaXplQ29udGV4dChjdHgpIHtcbiAgICAvLyBhZGQgYW55IGFkZGl0aW9uYWwgbW9kdWxlc1xuICAgIG5vdGlmeU5ld0NvbnRleHQuZm9yRWFjaChjYiA9PiBjYihjdHgpKTtcbn1cbi8qKlxuICogQXJyYXkgb2YgY2FsbGJhY2tzIHRvIGludm9rZSB3aGVuIGEgbmV3IGNvbnRleHQgaXMgY3JlYXRlZFxuICovXG5jb25zdCBub3RpZnlDbG9zZUNvbnRleHQgPSBbXTtcbi8qKlxuICogVXNlZCBpbnRlcm5hbGx5IHRvIHRlYXIgZG93biBhIENvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ29udGV4dENsb3NlKGNiKSB7XG4gICAgbm90aWZ5Q2xvc2VDb250ZXh0LnB1c2goY2IpO1xufVxuZXhwb3J0IGZ1bmN0aW9uIGNsb3NlQ29udGV4dChjdHgpIHtcbiAgICAvLyBhZGQgYW55IGFkZGl0aW9uYWwgbW9kdWxlc1xuICAgIG5vdGlmeUNsb3NlQ29udGV4dC5mb3JFYWNoKGNiID0+IGNiKGN0eCkpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udGV4dEluaXRpYWxpemF0aW9uLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNVbmRlZiB9IGZyb20gXCIuL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBFbWl0dGVyIGdpdmVzIGNsYXNzZXMgd2hpY2ggZXh0ZW5kIGl0XG4gKiB0aGUgYWJpbGl0eSB0byBsaXN0ZW4gZm9yIGFuZCBlbWl0IGV2ZW50cy5cbiAqIEluc3BpcmF0aW9uIGFuZCByZWZlcmVuY2UgZnJvbSBKZXJvbWUgRXRpZW5uZSdzIFtNaWNyb0V2ZW50XShodHRwczovL2dpdGh1Yi5jb20vamVyb21lZXRpZW5uZS9taWNyb2V2ZW50LmpzKS5cbiAqIE1JVCAoYykgMjAxMSBKZXJvbWUgRXRpZW5uZS5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBFbWl0dGVyIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRW1pdHRlclwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgY2FsbGJhY2sgdG8gYSBzcGVjaWZpYyBldmVudC5cbiAgICAgKiBAcGFyYW0gIGV2ZW50ICAgICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIGZvci5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWRcbiAgICAgKi9cbiAgICBvbihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgICAgLy8gc3BsaXQgdGhlIGV2ZW50XG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IGV2ZW50LnNwbGl0KC9cXFcrLyk7XG4gICAgICAgIGV2ZW50cy5mb3JFYWNoKGV2ZW50TmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNVbmRlZih0aGlzLl9ldmVudHMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2V2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudE5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50TmFtZV0gPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudE5hbWVdLnB1c2goY2FsbGJhY2spO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJpbmQgYSBjYWxsYmFjayB3aGljaCBpcyBvbmx5IGludm9rZWQgb25jZVxuICAgICAqIEBwYXJhbSAgZXZlbnQgICAgIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gZm9yLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgZXZlbnQgaXMgZW1pdHRlZFxuICAgICAqL1xuICAgIG9uY2UoZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IGJvdW5kQ2FsbGJhY2sgPSAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgY2FsbGJhY2soLi4uYXJncyk7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIGV2ZW50XG4gICAgICAgICAgICB0aGlzLm9mZihldmVudCwgYm91bmRDYWxsYmFjayk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMub24oZXZlbnQsIGJvdW5kQ2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBldmVudCBsaXN0ZW5lci5cbiAgICAgKiBAcGFyYW0gIGV2ZW50ICAgICBUaGUgZXZlbnQgdG8gc3RvcCBsaXN0ZW5pbmcgdG8uXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHdoaWNoIHdhcyBib3VuZCB0byB0aGUgZXZlbnQgd2l0aCBFbWl0dGVyLm9uLlxuICAgICAqICAgICAgICAgICAgICAgICAgIElmIG5vIGNhbGxiYWNrIGlzIGdpdmVuLCBhbGwgY2FsbGJhY2tzIGV2ZW50cyBhcmUgcmVtb3ZlZC5cbiAgICAgKi9cbiAgICBvZmYoZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IGV2ZW50LnNwbGl0KC9cXFcrLyk7XG4gICAgICAgIGV2ZW50cy5mb3JFYWNoKGV2ZW50TmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNVbmRlZih0aGlzLl9ldmVudHMpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGlmIChpc1VuZGVmKGNhbGxiYWNrKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZlbnRdID0gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBldmVudExpc3QgPSB0aGlzLl9ldmVudHNbZXZlbnRdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gZXZlbnRMaXN0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXZlbnRMaXN0W2ldID09PSBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TGlzdC5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIGFsbCBvZiB0aGUgY2FsbGJhY2tzIGJvdW5kIHRvIHRoZSBldmVudFxuICAgICAqIHdpdGggYW55IGFyZ3VtZW50cyBwYXNzZWQgaW4uXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50LlxuICAgICAqIEBwYXJhbSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgZnVuY3Rpb25zIGxpc3RlbmluZy5cbiAgICAgKi9cbiAgICBlbWl0KGV2ZW50LCAuLi5hcmdzKSB7XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnQpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnRMaXN0ID0gdGhpcy5fZXZlbnRzW2V2ZW50XS5zbGljZSgwKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gZXZlbnRMaXN0Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50TGlzdFtpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBFbWl0dGVyIGZ1bmN0aW9ucyAob24vb2ZmL2VtaXQpIHRvIHRoZSBvYmplY3RcbiAgICAgKi9cbiAgICBzdGF0aWMgbWl4aW4oY29uc3RyKSB7XG4gICAgICAgIC8vIGluc3RhbmNlLl9ldmVudHMgPSB7fTtcbiAgICAgICAgW1wib25cIiwgXCJvbmNlXCIsIFwib2ZmXCIsIFwiZW1pdFwiXS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvcGVydHkgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKEVtaXR0ZXIucHJvdG90eXBlLCBuYW1lKTtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb25zdHIucHJvdG90eXBlLCBuYW1lLCBwcm9wZXJ0eSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FbWl0dGVyLmpzLm1hcCIsImltcG9ydCB7IEVtaXR0ZXIgfSBmcm9tIFwiLi4vdXRpbC9FbWl0dGVyXCI7XG5leHBvcnQgY2xhc3MgQmFzZUNvbnRleHQgZXh0ZW5kcyBFbWl0dGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5pc09mZmxpbmUgPSBmYWxzZTtcbiAgICB9XG4gICAgLypcbiAgICAgKiBUaGlzIGlzIGEgcGxhY2Vob2xkZXIgc28gdGhhdCBKU09OLnN0cmluZ2lmeSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvclxuICAgICAqIFRoaXMgbWF0Y2hlcyB3aGF0IEpTT04uc3RyaW5naWZ5KGF1ZGlvQ29udGV4dCkgcmV0dXJucyBvbiBhIG5hdGl2ZVxuICAgICAqIGF1ZGlvQ29udGV4dCBpbnN0YW5jZS5cbiAgICAgKi9cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1CYXNlQ29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRpY2tlciB9IGZyb20gXCIuLi9jbG9jay9UaWNrZXJcIjtcbmltcG9ydCB7IGlzQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQ29udGV4dCwgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZSwgfSBmcm9tIFwiLi9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IGNsb3NlQ29udGV4dCwgaW5pdGlhbGl6ZUNvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEJhc2VDb250ZXh0IH0gZnJvbSBcIi4vQmFzZUNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgQXVkaW9Db250ZXh0LlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRleHQgZXh0ZW5kcyBCYXNlQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ29udGV4dFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQW4gb2JqZWN0IGNvbnRhaW5pbmcgYWxsIG9mIHRoZSBjb25zdGFudHMgQXVkaW9CdWZmZXJTb3VyY2VOb2Rlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29uc3RhbnRzID0gbmV3IE1hcCgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBzZXRUaW1lb3V0IGV2ZW50cy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVvdXRzID0gbmV3IFRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZW91dCBpZCBjb3VudGVyXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lb3V0SWRzID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByaXZhdGUgaW5kaWNhdG9yIGlmIHRoZSBjb250ZXh0IGhhcyBiZWVuIGluaXRpYWxpemVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBjb250ZXh0IGlzIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgb3IgYW4gQXVkaW9Db250ZXh0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlzT2ZmbGluZSA9IGZhbHNlO1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIEFVRElPIFdPUktMRVRcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogTWFwcyBhIG1vZHVsZSBuYW1lIHRvIHByb21pc2Ugb2YgdGhlIGFkZE1vZHVsZSBtZXRob2RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3dvcmtsZXRNb2R1bGVzID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29udGV4dC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcbiAgICAgICAgICAgIFwiY29udGV4dFwiLFxuICAgICAgICBdKTtcbiAgICAgICAgaWYgKG9wdGlvbnMuY29udGV4dCkge1xuICAgICAgICAgICAgdGhpcy5fY29udGV4dCA9IG9wdGlvbnMuY29udGV4dDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHQgPSBjcmVhdGVBdWRpb0NvbnRleHQoe1xuICAgICAgICAgICAgICAgIGxhdGVuY3lIaW50OiBvcHRpb25zLmxhdGVuY3lIaW50LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGlja2VyID0gbmV3IFRpY2tlcih0aGlzLmVtaXQuYmluZCh0aGlzLCBcInRpY2tcIiksIG9wdGlvbnMuY2xvY2tTb3VyY2UsIG9wdGlvbnMudXBkYXRlSW50ZXJ2YWwpO1xuICAgICAgICB0aGlzLm9uKFwidGlja1wiLCB0aGlzLl90aW1lb3V0TG9vcC5iaW5kKHRoaXMpKTtcbiAgICAgICAgLy8gZndkIGV2ZW50cyBmcm9tIHRoZSBjb250ZXh0XG4gICAgICAgIHRoaXMuX2NvbnRleHQub25zdGF0ZWNoYW5nZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXRlY2hhbmdlXCIsIHRoaXMuc3RhdGUpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLl9zZXRMYXRlbmN5SGludChvcHRpb25zLmxhdGVuY3lIaW50KTtcbiAgICAgICAgdGhpcy5sb29rQWhlYWQgPSBvcHRpb25zLmxvb2tBaGVhZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2xvY2tTb3VyY2U6IFwid29ya2VyXCIsXG4gICAgICAgICAgICBsYXRlbmN5SGludDogXCJpbnRlcmFjdGl2ZVwiLFxuICAgICAgICAgICAgbG9va0FoZWFkOiAwLjEsXG4gICAgICAgICAgICB1cGRhdGVJbnRlcnZhbDogMC4wNSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRmluaXNoIHNldHRpbmcgdXAgdGhlIGNvbnRleHQuICoqWW91IHVzdWFsbHkgZG8gbm90IG5lZWQgdG8gZG8gdGhpcyBtYW51YWxseS4qKlxuICAgICAqL1xuICAgIGluaXRpYWxpemUoKSB7XG4gICAgICAgIGlmICghdGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIC8vIGFkZCBhbnkgYWRkaXRpb25hbCBtb2R1bGVzXG4gICAgICAgICAgICBpbml0aWFsaXplQ29udGV4dCh0aGlzKTtcbiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBCQVNFIEFVRElPIENPTlRFWFQgTUVUSE9EU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgY3JlYXRlQW5hbHlzZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUFuYWx5c2VyKCk7XG4gICAgfVxuICAgIGNyZWF0ZU9zY2lsbGF0b3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICB9XG4gICAgY3JlYXRlQmlxdWFkRmlsdGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbE1lcmdlcihudW1iZXJPZklucHV0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDaGFubmVsTWVyZ2VyKG51bWJlck9mSW5wdXRzKTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIobnVtYmVyT2ZPdXRwdXRzKTtcbiAgICB9XG4gICAgY3JlYXRlQ29uc3RhbnRTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgfVxuICAgIGNyZWF0ZUNvbnZvbHZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZURlbGF5KG1heERlbGF5VGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVEZWxheShtYXhEZWxheVRpbWUpO1xuICAgIH1cbiAgICBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpO1xuICAgIH1cbiAgICBjcmVhdGVHYWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgfVxuICAgIGNyZWF0ZUlJUkZpbHRlcihmZWVkRm9yd2FyZCwgZmVlZGJhY2spIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoZmVlZEZvcndhcmQsIGZlZWRiYWNrKTtcbiAgICB9XG4gICAgY3JlYXRlUGFubmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlUGVyaW9kaWNXYXZlKHJlYWwsIGltYWcsIGNvbnN0cmFpbnRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnLCBjb25zdHJhaW50cyk7XG4gICAgfVxuICAgIGNyZWF0ZVN0ZXJlb1Bhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZVdhdmVTaGFwZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKSB7XG4gICAgICAgIGFzc2VydChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSwgXCJOb3QgYXZhaWxhYmxlIGlmIE9mZmxpbmVBdWRpb0NvbnRleHRcIik7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICByZXR1cm4gY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShzdHJlYW0pO1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UoZWxlbWVudCkge1xuICAgICAgICBhc3NlcnQoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCksIFwiTm90IGF2YWlsYWJsZSBpZiBPZmZsaW5lQXVkaW9Db250ZXh0XCIpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKGVsZW1lbnQpO1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICBhc3NlcnQoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCksIFwiTm90IGF2YWlsYWJsZSBpZiBPZmZsaW5lQXVkaW9Db250ZXh0XCIpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpO1xuICAgIH1cbiAgICBkZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmRlY29kZUF1ZGlvRGF0YShhdWRpb0RhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIEF1ZGlvQ29udGV4dC5cbiAgICAgKi9cbiAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIEF1ZGlvQ29udGV4dC5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LnN0YXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIEF1ZGlvQ29udGV4dC5cbiAgICAgKi9cbiAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxpc3RlbmVyXG4gICAgICovXG4gICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xpc3RlbmVyO1xuICAgIH1cbiAgICBzZXQgbGlzdGVuZXIobCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIlRoZSBsaXN0ZW5lciBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fbGlzdGVuZXIgPSBsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGVyZSBpcyBvbmx5IG9uZSBUcmFuc3BvcnQgcGVyIENvbnRleHQuIEl0IGlzIGNyZWF0ZWQgb24gaW5pdGlhbGl6YXRpb24uXG4gICAgICovXG4gICAgZ2V0IHRyYW5zcG9ydCgpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmFuc3BvcnQ7XG4gICAgfVxuICAgIHNldCB0cmFuc3BvcnQodCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIlRoZSB0cmFuc3BvcnQgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX3RyYW5zcG9ydCA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgdGhlIERyYXcgb2JqZWN0IGZvciB0aGUgY29udGV4dCB3aGljaCBpcyB1c2VmdWwgZm9yIHN5bmNocm9uaXppbmcgdGhlIGRyYXcgZnJhbWUgd2l0aCB0aGUgVG9uZS5qcyBjbG9jay5cbiAgICAgKi9cbiAgICBnZXQgZHJhdygpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9kcmF3O1xuICAgIH1cbiAgICBzZXQgZHJhdyhkKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5faW5pdGlhbGl6ZWQsIFwiRHJhdyBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fZHJhdyA9IGQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcmVmZXJlbmNlIHRvIHRoZSBDb250ZXh0J3MgZGVzdGluYXRpb24gbm9kZS5cbiAgICAgKi9cbiAgICBnZXQgZGVzdGluYXRpb24oKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVzdGluYXRpb247XG4gICAgfVxuICAgIHNldCBkZXN0aW5hdGlvbihkKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5faW5pdGlhbGl6ZWQsIFwiVGhlIGRlc3RpbmF0aW9uIGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl9kZXN0aW5hdGlvbiA9IGQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbiBhdWRpbyB3b3JrbGV0IG5vZGUgZnJvbSBhIG5hbWUgYW5kIG9wdGlvbnMuIFRoZSBtb2R1bGVcbiAgICAgKiBtdXN0IGZpcnN0IGJlIGxvYWRlZCB1c2luZyBbW2FkZEF1ZGlvV29ya2xldE1vZHVsZV1dLlxuICAgICAqL1xuICAgIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUobmFtZSwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZSh0aGlzLnJhd0NvbnRleHQsIG5hbWUsIG9wdGlvbnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIG1vZHVsZVxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgbW9kdWxlXG4gICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZVxuICAgICAqL1xuICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZSh1cmwsIG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydChpc0RlZmluZWQodGhpcy5yYXdDb250ZXh0LmF1ZGlvV29ya2xldCksIFwiQXVkaW9Xb3JrbGV0Tm9kZSBpcyBvbmx5IGF2YWlsYWJsZSBpbiBhIHNlY3VyZSBjb250ZXh0IChodHRwcyBvciBsb2NhbGhvc3QpXCIpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl93b3JrbGV0TW9kdWxlcy5oYXMobmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcy5zZXQobmFtZSwgdGhpcy5yYXdDb250ZXh0LmF1ZGlvV29ya2xldC5hZGRNb2R1bGUodXJsKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl93b3JrbGV0TW9kdWxlcy5nZXQobmFtZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIGFsbCBvZiB0aGUgd29ya2xldHMgaGF2ZSBiZWVuIGxvYWRlZCBvbiB0aGlzIGNvbnRleHRcbiAgICAgKi9cbiAgICB3b3JrbGV0c0FyZVJlYWR5KCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtsZXRNb2R1bGVzLmZvckVhY2goKHByb21pc2UpID0+IHByb21pc2VzLnB1c2gocHJvbWlzZSkpO1xuICAgICAgICAgICAgeWllbGQgUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUSUNLRVJcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEhvdyBvZnRlbiB0aGUgaW50ZXJ2YWwgY2FsbGJhY2sgaXMgaW52b2tlZC5cbiAgICAgKiBUaGlzIG51bWJlciBjb3JyZXNwb25kcyB0byBob3cgcmVzcG9uc2l2ZSB0aGUgc2NoZWR1bGluZ1xuICAgICAqIGNhbiBiZS4gY29udGV4dC51cGRhdGVJbnRlcnZhbCArIGNvbnRleHQubG9va0FoZWFkIGdpdmVzIHlvdSB0aGVcbiAgICAgKiB0b3RhbCBsYXRlbmN5IGJldHdlZW4gc2NoZWR1bGluZyBhbiBldmVudCBhbmQgaGVhcmluZyBpdC5cbiAgICAgKi9cbiAgICBnZXQgdXBkYXRlSW50ZXJ2YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrZXIudXBkYXRlSW50ZXJ2YWw7XG4gICAgfVxuICAgIHNldCB1cGRhdGVJbnRlcnZhbChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl90aWNrZXIudXBkYXRlSW50ZXJ2YWwgPSBpbnRlcnZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hhdCB0aGUgc291cmNlIG9mIHRoZSBjbG9jayBpcywgZWl0aGVyIFwid29ya2VyXCIgKGRlZmF1bHQpLFxuICAgICAqIFwidGltZW91dFwiLCBvciBcIm9mZmxpbmVcIiAobm9uZSkuXG4gICAgICovXG4gICAgZ2V0IGNsb2NrU291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja2VyLnR5cGU7XG4gICAgfVxuICAgIHNldCBjbG9ja1NvdXJjZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3RpY2tlci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgcGxheWJhY2ssIHdoaWNoIGFmZmVjdHMgdHJhZGVvZmZzIGJldHdlZW4gYXVkaW9cbiAgICAgKiBvdXRwdXQgbGF0ZW5jeSBhbmQgcmVzcG9uc2l2ZW5lc3MuXG4gICAgICogSW4gYWRkaXRpb24gdG8gc2V0dGluZyB0aGUgdmFsdWUgaW4gc2Vjb25kcywgdGhlIGxhdGVuY3lIaW50IGFsc29cbiAgICAgKiBhY2NlcHRzIHRoZSBzdHJpbmdzIFwiaW50ZXJhY3RpdmVcIiAocHJpb3JpdGl6ZXMgbG93IGxhdGVuY3kpLFxuICAgICAqIFwicGxheWJhY2tcIiAocHJpb3JpdGl6ZXMgc3VzdGFpbmVkIHBsYXliYWNrKSwgXCJiYWxhbmNlZFwiIChiYWxhbmNlc1xuICAgICAqIGxhdGVuY3kgYW5kIHBlcmZvcm1hbmNlKS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHByaW9yaXRpemUgc3VzdGFpbmVkIHBsYXliYWNrXG4gICAgICogY29uc3QgY29udGV4dCA9IG5ldyBUb25lLkNvbnRleHQoeyBsYXRlbmN5SGludDogXCJwbGF5YmFja1wiIH0pO1xuICAgICAqIC8vIHNldCB0aGlzIGNvbnRleHQgYXMgdGhlIGdsb2JhbCBDb250ZXh0XG4gICAgICogVG9uZS5zZXRDb250ZXh0KGNvbnRleHQpO1xuICAgICAqIC8vIHRoZSBnbG9iYWwgY29udGV4dCBpcyBnZXR0YWJsZSB3aXRoIFRvbmUuZ2V0Q29udGV4dCgpXG4gICAgICogY29uc29sZS5sb2coVG9uZS5nZXRDb250ZXh0KCkubGF0ZW5jeUhpbnQpO1xuICAgICAqL1xuICAgIGdldCBsYXRlbmN5SGludCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lIaW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGxvb2tBaGVhZCBhbmQgdXBkYXRlSW50ZXJ2YWwgYmFzZWQgb24gdGhlIGxhdGVuY3lIaW50XG4gICAgICovXG4gICAgX3NldExhdGVuY3lIaW50KGhpbnQpIHtcbiAgICAgICAgbGV0IGxvb2tBaGVhZFZhbHVlID0gMDtcbiAgICAgICAgdGhpcy5fbGF0ZW5jeUhpbnQgPSBoaW50O1xuICAgICAgICBpZiAoaXNTdHJpbmcoaGludCkpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoaGludCkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJpbnRlcmFjdGl2ZVwiOlxuICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWRWYWx1ZSA9IDAuMTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInBsYXliYWNrXCI6XG4gICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZFZhbHVlID0gMC41O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiYmFsYW5jZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkVmFsdWUgPSAwLjI1O1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvb2tBaGVhZCA9IGxvb2tBaGVhZFZhbHVlO1xuICAgICAgICB0aGlzLnVwZGF0ZUludGVydmFsID0gbG9va0FoZWFkVmFsdWUgLyAyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdW53cmFwcGVkIEF1ZGlvQ29udGV4dCBvciBPZmZsaW5lQXVkaW9Db250ZXh0XG4gICAgICovXG4gICAgZ2V0IHJhd0NvbnRleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCBhdWRpbyBjb250ZXh0IHRpbWUgcGx1cyBhIHNob3J0IFtbbG9va0FoZWFkXV0uXG4gICAgICovXG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jdXJyZW50VGltZSArIHRoaXMubG9va0FoZWFkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCBhdWRpbyBjb250ZXh0IHRpbWUgd2l0aG91dCB0aGUgW1tsb29rQWhlYWRdXS5cbiAgICAgKiBJbiBtb3N0IGNhc2VzIGl0IGlzIGJldHRlciB0byB1c2UgW1tub3ddXSBpbnN0ZWFkIG9mIFtbaW1tZWRpYXRlXV0gc2luY2VcbiAgICAgKiB3aXRoIFtbbm93XV0gdGhlIFtbbG9va0FoZWFkXV0gaXMgYXBwbGllZCBlcXVhbGx5IHRvIF9hbGxfIGNvbXBvbmVudHMgaW5jbHVkaW5nIGludGVybmFsIGNvbXBvbmVudHMsXG4gICAgICogdG8gbWFraW5nIHN1cmUgdGhhdCBldmVyeXRoaW5nIGlzIHNjaGVkdWxlZCBpbiBzeW5jLiBNaXhpbmcgW1tub3ddXSBhbmQgW1tpbW1lZGlhdGVdXVxuICAgICAqIGNhbiBjYXVzZSBzb21lIHRpbWluZyBpc3N1ZXMuIElmIG5vIGxvb2tBaGVhZCBpcyBkZXNpcmVkLCB5b3UgY2FuIHNldCB0aGUgW1tsb29rQWhlYWRdXSB0byBgMGAuXG4gICAgICovXG4gICAgaW1tZWRpYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnRzIHRoZSBhdWRpbyBjb250ZXh0IGZyb20gYSBzdXNwZW5kZWQgc3RhdGUuIFRoaXMgaXMgcmVxdWlyZWRcbiAgICAgKiB0byBpbml0aWFsbHkgc3RhcnQgdGhlIEF1ZGlvQ29udGV4dC4gU2VlIFtbVG9uZS5zdGFydF1dXG4gICAgICovXG4gICAgcmVzdW1lKCkge1xuICAgICAgICBpZiAoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LnJlc3VtZSgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBjb250ZXh0LiBPbmNlIGNsb3NlZCwgdGhlIGNvbnRleHQgY2FuIG5vIGxvbmdlciBiZSB1c2VkIGFuZFxuICAgICAqIGFueSBBdWRpb05vZGVzIGNyZWF0ZWQgZnJvbSB0aGUgY29udGV4dCB3aWxsIGJlIHNpbGVudC5cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGlmIChpc0F1ZGlvQ29udGV4dCh0aGlzLl9jb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHlpZWxkIHRoaXMuX2NvbnRleHQuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLl9pbml0aWFsaXplZCkge1xuICAgICAgICAgICAgICAgIGNsb3NlQ29udGV4dCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqICoqSW50ZXJuYWwqKiBHZW5lcmF0ZSBhIGxvb3BlZCBidWZmZXIgYXQgc29tZSBjb25zdGFudCB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXRDb25zdGFudCh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NvbnN0YW50cy5oYXModmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnN0YW50cy5nZXQodmFsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEyOCwgdGhpcy5fY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIGNvbnN0IGFyciA9IGJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgYXJyW2ldID0gdmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY29uc3RhbnQgPSB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICAgICAgY29uc3RhbnQuY2hhbm5lbENvdW50ID0gMTtcbiAgICAgICAgICAgIGNvbnN0YW50LmNoYW5uZWxDb3VudE1vZGUgPSBcImV4cGxpY2l0XCI7XG4gICAgICAgICAgICBjb25zdGFudC5idWZmZXIgPSBidWZmZXI7XG4gICAgICAgICAgICBjb25zdGFudC5sb29wID0gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnN0YW50LnN0YXJ0KDApO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRzLnNldCh2YWwsIGNvbnN0YW50KTtcbiAgICAgICAgICAgIHJldHVybiBjb25zdGFudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC4gQWxzbyBjbG9zZXMgdGhlIGF1ZGlvIGNvbnRleHQuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aWNrZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aW1lb3V0cy5kaXNwb3NlKCk7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuX2NvbnN0YW50cykubWFwKCh2YWwpID0+IHRoaXMuX2NvbnN0YW50c1t2YWxdLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFRJTUVPVVRTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJpdmF0ZSBsb29wIHdoaWNoIGtlZXBzIHRyYWNrIG9mIHRoZSBjb250ZXh0IHNjaGVkdWxlZCB0aW1lb3V0c1xuICAgICAqIElzIGludm9rZWQgZnJvbSB0aGUgY2xvY2sgc291cmNlXG4gICAgICovXG4gICAgX3RpbWVvdXRMb29wKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICBsZXQgZmlyc3RFdmVudCA9IHRoaXMuX3RpbWVvdXRzLnBlZWsoKTtcbiAgICAgICAgd2hpbGUgKHRoaXMuX3RpbWVvdXRzLmxlbmd0aCAmJiBmaXJzdEV2ZW50ICYmIGZpcnN0RXZlbnQudGltZSA8PSBub3cpIHtcbiAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIGZpcnN0RXZlbnQuY2FsbGJhY2soKTtcbiAgICAgICAgICAgIC8vIHNoaWZ0IHRoZSBmaXJzdCBldmVudCBvZmZcbiAgICAgICAgICAgIHRoaXMuX3RpbWVvdXRzLnNoaWZ0KCk7XG4gICAgICAgICAgICAvLyBnZXQgdGhlIG5leHQgb25lXG4gICAgICAgICAgICBmaXJzdEV2ZW50ID0gdGhpcy5fdGltZW91dHMucGVlaygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgc2V0VGltZW91dCB3aGljaCBpcyBndWFyYW50ZWVkIGJ5IHRoZSBjbG9jayBzb3VyY2UuXG4gICAgICogQWxzbyBydW5zIGluIHRoZSBvZmZsaW5lIGNvbnRleHQuXG4gICAgICogQHBhcmFtICBmbiAgICAgICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlXG4gICAgICogQHBhcmFtICB0aW1lb3V0ICBUaGUgdGltZW91dCBpbiBzZWNvbmRzXG4gICAgICogQHJldHVybnMgSUQgdG8gdXNlIHdoZW4gaW52b2tpbmcgQ29udGV4dC5jbGVhclRpbWVvdXRcbiAgICAgKi9cbiAgICBzZXRUaW1lb3V0KGZuLCB0aW1lb3V0KSB7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRJZHMrKztcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgdGhpcy5fdGltZW91dHMuYWRkKHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBmbixcbiAgICAgICAgICAgIGlkOiB0aGlzLl90aW1lb3V0SWRzLFxuICAgICAgICAgICAgdGltZTogbm93ICsgdGltZW91dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lb3V0SWRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhcnMgYSBwcmV2aW91c2x5IHNjaGVkdWxlZCB0aW1lb3V0IHdpdGggVG9uZS5jb250ZXh0LnNldFRpbWVvdXRcbiAgICAgKiBAcGFyYW0gIGlkICBUaGUgSUQgcmV0dXJuZWQgZnJvbSBzZXRUaW1lb3V0XG4gICAgICovXG4gICAgY2xlYXJUaW1lb3V0KGlkKSB7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRzLmZvckVhY2goKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuaWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGltZW91dHMucmVtb3ZlKGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhciB0aGUgZnVuY3Rpb24gc2NoZWR1bGVkIGJ5IFtbc2V0SW50ZXJ2YWxdXVxuICAgICAqL1xuICAgIGNsZWFySW50ZXJ2YWwoaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xlYXJUaW1lb3V0KGlkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkcyBhIHJlcGVhdGluZyBldmVudCB0byB0aGUgY29udGV4dCdzIGNhbGxiYWNrIGNsb2NrXG4gICAgICovXG4gICAgc2V0SW50ZXJ2YWwoZm4sIGludGVydmFsKSB7XG4gICAgICAgIGNvbnN0IGlkID0gKyt0aGlzLl90aW1lb3V0SWRzO1xuICAgICAgICBjb25zdCBpbnRlcnZhbEZuID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVvdXRzLmFkZCh7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICBmbigpO1xuICAgICAgICAgICAgICAgICAgICAvLyBpbnZva2UgdGhlIGV2ZW50IHRvIHJlcGVhdCBpdFxuICAgICAgICAgICAgICAgICAgICBpbnRlcnZhbEZuKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICB0aW1lOiBub3cgKyBpbnRlcnZhbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuICAgICAgICAvLyBraWNrIGl0IG9mZlxuICAgICAgICBpbnRlcnZhbEZuKCk7XG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db250ZXh0LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgQmFzZUNvbnRleHQgfSBmcm9tIFwiLi9CYXNlQ29udGV4dFwiO1xuZXhwb3J0IGNsYXNzIER1bW15Q29udGV4dCBleHRlbmRzIEJhc2VDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5sb29rQWhlYWQgPSAwO1xuICAgICAgICB0aGlzLmxhdGVuY3lIaW50ID0gMDtcbiAgICAgICAgdGhpcy5pc09mZmxpbmUgPSBmYWxzZTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBCQVNFIEFVRElPIENPTlRFWFQgTUVUSE9EU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgY3JlYXRlQW5hbHlzZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlT3NjaWxsYXRvcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXJTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQmlxdWFkRmlsdGVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlcihfbnVtYmVyT2ZDaGFubmVscywgX2xlbmd0aCwgX3NhbXBsZVJhdGUpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsTWVyZ2VyKF9udW1iZXJPZklucHV0cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxTcGxpdHRlcihfbnVtYmVyT2ZPdXRwdXRzKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ29uc3RhbnRTb3VyY2UoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ29udm9sdmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZURlbGF5KF9tYXhEZWxheVRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVJSVJGaWx0ZXIoX2ZlZWRGb3J3YXJkLCBfZmVlZGJhY2spIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVQYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlUGVyaW9kaWNXYXZlKF9yZWFsLCBfaW1hZywgX2NvbnN0cmFpbnRzKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlU3RlcmVvUGFubmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVdhdmVTaGFwZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UoX3N0cmVhbSkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShfZWxlbWVudCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZGVjb2RlQXVkaW9EYXRhKF9hdWRpb0RhdGEpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVE9ORSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUoX25hbWUsIF9vcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IHJhd0NvbnRleHQoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKF91cmwsIF9uYW1lKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXN1bWUoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgc2V0VGltZW91dChfZm4sIF90aW1lb3V0KSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjbGVhclRpbWVvdXQoX2lkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRJbnRlcnZhbChfZm4sIF9pbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgY2xlYXJJbnRlcnZhbChfaWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldENvbnN0YW50KF92YWwpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBnZXQgbGlzdGVuZXIoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IHRyYW5zcG9ydCgpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBnZXQgZHJhdygpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBzZXQgZHJhdyhfZCkgeyB9XG4gICAgZ2V0IGRlc3RpbmF0aW9uKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIHNldCBkZXN0aW5hdGlvbihfZCkgeyB9XG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaW1tZWRpYXRlKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EdW1teUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gXCIuL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBNYWtlIHRoZSBwcm9wZXJ0eSBub3Qgd3JpdGFibGUgdXNpbmcgYGRlZmluZVByb3BlcnR5YC4gSW50ZXJuYWwgdXNlIG9ubHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkT25seSh0YXJnZXQsIHByb3BlcnR5KSB7XG4gICAgaWYgKGlzQXJyYXkocHJvcGVydHkpKSB7XG4gICAgICAgIHByb3BlcnR5LmZvckVhY2goc3RyID0+IHJlYWRPbmx5KHRhcmdldCwgc3RyKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwge1xuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIGFuIGF0dHJpYnV0ZSB3cml0ZWFibGUuIEludGVybmFsIHVzZSBvbmx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGFibGUodGFyZ2V0LCBwcm9wZXJ0eSkge1xuICAgIGlmIChpc0FycmF5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm9wZXJ0eS5mb3JFYWNoKHN0ciA9PiB3cml0YWJsZSh0YXJnZXQsIHN0cikpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHtcbiAgICAgICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9XG59XG5leHBvcnQgY29uc3Qgbm9PcCA9ICgpID0+IHtcbiAgICAvLyBubyBvcGVyYXRpb24gaGVyZSFcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1JbnRlcmZhY2UuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc0F1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzTnVtYmVyLCBpc1N0cmluZyB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQXVkaW9CdWZmZXIgbG9hZGluZyBhbmQgc3RvcmFnZS4gVG9uZUF1ZGlvQnVmZmVyIGlzIHVzZWQgaW50ZXJuYWxseSBieSBhbGxcbiAqIGNsYXNzZXMgdGhhdCBtYWtlIHJlcXVlc3RzIGZvciBhdWRpbyBmaWxlcyBzdWNoIGFzIFRvbmUuUGxheWVyLFxuICogVG9uZS5TYW1wbGVyIGFuZCBUb25lLkNvbnZvbHZlci5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBidWZmZXIgPSBuZXcgVG9uZS5Ub25lQXVkaW9CdWZmZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vQTEubXAzXCIsICgpID0+IHtcbiAqIFx0Y29uc29sZS5sb2coXCJsb2FkZWRcIik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQXVkaW9CdWZmZXIgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9CdWZmZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcyBsb2FkZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9ubG9hZCA9IG5vT3A7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQXVkaW9CdWZmZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIiwgXCJvbmVycm9yXCJdKTtcbiAgICAgICAgdGhpcy5yZXZlcnNlID0gb3B0aW9ucy5yZXZlcnNlO1xuICAgICAgICB0aGlzLm9ubG9hZCA9IG9wdGlvbnMub25sb2FkO1xuICAgICAgICBpZiAob3B0aW9ucy51cmwgJiYgaXNBdWRpb0J1ZmZlcihvcHRpb25zLnVybCkgfHwgb3B0aW9ucy51cmwgaW5zdGFuY2VvZiBUb25lQXVkaW9CdWZmZXIpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0KG9wdGlvbnMudXJsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1N0cmluZyhvcHRpb25zLnVybCkpIHtcbiAgICAgICAgICAgIC8vIGluaXRpYXRlIHRoZSBkb3dubG9hZFxuICAgICAgICAgICAgdGhpcy5sb2FkKG9wdGlvbnMudXJsKS5jYXRjaChvcHRpb25zLm9uZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICByZXZlcnNlOiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNhbXBsZSByYXRlIG9mIHRoZSBBdWRpb0J1ZmZlclxuICAgICAqL1xuICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLnNhbXBsZVJhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0Q29udGV4dCgpLnNhbXBsZVJhdGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUGFzcyBpbiBhbiBBdWRpb0J1ZmZlciBvciBUb25lQXVkaW9CdWZmZXIgdG8gc2V0IHRoZSB2YWx1ZSBvZiB0aGlzIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBzZXQoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIgaW5zdGFuY2VvZiBUb25lQXVkaW9CdWZmZXIpIHtcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgbG9hZGVkLCBzZXQgaXRcbiAgICAgICAgICAgIGlmIChidWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYnVmZmVyID0gYnVmZmVyLmdldCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHdoZW4gaXQncyBsb2FkZWQsIGludm9rZSBpdCdzIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgYnVmZmVyLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXQoYnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbmxvYWQodGhpcyk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICAvLyByZXZlcnNlIGl0IGluaXRpYWxseVxuICAgICAgICBpZiAodGhpcy5fcmV2ZXJzZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGF1ZGlvIGJ1ZmZlciBzdG9yZWQgaW4gdGhlIG9iamVjdC5cbiAgICAgKi9cbiAgICBnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE1ha2VzIGFuIGZldGNoIHJlcXVlc3QgZm9yIHRoZSBzZWxlY3RlZCB1cmwgdGhlbiBkZWNvZGVzIHRoZSBmaWxlIGFzIGFuIGF1ZGlvIGJ1ZmZlci5cbiAgICAgKiBJbnZva2VzIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC4gZmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZSBicm93c2VyLlxuICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aXRoIHRoaXMgVG9uZUF1ZGlvQnVmZmVyXG4gICAgICovXG4gICAgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGRvbmVMb2FkaW5nID0gVG9uZUF1ZGlvQnVmZmVyLmxvYWQodXJsKS50aGVuKGF1ZGlvQnVmZmVyID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBvbmxvYWQgbWV0aG9kXG4gICAgICAgICAgICAgICAgdGhpcy5vbmxvYWQodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMucHVzaChkb25lTG9hZGluZyk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHlpZWxkIGRvbmVMb2FkaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZmluYWxseSB7XG4gICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBkb3dubG9hZGVkIGZpbGVcbiAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMuaW5kZXhPZihkb25lTG9hZGluZyk7XG4gICAgICAgICAgICAgICAgVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBhdWRpbyBidWZmZXIgZnJvbSB0aGUgYXJyYXkuXG4gICAgICogVG8gY3JlYXRlIGEgbXVsdGljaGFubmVsIEF1ZGlvQnVmZmVyLCBwYXNzIGluIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS5cbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwgdGhlIGF1ZGlvIGJ1ZmZlclxuICAgICAqL1xuICAgIGZyb21BcnJheShhcnJheSkge1xuICAgICAgICBjb25zdCBpc011bHRpZGltZW5zaW9uYWwgPSBpc0FycmF5KGFycmF5KSAmJiBhcnJheVswXS5sZW5ndGggPiAwO1xuICAgICAgICBjb25zdCBjaGFubmVscyA9IGlzTXVsdGlkaW1lbnNpb25hbCA/IGFycmF5Lmxlbmd0aCA6IDE7XG4gICAgICAgIGNvbnN0IGxlbiA9IGlzTXVsdGlkaW1lbnNpb25hbCA/IGFycmF5WzBdLmxlbmd0aCA6IGFycmF5Lmxlbmd0aDtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IGdldENvbnRleHQoKTtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gY29udGV4dC5jcmVhdGVCdWZmZXIoY2hhbm5lbHMsIGxlbiwgY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgbXVsdGlDaGFubmVsQXJyYXkgPSAhaXNNdWx0aWRpbWVuc2lvbmFsICYmIGNoYW5uZWxzID09PSAxID9cbiAgICAgICAgICAgIFthcnJheV0gOiBhcnJheTtcbiAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCBjaGFubmVsczsgYysrKSB7XG4gICAgICAgICAgICBidWZmZXIuY29weVRvQ2hhbm5lbChtdWx0aUNoYW5uZWxBcnJheVtjXSwgYyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3VtcyBtdWx0aXBsZSBjaGFubmVscyBpbnRvIDEgY2hhbm5lbFxuICAgICAqIEBwYXJhbSBjaGFuTnVtIE9wdGlvbmFsbHkgb25seSBjb3B5IGEgc2luZ2xlIGNoYW5uZWwgZnJvbSB0aGUgYXJyYXkuXG4gICAgICovXG4gICAgdG9Nb25vKGNoYW5OdW0pIHtcbiAgICAgICAgaWYgKGlzTnVtYmVyKGNoYW5OdW0pKSB7XG4gICAgICAgICAgICB0aGlzLmZyb21BcnJheSh0aGlzLnRvQXJyYXkoY2hhbk51bSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IG91dHB1dEFycmF5ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmxlbmd0aCk7XG4gICAgICAgICAgICBjb25zdCBudW1DaGFubmVscyA9IHRoaXMubnVtYmVyT2ZDaGFubmVscztcbiAgICAgICAgICAgIGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgbnVtQ2hhbm5lbHM7IGNoYW5uZWwrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxBcnJheSA9IHRoaXMudG9BcnJheShjaGFubmVsKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoYW5uZWxBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRBcnJheVtpXSArPSBjaGFubmVsQXJyYXlbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZGl2aWRlIGJ5IHRoZSBudW1iZXIgb2YgY2hhbm5lbHNcbiAgICAgICAgICAgIG91dHB1dEFycmF5ID0gb3V0cHV0QXJyYXkubWFwKHNhbXBsZSA9PiBzYW1wbGUgLyBudW1DaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLmZyb21BcnJheShvdXRwdXRBcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgYnVmZmVyIGFzIGFuIGFycmF5LiBTaW5nbGUgY2hhbm5lbCBidWZmZXJzIHdpbGwgcmV0dXJuIGEgMS1kaW1lbnNpb25hbFxuICAgICAqIEZsb2F0MzJBcnJheSwgYW5kIG11bHRpY2hhbm5lbCBidWZmZXJzIHdpbGwgcmV0dXJuIG11bHRpZGltZW5zaW9uYWwgYXJyYXlzLlxuICAgICAqIEBwYXJhbSBjaGFubmVsIE9wdGlvbmFsbHkgb25seSBjb3B5IGEgc2luZ2xlIGNoYW5uZWwgZnJvbSB0aGUgYXJyYXkuXG4gICAgICovXG4gICAgdG9BcnJheShjaGFubmVsKSB7XG4gICAgICAgIGlmIChpc051bWJlcihjaGFubmVsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5udW1iZXJPZkNoYW5uZWxzID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50b0FycmF5KDApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcmV0ID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgYysrKSB7XG4gICAgICAgICAgICAgICAgcmV0W2NdID0gdGhpcy5nZXRDaGFubmVsRGF0YShjKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgRmxvYXQzMkFycmF5IHJlcHJlc2VudGluZyB0aGUgUENNIGF1ZGlvIGRhdGEgZm9yIHRoZSBzcGVjaWZpYyBjaGFubmVsLlxuICAgICAqIEBwYXJhbSAgY2hhbm5lbCAgVGhlIGNoYW5uZWwgbnVtYmVyIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGF1ZGlvIGFzIGEgVHlwZWRBcnJheVxuICAgICAqL1xuICAgIGdldENoYW5uZWxEYXRhKGNoYW5uZWwpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRmxvYXQzMkFycmF5KDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEN1dCBhIHN1YnNlY3Rpb24gb2YgdGhlIGFycmF5IGFuZCByZXR1cm4gYSBidWZmZXIgb2YgdGhlXG4gICAgICogc3Vic2VjdGlvbi4gRG9lcyBub3QgbW9kaWZ5IHRoZSBvcmlnaW5hbCBidWZmZXJcbiAgICAgKiBAcGFyYW0gc3RhcnQgVGhlIHRpbWUgdG8gc3RhcnQgdGhlIHNsaWNlXG4gICAgICogQHBhcmFtIGVuZCBUaGUgZW5kIHRpbWUgdG8gc2xpY2UuIElmIG5vbmUgaXMgZ2l2ZW4gd2lsbCBkZWZhdWx0IHRvIHRoZSBlbmQgb2YgdGhlIGJ1ZmZlclxuICAgICAqL1xuICAgIHNsaWNlKHN0YXJ0LCBlbmQgPSB0aGlzLmR1cmF0aW9uKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0U2FtcGxlcyA9IE1hdGguZmxvb3Ioc3RhcnQgKiB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBlbmRTYW1wbGVzID0gTWF0aC5mbG9vcihlbmQgKiB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgICBhc3NlcnQoc3RhcnRTYW1wbGVzIDwgZW5kU2FtcGxlcywgXCJUaGUgc3RhcnQgdGltZSBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgZW5kIHRpbWVcIik7XG4gICAgICAgIGNvbnN0IGxlbmd0aCA9IGVuZFNhbXBsZXMgLSBzdGFydFNhbXBsZXM7XG4gICAgICAgIGNvbnN0IHJldEJ1ZmZlciA9IGdldENvbnRleHQoKS5jcmVhdGVCdWZmZXIodGhpcy5udW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5udW1iZXJPZkNoYW5uZWxzOyBjaGFubmVsKyspIHtcbiAgICAgICAgICAgIHJldEJ1ZmZlci5jb3B5VG9DaGFubmVsKHRoaXMuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCkuc3ViYXJyYXkoc3RhcnRTYW1wbGVzLCBlbmRTYW1wbGVzKSwgY2hhbm5lbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBUb25lQXVkaW9CdWZmZXIocmV0QnVmZmVyKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV2ZXJzZSB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIF9yZXZlcnNlKCkge1xuICAgICAgICBpZiAodGhpcy5sb2FkZWQpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5udW1iZXJPZkNoYW5uZWxzOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLmdldENoYW5uZWxEYXRhKGkpLnJldmVyc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBpcyBsb2FkZWQgb3Igbm90XG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoID4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIG9mIHRoZSBidWZmZXIgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICBnZXQgZHVyYXRpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuZHVyYXRpb247XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIgaW4gc2FtcGxlc1xuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkaXNjcmV0ZSBhdWRpbyBjaGFubmVscy4gUmV0dXJucyAwIGlmIG5vIGJ1ZmZlciBpcyBsb2FkZWQuXG4gICAgICovXG4gICAgZ2V0IG51bWJlck9mQ2hhbm5lbHMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldmVyc2UgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBnZXQgcmV2ZXJzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JldmVyc2VkO1xuICAgIH1cbiAgICBzZXQgcmV2ZXJzZShyZXYpIHtcbiAgICAgICAgaWYgKHRoaXMuX3JldmVyc2VkICE9PSByZXYpIHtcbiAgICAgICAgICAgIHRoaXMuX3JldmVyc2VkID0gcmV2O1xuICAgICAgICAgICAgdGhpcy5fcmV2ZXJzZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIFRvbmVBdWRpb0J1ZmZlciBmcm9tIHRoZSBhcnJheS4gVG8gY3JlYXRlIGEgbXVsdGljaGFubmVsIEF1ZGlvQnVmZmVyLFxuICAgICAqIHBhc3MgaW4gYSBtdWx0aWRpbWVuc2lvbmFsIGFycmF5LlxuICAgICAqIEBwYXJhbSBhcnJheSBUaGUgYXJyYXkgdG8gZmlsbCB0aGUgYXVkaW8gYnVmZmVyXG4gICAgICogQHJldHVybiBBIFRvbmVBdWRpb0J1ZmZlciBjcmVhdGVkIGZyb20gdGhlIGFycmF5XG4gICAgICovXG4gICAgc3RhdGljIGZyb21BcnJheShhcnJheSkge1xuICAgICAgICByZXR1cm4gKG5ldyBUb25lQXVkaW9CdWZmZXIoKSkuZnJvbUFycmF5KGFycmF5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFRvbmVBdWRpb0J1ZmZlciBmcm9tIGEgVVJMLCByZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byBhIFRvbmVBdWRpb0J1ZmZlclxuICAgICAqIEBwYXJhbSAgdXJsIFRoZSB1cmwgdG8gbG9hZC5cbiAgICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB3aGljaCByZXNvbHZlcyB0byBhIFRvbmVBdWRpb0J1ZmZlclxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tVXJsKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpO1xuICAgICAgICAgICAgcmV0dXJuIHlpZWxkIGJ1ZmZlci5sb2FkKHVybCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2FkcyBhIHVybCB1c2luZyBmZXRjaCBhbmQgcmV0dXJucyB0aGUgQXVkaW9CdWZmZXIuXG4gICAgICovXG4gICAgc3RhdGljIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAvLyB0ZXN0IGlmIHRoZSB1cmwgY29udGFpbnMgbXVsdGlwbGUgZXh0ZW5zaW9uc1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IHVybC5tYXRjaCgvXFxbKFteXFxdXFxbXStcXHwuKylcXF0kLyk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlcykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBtYXRjaGVzWzFdLnNwbGl0KFwifFwiKTtcbiAgICAgICAgICAgICAgICBsZXQgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1swXTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGV4dCBvZiBleHRlbnNpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChUb25lQXVkaW9CdWZmZXIuc3VwcG9ydHNUeXBlKGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbiA9IGV4dDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHVybCA9IHVybC5yZXBsYWNlKG1hdGNoZXNbMF0sIGV4dGVuc2lvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlcmUgaXMgYSBzbGFzaCBiZXR3ZWVuIHRoZSBiYXNlVXJsIGFuZCB0aGUgdXJsXG4gICAgICAgICAgICBjb25zdCBiYXNlVXJsID0gVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgPT09IFwiXCIgfHwgVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwuZW5kc1dpdGgoXCIvXCIpID8gVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgOiBUb25lQXVkaW9CdWZmZXIuYmFzZVVybCArIFwiL1wiO1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB5aWVsZCBmZXRjaChiYXNlVXJsICsgdXJsKTtcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGNvdWxkIG5vdCBsb2FkIHVybDogJHt1cmx9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IHlpZWxkIHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlciA9IHlpZWxkIGdldENvbnRleHQoKS5kZWNvZGVBdWRpb0RhdGEoYXJyYXlCdWZmZXIpO1xuICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGEgdXJsJ3MgZXh0ZW5zaW9uIHRvIHNlZSBpZiB0aGUgY3VycmVudCBicm93c2VyIGNhbiBwbGF5IHRoYXQgZmlsZSB0eXBlLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybC9leHRlbnNpb24gdG8gdGVzdFxuICAgICAqIEByZXR1cm4gSWYgdGhlIGZpbGUgZXh0ZW5zaW9uIGNhbiBiZSBwbGF5ZWRcbiAgICAgKiBAc3RhdGljXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRvbmVBdWRpb0J1ZmZlci5zdXBwb3J0c1R5cGUoXCJ3YXZcIik7IC8vIHJldHVybnMgdHJ1ZVxuICAgICAqIFRvbmUuVG9uZUF1ZGlvQnVmZmVyLnN1cHBvcnRzVHlwZShcInBhdGgvdG8vZmlsZS53YXZcIik7IC8vIHJldHVybnMgdHJ1ZVxuICAgICAqL1xuICAgIHN0YXRpYyBzdXBwb3J0c1R5cGUodXJsKSB7XG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbnMgPSB1cmwuc3BsaXQoXCIuXCIpO1xuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBleHRlbnNpb25zW2V4dGVuc2lvbnMubGVuZ3RoIC0gMV07XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImF1ZGlvXCIpLmNhblBsYXlUeXBlKFwiYXVkaW8vXCIgKyBleHRlbnNpb24pO1xuICAgICAgICByZXR1cm4gcmVzcG9uc2UgIT09IFwiXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBQcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gYWxsIG9mIHRoZSBidWZmZXJzIGhhdmUgbG9hZGVkXG4gICAgICovXG4gICAgc3RhdGljIGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgbWFrZXMgc3VyZSB0aGF0IHRoZSBmdW5jdGlvbiBpcyBhbHdheXMgYXN5bmNcbiAgICAgICAgICAgIHlpZWxkIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgd2hpbGUgKFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgeWllbGQgVG9uZUF1ZGlvQnVmZmVyLmRvd25sb2Fkc1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTVEFUSUMgTUVUSE9EU1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIEEgcGF0aCB3aGljaCBpcyBwcmVmaXhlZCBiZWZvcmUgZXZlcnkgdXJsLlxuICovXG5Ub25lQXVkaW9CdWZmZXIuYmFzZVVybCA9IFwiXCI7XG4vKipcbiAqIEFsbCBvZiB0aGUgZG93bmxvYWRzXG4gKi9cblRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMgPSBbXTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb0J1ZmZlci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Db250ZXh0XCI7XG5pbXBvcnQgeyBpc09mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4vVG9uZUF1ZGlvQnVmZmVyXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBPZmZsaW5lQXVkaW9Db250ZXh0XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICogQGV4YW1wbGVcbiAqIC8vIGdlbmVyYXRlIGEgc2luZ2xlIGNoYW5uZWwsIDAuNSBzZWNvbmQgYnVmZmVyXG4gKiBjb25zdCBjb250ZXh0ID0gbmV3IFRvbmUuT2ZmbGluZUNvbnRleHQoMSwgMC41LCA0NDEwMCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKHsgY29udGV4dCB9KTtcbiAqIGNvbnRleHQucmVuZGVyKCkudGhlbihidWZmZXIgPT4ge1xuICogXHRjb25zb2xlLmxvZyhidWZmZXIubnVtYmVyT2ZDaGFubmVscywgYnVmZmVyLmR1cmF0aW9uKTtcbiAqIH0pO1xuICovXG5leHBvcnQgY2xhc3MgT2ZmbGluZUNvbnRleHQgZXh0ZW5kcyBDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoe1xuICAgICAgICAgICAgY2xvY2tTb3VyY2U6IFwib2ZmbGluZVwiLFxuICAgICAgICAgICAgY29udGV4dDogaXNPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSkgP1xuICAgICAgICAgICAgICAgIGFyZ3VtZW50c1swXSA6IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdLCBhcmd1bWVudHNbMV0gKiBhcmd1bWVudHNbMl0sIGFyZ3VtZW50c1syXSksXG4gICAgICAgICAgICBsb29rQWhlYWQ6IDAsXG4gICAgICAgICAgICB1cGRhdGVJbnRlcnZhbDogaXNPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSkgP1xuICAgICAgICAgICAgICAgIDEyOCAvIGFyZ3VtZW50c1swXS5zYW1wbGVSYXRlIDogMTI4IC8gYXJndW1lbnRzWzJdLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPZmZsaW5lQ29udGV4dFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogQW4gYXJ0aWZpY2lhbCBjbG9jayBzb3VyY2VcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2N1cnJlbnRUaW1lID0gMDtcbiAgICAgICAgdGhpcy5pc09mZmxpbmUgPSB0cnVlO1xuICAgICAgICB0aGlzLl9kdXJhdGlvbiA9IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgIGFyZ3VtZW50c1swXS5sZW5ndGggLyBhcmd1bWVudHNbMF0uc2FtcGxlUmF0ZSA6IGFyZ3VtZW50c1sxXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgdGhlIG5vdyBtZXRob2QgdG8gcG9pbnQgdG8gdGhlIGludGVybmFsIGNsb2NrIHRpbWVcbiAgICAgKi9cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2FtZSBhcyB0aGlzLm5vdygpXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciBqdXN0IHRoZSBjbG9jayBwb3J0aW9uIG9mIHRoZSBhdWRpbyBjb250ZXh0LlxuICAgICAqL1xuICAgIF9yZW5kZXJDbG9jayhhc3luY2hyb25vdXMpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGxldCBpbmRleCA9IDA7XG4gICAgICAgICAgICB3aGlsZSAodGhpcy5fZHVyYXRpb24gLSB0aGlzLl9jdXJyZW50VGltZSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gaW52b2tlIGFsbCB0aGUgY2FsbGJhY2tzIG9uIHRoYXQgdGltZVxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInRpY2tcIik7XG4gICAgICAgICAgICAgICAgLy8gaW5jcmVtZW50IHRoZSBjbG9jayBpbiBibG9jay1zaXplZCBjaHVua3NcbiAgICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50VGltZSArPSAxMjggLyB0aGlzLnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgLy8geWllbGQgb25jZSBhIHNlY29uZCBvZiBhdWRpb1xuICAgICAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICAgICAgY29uc3QgeWllbGRFdmVyeSA9IE1hdGguZmxvb3IodGhpcy5zYW1wbGVSYXRlIC8gMTI4KTtcbiAgICAgICAgICAgICAgICBpZiAoYXN5bmNocm9ub3VzICYmIGluZGV4ICUgeWllbGRFdmVyeSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB5aWVsZCBuZXcgUHJvbWlzZShkb25lID0+IHNldFRpbWVvdXQoZG9uZSwgMSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbmRlciB0aGUgb3V0cHV0IG9mIHRoZSBPZmZsaW5lQ29udGV4dFxuICAgICAqIEBwYXJhbSBhc3luY2hyb25vdXMgSWYgdGhlIGNsb2NrIHNob3VsZCBiZSByZW5kZXJlZCBhc3luY2hyb25vdXNseSwgd2hpY2ggd2lsbCBub3QgYmxvY2sgdGhlIG1haW4gdGhyZWFkLCBidXQgYmUgc2xpZ2h0bHkgc2xvd2VyLlxuICAgICAqL1xuICAgIHJlbmRlcihhc3luY2hyb25vdXMgPSB0cnVlKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLndvcmtsZXRzQXJlUmVhZHkoKTtcbiAgICAgICAgICAgIHlpZWxkIHRoaXMuX3JlbmRlckNsb2NrKGFzeW5jaHJvbm91cyk7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCB0aGlzLl9jb250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFRvbmVBdWRpb0J1ZmZlcihidWZmZXIpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xvc2UgdGhlIGNvbnRleHRcbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9mZmxpbmVDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IHZlcnNpb24gfSBmcm9tIFwiLi4vdmVyc2lvblwiO1xuaW1wb3J0IHsgaGFzQXVkaW9Db250ZXh0LCB0aGVXaW5kb3cgfSBmcm9tIFwiLi9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvQ29udGV4dFwiO1xuaW1wb3J0IHsgRHVtbXlDb250ZXh0IH0gZnJvbSBcIi4vY29udGV4dC9EdW1teUNvbnRleHRcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4vY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgaXNBdWRpb0NvbnRleHQsIGlzT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gXCIuL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbi8qKlxuICogVGhpcyBkdW1teSBjb250ZXh0IGlzIHVzZWQgdG8gYXZvaWQgdGhyb3dpbmcgaW1tZWRpYXRlIGVycm9ycyB3aGVuIGltcG9ydGluZyBpbiBOb2RlLmpzXG4gKi9cbmNvbnN0IGR1bW15Q29udGV4dCA9IG5ldyBEdW1teUNvbnRleHQoKTtcbi8qKlxuICogVGhlIGdsb2JhbCBhdWRpbyBjb250ZXh0IHdoaWNoIGlzIGdldGFibGUgYW5kIGFzc2lnbmFibGUgdGhyb3VnaFxuICogZ2V0Q29udGV4dCBhbmQgc2V0Q29udGV4dFxuICovXG5sZXQgZ2xvYmFsQ29udGV4dCA9IGR1bW15Q29udGV4dDtcbi8qKlxuICogUmV0dXJucyB0aGUgZGVmYXVsdCBzeXN0ZW0td2lkZSBbW0NvbnRleHRdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENvbnRleHQoKSB7XG4gICAgaWYgKGdsb2JhbENvbnRleHQgPT09IGR1bW15Q29udGV4dCAmJiBoYXNBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgc2V0Q29udGV4dChuZXcgQ29udGV4dCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGdsb2JhbENvbnRleHQ7XG59XG4vKipcbiAqIFNldCB0aGUgZGVmYXVsdCBhdWRpbyBjb250ZXh0XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0Q29udGV4dChjb250ZXh0KSB7XG4gICAgaWYgKGlzQXVkaW9Db250ZXh0KGNvbnRleHQpKSB7XG4gICAgICAgIGdsb2JhbENvbnRleHQgPSBuZXcgQ29udGV4dChjb250ZXh0KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNPZmZsaW5lQXVkaW9Db250ZXh0KGNvbnRleHQpKSB7XG4gICAgICAgIGdsb2JhbENvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoY29udGV4dCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gY29udGV4dDtcbiAgICB9XG59XG4vKipcbiAqIE1vc3QgYnJvd3NlcnMgd2lsbCBub3QgcGxheSBfYW55XyBhdWRpbyB1bnRpbCBhIHVzZXJcbiAqIGNsaWNrcyBzb21ldGhpbmcgKGxpa2UgYSBwbGF5IGJ1dHRvbikuIEludm9rZSB0aGlzIG1ldGhvZFxuICogb24gYSBjbGljayBvciBrZXlwcmVzcyBldmVudCBoYW5kbGVyIHRvIHN0YXJ0IHRoZSBhdWRpbyBjb250ZXh0LlxuICogTW9yZSBhYm91dCB0aGUgQXV0b3BsYXkgcG9saWN5XG4gKiBbaGVyZV0oaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vd2ViL3VwZGF0ZXMvMjAxNy8wOS9hdXRvcGxheS1wb2xpY3ktY2hhbmdlcyN3ZWJhdWRpbylcbiAqIEBleGFtcGxlXG4gKiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYnV0dG9uXCIpLmFkZEV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBhc3luYyAoKSA9PiB7XG4gKiBcdGF3YWl0IFRvbmUuc3RhcnQoKTtcbiAqIFx0Y29uc29sZS5sb2coXCJjb250ZXh0IHN0YXJ0ZWRcIik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFydCgpIHtcbiAgICByZXR1cm4gZ2xvYmFsQ29udGV4dC5yZXN1bWUoKTtcbn1cbi8qKlxuICogTG9nIFRvbmUuanMgKyB2ZXJzaW9uIGluIHRoZSBjb25zb2xlLlxuICovXG5pZiAodGhlV2luZG93ICYmICF0aGVXaW5kb3cuVE9ORV9TSUxFTkNFX0xPR0dJTkcpIHtcbiAgICBsZXQgcHJlZml4ID0gXCJ2XCI7XG4gICAgaWYgKHZlcnNpb24gPT09IFwiZGV2XCIpIHtcbiAgICAgICAgcHJlZml4ID0gXCJcIjtcbiAgICB9XG4gICAgY29uc3QgcHJpbnRTdHJpbmcgPSBgICogVG9uZS5qcyAke3ByZWZpeH0ke3ZlcnNpb259ICogYDtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgIGNvbnNvbGUubG9nKGAlYyR7cHJpbnRTdHJpbmd9YCwgXCJiYWNrZ3JvdW5kOiAjMDAwOyBjb2xvcjogI2ZmZlwiKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdsb2JhbC5qcy5tYXAiLCIvKipcbiAqIEVxdWFsIHBvd2VyIGdhaW4gc2NhbGUuIEdvb2QgZm9yIGNyb3NzLWZhZGluZy5cbiAqIEBwYXJhbSAgcGVyY2VudCAoMC0xKVxuICovXG5leHBvcnQgZnVuY3Rpb24gZXF1YWxQb3dlclNjYWxlKHBlcmNlbnQpIHtcbiAgICBjb25zdCBwaUZhY3RvciA9IDAuNSAqIE1hdGguUEk7XG4gICAgcmV0dXJuIE1hdGguc2luKHBlcmNlbnQgKiBwaUZhY3Rvcik7XG59XG4vKipcbiAqIENvbnZlcnQgZGVjaWJlbHMgaW50byBnYWluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGJUb0dhaW4oZGIpIHtcbiAgICByZXR1cm4gTWF0aC5wb3coMTAsIGRiIC8gMjApO1xufVxuLyoqXG4gKiBDb252ZXJ0IGdhaW4gdG8gZGVjaWJlbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnYWluVG9EYihnYWluKSB7XG4gICAgcmV0dXJuIDIwICogKE1hdGgubG9nKGdhaW4pIC8gTWF0aC5MTjEwKTtcbn1cbi8qKlxuICogQ29udmVydCBhbiBpbnRlcnZhbCAoaW4gc2VtaXRvbmVzKSB0byBhIGZyZXF1ZW5jeSByYXRpby5cbiAqIEBwYXJhbSBpbnRlcnZhbCB0aGUgbnVtYmVyIG9mIHNlbWl0b25lcyBhYm92ZSB0aGUgYmFzZSBub3RlXG4gKiBAZXhhbXBsZVxuICogVG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oMCk7IC8vIDFcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKDEyKTsgLy8gMlxuICogVG9uZS5pbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oLTEyKTsgLy8gMC41XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwpIHtcbiAgICByZXR1cm4gTWF0aC5wb3coMiwgKGludGVydmFsIC8gMTIpKTtcbn1cbi8qKlxuICogVGhlIEdsb2JhbCBbY29uY2VydCB0dW5pbmcgcGl0Y2hdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbmNlcnRfcGl0Y2gpIHdoaWNoIGlzIHVzZWRcbiAqIHRvIGdlbmVyYXRlIGFsbCB0aGUgb3RoZXIgcGl0Y2ggdmFsdWVzIGZyb20gbm90ZXMuIEE0J3MgdmFsdWVzIGluIEhlcnR6LlxuICovXG5sZXQgQTQgPSA0NDA7XG5leHBvcnQgZnVuY3Rpb24gZ2V0QTQoKSB7XG4gICAgcmV0dXJuIEE0O1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNldEE0KGZyZXEpIHtcbiAgICBBNCA9IGZyZXE7XG59XG4vKipcbiAqIENvbnZlcnQgYSBmcmVxdWVuY3kgdmFsdWUgdG8gYSBNSURJIG5vdGUuXG4gKiBAcGFyYW0gZnJlcXVlbmN5IFRoZSB2YWx1ZSB0byBmcmVxdWVuY3kgdmFsdWUgdG8gY29udmVydC5cbiAqIEBleGFtcGxlXG4gKiBUb25lLmZ0b20oNDQwKTsgLy8gcmV0dXJucyA2OVxuICovXG5leHBvcnQgZnVuY3Rpb24gZnRvbShmcmVxdWVuY3kpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChmdG9tZihmcmVxdWVuY3kpKTtcbn1cbi8qKlxuICogQ29udmVydCBhIGZyZXF1ZW5jeSB0byBhIGZsb2F0aW5nIHBvaW50IG1pZGkgdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZ0b21mKGZyZXF1ZW5jeSkge1xuICAgIHJldHVybiA2OSArIDEyICogTWF0aC5sb2cyKGZyZXF1ZW5jeSAvIEE0KTtcbn1cbi8qKlxuICogQ29udmVydCBhIE1JREkgbm90ZSB0byBmcmVxdWVuY3kgdmFsdWUuXG4gKiBAcGFyYW0gIG1pZGkgVGhlIG1pZGkgbnVtYmVyIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJuIFRoZSBjb3JyZXNwb25kaW5nIGZyZXF1ZW5jeSB2YWx1ZVxuICogQGV4YW1wbGVcbiAqIFRvbmUubXRvZig2OSk7IC8vIDQ0MFxuICovXG5leHBvcnQgZnVuY3Rpb24gbXRvZihtaWRpKSB7XG4gICAgcmV0dXJuIEE0ICogTWF0aC5wb3coMiwgKG1pZGkgLSA2OSkgLyAxMik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db252ZXJzaW9ucy5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNPYmplY3QsIGlzU3RyaW5nLCBpc1VuZGVmIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRpbWVCYXNlIGlzIGEgZmxleGlibGUgZW5jb2Rpbmcgb2YgdGltZSB3aGljaCBjYW4gYmUgZXZhbHVhdGVkIHRvIGFuZCBmcm9tIGEgc3RyaW5nLlxuICovXG5leHBvcnQgY2xhc3MgVGltZUJhc2VDbGFzcyBleHRlbmRzIFRvbmUge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IGFzc29jaWF0ZWQgd2l0aCB0aGUgdGltZSB2YWx1ZS4gVXNlZCB0byBjb21wdXRlXG4gICAgICogVHJhbnNwb3J0IGFuZCBjb250ZXh0LXJlbGF0aXZlIHRpbWluZy5cbiAgICAgKiBAcGFyYW0gIHZhbHVlICBUaGUgdGltZSB2YWx1ZSBhcyBhIG51bWJlciwgc3RyaW5nIG9yIG9iamVjdFxuICAgICAqIEBwYXJhbSAgdW5pdHMgIFVuaXQgdmFsdWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoY29udGV4dCwgdmFsdWUsIHVuaXRzKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZGVmYXVsdCB1bml0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcInNcIjtcbiAgICAgICAgdGhpcy5fdmFsID0gdmFsdWU7XG4gICAgICAgIHRoaXMuX3VuaXRzID0gdW5pdHM7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuX2V4cHJlc3Npb25zID0gdGhpcy5fZ2V0RXhwcmVzc2lvbnMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWxsIG9mIHRoZSB0aW1lIGVuY29kaW5nIGV4cHJlc3Npb25zXG4gICAgICovXG4gICAgX2dldEV4cHJlc3Npb25zKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaHo6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5VG9Vbml0cyhwYXJzZUZsb2F0KHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8paHokL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaToge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl90aWNrc1RvVW5pdHMocGFyc2VJbnQodmFsdWUsIDEwKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspaSQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUludCh2YWx1ZSwgMTApICogdGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyltJC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG46IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSwgZG90KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHBhcnNlSW50KHZhbHVlLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNjYWxhciA9IGRvdCA9PT0gXCIuXCIgPyAxLjUgOiAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAobnVtZXJpY1ZhbHVlID09PSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSkgKiBzY2FsYXI7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmVhdHNUb1VuaXRzKDQgLyBudW1lcmljVmFsdWUpICogc2NhbGFyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspbihcXC4/KSQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBudW1iZXI6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZXhwcmVzc2lvbnNbdGhpcy5kZWZhdWx0VW5pdHNdLm1ldGhvZC5jYWxsKHRoaXMsIHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPykkLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NlY29uZHNUb1VuaXRzKHBhcnNlRmxvYXQodmFsdWUpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPylzJC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2FtcGxlczoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludCh2YWx1ZSwgMTApIC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspc2FtcGxlcyQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHQ6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmVhdHNUb1VuaXRzKDggLyAoTWF0aC5mbG9vcihudW1lcmljVmFsdWUpICogMykpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKXQkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHI6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6IChtLCBxLCBzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtICYmIG0gIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHModGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpICogcGFyc2VGbG9hdChtKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHEgJiYgcSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocyAmJiBzICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocykgLyA0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG90YWw7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pOihcXGQrKD86XFwuXFxkKyk/KTo/KFxcZCsoPzpcXC5cXGQrKT8pPyQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRWQUxVRSBPRlxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEV2YWx1YXRlIHRoZSB0aW1lIHZhbHVlLiBSZXR1cm5zIHRoZSB0aW1lIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgdmFsdWVPZigpIHtcbiAgICAgICAgaWYgKHRoaXMuX3ZhbCBpbnN0YW5jZW9mIFRpbWVCYXNlQ2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuZnJvbVR5cGUodGhpcy5fdmFsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNVbmRlZih0aGlzLl92YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbm9BcmcoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc1N0cmluZyh0aGlzLl92YWwpICYmIGlzVW5kZWYodGhpcy5fdW5pdHMpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHVuaXRzIGluIHRoaXMuX2V4cHJlc3Npb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2V4cHJlc3Npb25zW3VuaXRzXS5yZWdleHAudGVzdCh0aGlzLl92YWwudHJpbSgpKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl91bml0cyA9IHVuaXRzO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fdmFsKSkge1xuICAgICAgICAgICAgbGV0IHRvdGFsID0gMDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdHlwZU5hbWUgaW4gdGhpcy5fdmFsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl92YWxbdHlwZU5hbWVdKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudGl0eSA9IHRoaXMuX3ZhbFt0eXBlTmFtZV07XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGltZSA9IChuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0aGlzLmNvbnRleHQsIHR5cGVOYW1lKSkudmFsdWVPZigpICogcXVhbnRpdHk7XG4gICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRpbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fdW5pdHMpKSB7XG4gICAgICAgICAgICBjb25zdCBleHByID0gdGhpcy5fZXhwcmVzc2lvbnNbdGhpcy5fdW5pdHNdO1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hpbmcgPSB0aGlzLl92YWwudG9TdHJpbmcoKS50cmltKCkubWF0Y2goZXhwci5yZWdleHApO1xuICAgICAgICAgICAgaWYgKG1hdGNoaW5nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4cHIubWV0aG9kLmFwcGx5KHRoaXMsIG1hdGNoaW5nLnNsaWNlKDEpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBleHByLm1ldGhvZC5jYWxsKHRoaXMsIHRoaXMuX3ZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcodGhpcy5fdmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodGhpcy5fdmFsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl92YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRVTklUIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBmcmVxdWVuY3kgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSB7XG4gICAgICAgIHJldHVybiAxIC8gZnJlcTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiAoNjAgLyB0aGlzLl9nZXRCcG0oKSkgKiBiZWF0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gc2Vjb25kcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiAodGlja3MgKiAodGhpcy5fYmVhdHNUb1VuaXRzKDEpKSAvIHRoaXMuX2dldFBQUSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2l0aCBubyBhcmd1bWVudHMsIHJldHVybiAnbm93J1xuICAgICAqL1xuICAgIF9ub0FyZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25vdygpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFRFTVBPIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBicG1cbiAgICAgKi9cbiAgICBfZ2V0QnBtKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5icG0udmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZVNpZ25hdHVyZVxuICAgICAqL1xuICAgIF9nZXRUaW1lU2lnbmF0dXJlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aW1lU2lnbmF0dXJlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIFBQUSBvciAxOTIgaWYgVHJhbnNwb3J0IGlzIG5vdCBhdmFpbGFibGVcbiAgICAgKi9cbiAgICBfZ2V0UFBRKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5QUFE7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0Q09OVkVSU0lPTiBJTlRFUkZBQ0VcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBDb2VyY2UgYSB0aW1lIHR5cGUgaW50byB0aGlzIHVuaXRzIHR5cGUuXG4gICAgICogQHBhcmFtIHR5cGUgQW55IHRpbWUgdHlwZSB1bml0c1xuICAgICAqL1xuICAgIGZyb21UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdW5pdHMgPSB1bmRlZmluZWQ7XG4gICAgICAgIHN3aXRjaCAodGhpcy5kZWZhdWx0VW5pdHMpIHtcbiAgICAgICAgICAgIGNhc2UgXCJzXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgXCJpXCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b1RpY2tzKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiaHpcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvRnJlcXVlbmN5KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwibWlkaVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9NaWRpKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgaW4gaGVydHpcbiAgICAgKi9cbiAgICB0b0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIDEgLyB0aGlzLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gc2FtcGxlc1xuICAgICAqL1xuICAgIHRvU2FtcGxlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9TZWNvbmRzKCkgKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIG1pbGxpc2Vjb25kcy5cbiAgICAgKi9cbiAgICB0b01pbGxpc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9TZWNvbmRzKCkgKiAxMDAwO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpbWVCYXNlLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBmdG9tIH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IFRpbWVCYXNlQ2xhc3MgfSBmcm9tIFwiLi9UaW1lQmFzZVwiO1xuLyoqXG4gKiBUaW1lQ2xhc3MgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgYW5kIGRlY29kaW5nIFRpbWUgdmFsdWVzLlxuICogVGltZUNsYXNzIGNhbiBiZSBwYXNzZWQgaW50byB0aGUgcGFyYW1ldGVyIG9mIGFueSBtZXRob2Qgd2hpY2ggdGFrZXMgdGltZSBhcyBhbiBhcmd1bWVudC5cbiAqIEBwYXJhbSAgdmFsICAgIFRoZSB0aW1lIHZhbHVlLlxuICogQHBhcmFtICB1bml0cyAgVGhlIHVuaXRzIG9mIHRoZSB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCB0aW1lID0gVG9uZS5UaW1lKFwiNG5cIik7IC8vIGEgcXVhcnRlciBub3RlXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgY2xhc3MgVGltZUNsYXNzIGV4dGVuZHMgVGltZUJhc2VDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVGltZUNsYXNzXCI7XG4gICAgfVxuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oc3VwZXIuX2dldEV4cHJlc3Npb25zKCksIHtcbiAgICAgICAgICAgIG5vdzoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKGNhcHR1cmUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25vdygpICsgbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5jb250ZXh0LCBjYXB0dXJlKS52YWx1ZU9mKCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eXFwrKC4rKS8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcXVhbnRpemU6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6IChjYXB0dXJlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHF1YW50VG8gPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgY2FwdHVyZSkudmFsdWVPZigpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc2Vjb25kc1RvVW5pdHModGhpcy5jb250ZXh0LnRyYW5zcG9ydC5uZXh0U3ViZGl2aXNpb24ocXVhbnRUbykpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXkAoLispLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBRdWFudGl6ZSB0aGUgdGltZSBieSB0aGUgZ2l2ZW4gc3ViZGl2aXNpb24uIE9wdGlvbmFsbHkgYWRkIGFcbiAgICAgKiBwZXJjZW50YWdlIHdoaWNoIHdpbGwgbW92ZSB0aGUgdGltZSB2YWx1ZSB0b3dhcmRzIHRoZSBpZGVhbFxuICAgICAqIHF1YW50aXplZCB2YWx1ZSBieSB0aGF0IHBlcmNlbnRhZ2UuXG4gICAgICogQHBhcmFtICBzdWJkaXYgICAgVGhlIHN1YmRpdmlzaW9uIHRvIHF1YW50aXplIHRvXG4gICAgICogQHBhcmFtICBwZXJjZW50ICBNb3ZlIHRoZSB0aW1lIHZhbHVlIHRvd2FyZHMgdGhlIHF1YW50aXplZCB2YWx1ZSBieSBhIHBlcmNlbnRhZ2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRpbWUoMjEpLnF1YW50aXplKDIpOyAvLyByZXR1cm5zIDIyXG4gICAgICogVG9uZS5UaW1lKDAuNikucXVhbnRpemUoXCI0blwiLCAwLjUpOyAvLyByZXR1cm5zIDAuNTVcbiAgICAgKi9cbiAgICBxdWFudGl6ZShzdWJkaXYsIHBlcmNlbnQgPSAxKSB7XG4gICAgICAgIGNvbnN0IHN1YmRpdmlzaW9uID0gbmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5jb250ZXh0LCBzdWJkaXYpLnZhbHVlT2YoKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnZhbHVlT2YoKTtcbiAgICAgICAgY29uc3QgbXVsdGlwbGUgPSBNYXRoLnJvdW5kKHZhbHVlIC8gc3ViZGl2aXNpb24pO1xuICAgICAgICBjb25zdCBpZGVhbCA9IG11bHRpcGxlICogc3ViZGl2aXNpb247XG4gICAgICAgIGNvbnN0IGRpZmYgPSBpZGVhbCAtIHZhbHVlO1xuICAgICAgICByZXR1cm4gdmFsdWUgKyBkaWZmICogcGVyY2VudDtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQ09OVkVSU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgVGltZSB0byBOb3RhdGlvbi4gVGhlIG5vdGF0aW9uIHZhbHVlcyBhcmUgd2lsbCBiZSB0aGVcbiAgICAgKiBjbG9zZXN0IHJlcHJlc2VudGF0aW9uIGJldHdlZW4gMW0gdG8gMTI4dGggbm90ZS5cbiAgICAgKiBAcmV0dXJuIHtOb3RhdGlvbn1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGlmIHRoZSBUcmFuc3BvcnQgaXMgYXQgMTIwYnBtOlxuICAgICAqIFRvbmUuVGltZSgyKS50b05vdGF0aW9uKCk7IC8vIHJldHVybnMgXCIxbVwiXG4gICAgICovXG4gICAgdG9Ob3RhdGlvbigpIHtcbiAgICAgICAgY29uc3QgdGltZSA9IHRoaXMudG9TZWNvbmRzKCk7XG4gICAgICAgIGNvbnN0IHRlc3ROb3RhdGlvbnMgPSBbXCIxbVwiXTtcbiAgICAgICAgZm9yIChsZXQgcG93ZXIgPSAxOyBwb3dlciA8IDk7IHBvd2VyKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHN1YmRpdiA9IE1hdGgucG93KDIsIHBvd2VyKTtcbiAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyBcIm4uXCIpO1xuICAgICAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKHN1YmRpdiArIFwiblwiKTtcbiAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyBcInRcIik7XG4gICAgICAgIH1cbiAgICAgICAgdGVzdE5vdGF0aW9ucy5wdXNoKFwiMFwiKTtcbiAgICAgICAgLy8gZmluZCB0aGUgY2xvc2V0cyBub3RhdGlvbiByZXByZXNlbnRhdGlvblxuICAgICAgICBsZXQgY2xvc2VzdCA9IHRlc3ROb3RhdGlvbnNbMF07XG4gICAgICAgIGxldCBjbG9zZXN0U2Vjb25kcyA9IG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0ZXN0Tm90YXRpb25zWzBdKS50b1NlY29uZHMoKTtcbiAgICAgICAgdGVzdE5vdGF0aW9ucy5mb3JFYWNoKG5vdGF0aW9uID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdGF0aW9uU2Vjb25kcyA9IG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBub3RhdGlvbikudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMobm90YXRpb25TZWNvbmRzIC0gdGltZSkgPCBNYXRoLmFicyhjbG9zZXN0U2Vjb25kcyAtIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgY2xvc2VzdCA9IG5vdGF0aW9uO1xuICAgICAgICAgICAgICAgIGNsb3Nlc3RTZWNvbmRzID0gbm90YXRpb25TZWNvbmRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNsb3Nlc3Q7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBlbmNvZGVkIGFzIEJhcnM6QmVhdHM6U2l4dGVlbnRocy5cbiAgICAgKi9cbiAgICB0b0JhcnNCZWF0c1NpeHRlZW50aHMoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBsZXQgcXVhcnRlcnMgPSB0aGlzLnZhbHVlT2YoKSAvIHF1YXJ0ZXJUaW1lO1xuICAgICAgICBxdWFydGVycyA9IHBhcnNlRmxvYXQocXVhcnRlcnMudG9GaXhlZCg0KSk7XG4gICAgICAgIGNvbnN0IG1lYXN1cmVzID0gTWF0aC5mbG9vcihxdWFydGVycyAvIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSk7XG4gICAgICAgIGxldCBzaXh0ZWVudGhzID0gKHF1YXJ0ZXJzICUgMSkgKiA0O1xuICAgICAgICBxdWFydGVycyA9IE1hdGguZmxvb3IocXVhcnRlcnMpICUgdGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpO1xuICAgICAgICBjb25zdCBzaXh0ZWVudGhTdHJpbmcgPSBzaXh0ZWVudGhzLnRvU3RyaW5nKCk7XG4gICAgICAgIGlmIChzaXh0ZWVudGhTdHJpbmcubGVuZ3RoID4gMykge1xuICAgICAgICAgICAgLy8gdGhlIGFkZGl0aW9uYWwgcGFyc2VGbG9hdCByZW1vdmVzIGluc2lnbmlmaWNhbnQgdHJhaWxpbmcgemVyb2VzXG4gICAgICAgICAgICBzaXh0ZWVudGhzID0gcGFyc2VGbG9hdChwYXJzZUZsb2F0KHNpeHRlZW50aFN0cmluZykudG9GaXhlZCgzKSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBbbWVhc3VyZXMsIHF1YXJ0ZXJzLCBzaXh0ZWVudGhzXTtcbiAgICAgICAgcmV0dXJuIHByb2dyZXNzLmpvaW4oXCI6XCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gdGlja3MuXG4gICAgICovXG4gICAgdG9UaWNrcygpIHtcbiAgICAgICAgY29uc3QgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQocXVhcnRlcnMgKiB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIHRvU2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIGFzIGEgbWlkaSBub3RlLlxuICAgICAqL1xuICAgIHRvTWlkaSgpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20odGhpcy50b0ZyZXF1ZW5jeSgpKTtcbiAgICB9XG4gICAgX25vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5ub3coKTtcbiAgICB9XG59XG4vKipcbiAqIENyZWF0ZSBhIFRpbWVDbGFzcyBmcm9tIGEgdGltZSBzdHJpbmcgb3IgbnVtYmVyLiBUaGUgdGltZSBpcyBjb21wdXRlZCBhZ2FpbnN0IHRoZVxuICogZ2xvYmFsIFRvbmUuQ29udGV4dC4gVG8gdXNlIGEgc3BlY2lmaWMgY29udGV4dCwgdXNlIFtbVGltZUNsYXNzXV1cbiAqIEBwYXJhbSB2YWx1ZSBBIHZhbHVlIHdoaWNoIHJlcHJlc2VudHMgdGltZVxuICogQHBhcmFtIHVuaXRzIFRoZSB2YWx1ZSdzIHVuaXRzIGlmIHRoZXkgY2FuJ3QgYmUgaW5mZXJyZWQgYnkgdGhlIHZhbHVlLlxuICogQGNhdGVnb3J5IFVuaXRcbiAqIEBleGFtcGxlXG4gKiBjb25zdCB0aW1lID0gVG9uZS5UaW1lKFwiNG5cIikudG9TZWNvbmRzKCk7XG4gKiBjb25zb2xlLmxvZyh0aW1lKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBub3RlID0gVG9uZS5UaW1lKDEpLnRvTm90YXRpb24oKTtcbiAqIGNvbnNvbGUubG9nKG5vdGUpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZyZXEgPSBUb25lLlRpbWUoMC41KS50b0ZyZXF1ZW5jeSgpO1xuICogY29uc29sZS5sb2coZnJlcSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUaW1lKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVGltZUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpbWUuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbywgbXRvZiB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBmdG9tLCBnZXRBNCwgc2V0QTQgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSBcIi4vVGltZVwiO1xuLyoqXG4gKiBGcmVxdWVuY3kgaXMgYSBwcmltaXRpdmUgdHlwZSBmb3IgZW5jb2RpbmcgRnJlcXVlbmN5IHZhbHVlcy5cbiAqIEV2ZW50dWFsbHkgYWxsIHRpbWUgdmFsdWVzIGFyZSBldmFsdWF0ZWQgdG8gaGVydHogdXNpbmcgdGhlIGB2YWx1ZU9mYCBtZXRob2QuXG4gKiBAZXhhbXBsZVxuICogVG9uZS5GcmVxdWVuY3koXCJDM1wiKTsgLy8gMjYxXG4gKiBUb25lLkZyZXF1ZW5jeSgzOCwgXCJtaWRpXCIpO1xuICogVG9uZS5GcmVxdWVuY3koXCJDM1wiKS50cmFuc3Bvc2UoNCk7XG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgY2xhc3MgRnJlcXVlbmN5Q2xhc3MgZXh0ZW5kcyBUaW1lQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeVwiO1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwiaHpcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIFtjb25jZXJ0IHR1bmluZyBwaXRjaF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29uY2VydF9waXRjaCkgd2hpY2ggaXMgdXNlZFxuICAgICAqIHRvIGdlbmVyYXRlIGFsbCB0aGUgb3RoZXIgcGl0Y2ggdmFsdWVzIGZyb20gbm90ZXMuIEE0J3MgdmFsdWVzIGluIEhlcnR6LlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgQTQoKSB7XG4gICAgICAgIHJldHVybiBnZXRBNCgpO1xuICAgIH1cbiAgICBzdGF0aWMgc2V0IEE0KGZyZXEpIHtcbiAgICAgICAgc2V0QTQoZnJlcSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0QVVHTUVOVCBCQVNFIEVYUFJFU1NJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgX2dldEV4cHJlc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3VwZXIuX2dldEV4cHJlc3Npb25zKCksIHtcbiAgICAgICAgICAgIG1pZGk6IHtcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT9taWRpKS8sXG4gICAgICAgICAgICAgICAgbWV0aG9kKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRVbml0cyA9PT0gXCJtaWRpXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGcmVxdWVuY3lDbGFzcy5tdG9mKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbm90ZToge1xuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oW2EtZ117MX0oPzpifCN8eHxiYik/KSgtP1swLTldKykvaSxcbiAgICAgICAgICAgICAgICBtZXRob2QocGl0Y2gsIG9jdGF2ZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IG5vdGVUb1NjYWxlSW5kZXhbcGl0Y2gudG9Mb3dlckNhc2UoKV07XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vdGVOdW1iZXIgPSBpbmRleCArIChwYXJzZUludChvY3RhdmUsIDEwKSArIDEpICogMTI7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRVbml0cyA9PT0gXCJtaWRpXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBub3RlTnVtYmVyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIEZyZXF1ZW5jeUNsYXNzLm10b2Yobm90ZU51bWJlcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyOiB7XG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KTooXFxkKyg/OlxcLlxcZCspPyk6PyhcXGQrKD86XFwuXFxkKyk/KT8vLFxuICAgICAgICAgICAgICAgIG1ldGhvZChtLCBxLCBzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0b3RhbCA9IDE7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtICYmIG0gIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCAqPSB0aGlzLl9iZWF0c1RvVW5pdHModGhpcy5fZ2V0VGltZVNpZ25hdHVyZSgpICogcGFyc2VGbG9hdChtKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHEgJiYgcSAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICo9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAocyAmJiBzICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHBhcnNlRmxvYXQocykgLyA0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdG90YWw7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdEVYUFJFU1NJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVHJhbnNwb3NlcyB0aGUgZnJlcXVlbmN5IGJ5IHRoZSBnaXZlbiBudW1iZXIgb2Ygc2VtaXRvbmVzLlxuICAgICAqIEByZXR1cm4gIEEgbmV3IHRyYW5zcG9zZWQgZnJlcXVlbmN5XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLkZyZXF1ZW5jeShcIkE0XCIpLnRyYW5zcG9zZSgzKTsgLy8gXCJDNVwiXG4gICAgICovXG4gICAgdHJhbnNwb3NlKGludGVydmFsKSB7XG4gICAgICAgIHJldHVybiBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLnZhbHVlT2YoKSAqIGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyhpbnRlcnZhbCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUYWtlcyBhbiBhcnJheSBvZiBzZW1pdG9uZSBpbnRlcnZhbHMgYW5kIHJldHVybnNcbiAgICAgKiBhbiBhcnJheSBvZiBmcmVxdWVuY2llcyB0cmFuc3Bvc2VkIGJ5IHRob3NlIGludGVydmFscy5cbiAgICAgKiBAcmV0dXJuICBSZXR1cm5zIGFuIGFycmF5IG9mIEZyZXF1ZW5jaWVzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLkZyZXF1ZW5jeShcIkE0XCIpLmhhcm1vbml6ZShbMCwgMywgN10pOyAvLyBbXCJBNFwiLCBcIkM1XCIsIFwiRTVcIl1cbiAgICAgKi9cbiAgICBoYXJtb25pemUoaW50ZXJ2YWxzKSB7XG4gICAgICAgIHJldHVybiBpbnRlcnZhbHMubWFwKGludGVydmFsID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRyYW5zcG9zZShpbnRlcnZhbCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFVOSVQgQ09OVkVSU0lPTlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuRnJlcXVlbmN5KFwiQzRcIikudG9NaWRpKCk7IC8vIDYwXG4gICAgICovXG4gICAgdG9NaWRpKCkge1xuICAgICAgICByZXR1cm4gZnRvbSh0aGlzLnZhbHVlT2YoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBpbiBTY2llbnRpZmljIFBpdGNoIE5vdGF0aW9uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLkZyZXF1ZW5jeSg2OSwgXCJtaWRpXCIpLnRvTm90ZSgpOyAvLyBcIkE0XCJcbiAgICAgKi9cbiAgICB0b05vdGUoKSB7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KCk7XG4gICAgICAgIGNvbnN0IGxvZyA9IE1hdGgubG9nMihmcmVxIC8gRnJlcXVlbmN5Q2xhc3MuQTQpO1xuICAgICAgICBsZXQgbm90ZU51bWJlciA9IE1hdGgucm91bmQoMTIgKiBsb2cpICsgNTc7XG4gICAgICAgIGNvbnN0IG9jdGF2ZSA9IE1hdGguZmxvb3Iobm90ZU51bWJlciAvIDEyKTtcbiAgICAgICAgaWYgKG9jdGF2ZSA8IDApIHtcbiAgICAgICAgICAgIG5vdGVOdW1iZXIgKz0gLTEyICogb2N0YXZlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5vdGVOYW1lID0gc2NhbGVJbmRleFRvTm90ZVtub3RlTnVtYmVyICUgMTJdO1xuICAgICAgICByZXR1cm4gbm90ZU5hbWUgKyBvY3RhdmUudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBkdXJhdGlvbiBvZiBvbmUgY3ljbGUgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiAxIC8gc3VwZXIudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZHVyYXRpb24gb2Ygb25lIGN5Y2xlIGluIHRpY2tzXG4gICAgICovXG4gICAgdG9UaWNrcygpIHtcbiAgICAgICAgY29uc3QgcXVhcnRlclRpbWUgPSB0aGlzLl9iZWF0c1RvVW5pdHMoMSk7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3IocXVhcnRlcnMgKiB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VU5JVCBDT05WRVJTSU9OUyBIRUxQRVJTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogV2l0aCBubyBhcmd1bWVudHMsIHJldHVybiAwXG4gICAgICovXG4gICAgX25vQXJnKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBmcmVxdWVuY3kgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSB7XG4gICAgICAgIHJldHVybiBmcmVxO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuICAgICAqL1xuICAgIF90aWNrc1RvVW5pdHModGlja3MpIHtcbiAgICAgICAgcmV0dXJuIDEgLyAoKHRpY2tzICogNjApIC8gKHRoaXMuX2dldEJwbSgpICogdGhpcy5fZ2V0UFBRKCkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiAxIC8gc3VwZXIuX2JlYXRzVG9Vbml0cyhiZWF0cyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIDEgLyBzZWNvbmRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgTUlESSBub3RlIHRvIGZyZXF1ZW5jeSB2YWx1ZS5cbiAgICAgKiBAcGFyYW0gIG1pZGkgVGhlIG1pZGkgbnVtYmVyIHRvIGNvbnZlcnQuXG4gICAgICogQHJldHVybiBUaGUgY29ycmVzcG9uZGluZyBmcmVxdWVuY3kgdmFsdWVcbiAgICAgKi9cbiAgICBzdGF0aWMgbXRvZihtaWRpKSB7XG4gICAgICAgIHJldHVybiBtdG9mKG1pZGkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IGEgZnJlcXVlbmN5IHZhbHVlIHRvIGEgTUlESSBub3RlLlxuICAgICAqIEBwYXJhbSBmcmVxdWVuY3kgVGhlIHZhbHVlIHRvIGZyZXF1ZW5jeSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgICAqL1xuICAgIHN0YXRpYyBmdG9tKGZyZXF1ZW5jeSkge1xuICAgICAgICByZXR1cm4gZnRvbShmcmVxdWVuY3kpO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRGUkVRVUVOQ1kgQ09OVkVSU0lPTlNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBOb3RlIHRvIHNjYWxlIGluZGV4LlxuICogQGhpZGRlblxuICovXG5jb25zdCBub3RlVG9TY2FsZUluZGV4ID0ge1xuICAgIGNiYjogLTIsIGNiOiAtMSwgYzogMCwgXCJjI1wiOiAxLCBjeDogMixcbiAgICBkYmI6IDAsIGRiOiAxLCBkOiAyLCBcImQjXCI6IDMsIGR4OiA0LFxuICAgIGViYjogMiwgZWI6IDMsIGU6IDQsIFwiZSNcIjogNSwgZXg6IDYsXG4gICAgZmJiOiAzLCBmYjogNCwgZjogNSwgXCJmI1wiOiA2LCBmeDogNyxcbiAgICBnYmI6IDUsIGdiOiA2LCBnOiA3LCBcImcjXCI6IDgsIGd4OiA5LFxuICAgIGFiYjogNywgYWI6IDgsIGE6IDksIFwiYSNcIjogMTAsIGF4OiAxMSxcbiAgICBiYmI6IDksIGJiOiAxMCwgYjogMTEsIFwiYiNcIjogMTIsIGJ4OiAxMyxcbn07XG4vKipcbiAqIHNjYWxlIGluZGV4IHRvIG5vdGUgKHNoYXJwcylcbiAqIEBoaWRkZW5cbiAqL1xuY29uc3Qgc2NhbGVJbmRleFRvTm90ZSA9IFtcIkNcIiwgXCJDI1wiLCBcIkRcIiwgXCJEI1wiLCBcIkVcIiwgXCJGXCIsIFwiRiNcIiwgXCJHXCIsIFwiRyNcIiwgXCJBXCIsIFwiQSNcIiwgXCJCXCJdO1xuLyoqXG4gKiBDb252ZXJ0IGEgdmFsdWUgaW50byBhIEZyZXF1ZW5jeUNsYXNzIG9iamVjdC5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWlkaSA9IFRvbmUuRnJlcXVlbmN5KFwiQzNcIikudG9NaWRpKCk7XG4gKiBjb25zb2xlLmxvZyhtaWRpKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBoZXJ0eiA9IFRvbmUuRnJlcXVlbmN5KDM4LCBcIm1pZGlcIikudG9GcmVxdWVuY3koKTtcbiAqIGNvbnNvbGUubG9nKGhlcnR6KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEZyZXF1ZW5jeSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IEZyZXF1ZW5jeUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSBcIi4vVGltZVwiO1xuLyoqXG4gKiBUcmFuc3BvcnRUaW1lIGlzIGEgdGhlIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzXG4gKiB0aW1lbGluZS4gSXQgaXMgc2ltaWxhciB0byBUb25lLlRpbWUsIGJ1dCBpbnN0ZWFkIG9mIGV2YWx1YXRpbmdcbiAqIGFnYWluc3QgdGhlIEF1ZGlvQ29udGV4dCdzIGNsb2NrLCBpdCBpcyBldmFsdWF0ZWQgYWdhaW5zdFxuICogdGhlIFRyYW5zcG9ydCdzIHBvc2l0aW9uLiBTZWUgW1RyYW5zcG9ydFRpbWUgd2lraV0oaHR0cHM6Ly9naXRodWIuY29tL1RvbmVqcy9Ub25lLmpzL3dpa2kvVHJhbnNwb3J0VGltZSkuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgY2xhc3MgVHJhbnNwb3J0VGltZUNsYXNzIGV4dGVuZHMgVGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUcmFuc3BvcnRUaW1lXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgY3VycmVudCB0aW1lIGluIHdoaWNoZXZlciBjb250ZXh0IGlzIHJlbGV2YW50XG4gICAgICovXG4gICAgX25vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcztcbiAgICB9XG59XG4vKipcbiAqIFRyYW5zcG9ydFRpbWUgaXMgYSB0aGUgdGltZSBhbG9uZyB0aGUgVHJhbnNwb3J0J3NcbiAqIHRpbWVsaW5lLiBJdCBpcyBzaW1pbGFyIHRvIFtbVGltZV1dLCBidXQgaW5zdGVhZCBvZiBldmFsdWF0aW5nXG4gKiBhZ2FpbnN0IHRoZSBBdWRpb0NvbnRleHQncyBjbG9jaywgaXQgaXMgZXZhbHVhdGVkIGFnYWluc3RcbiAqIHRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbi4gU2VlIFtUcmFuc3BvcnRUaW1lIHdpa2ldKGh0dHBzOi8vZ2l0aHViLmNvbS9Ub25lanMvVG9uZS5qcy93aWtpL1RyYW5zcG9ydFRpbWUpLlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFRyYW5zcG9ydFRpbWUodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0VGltZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi90eXBlL0ZyZXF1ZW5jeVwiO1xuaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSBcIi4uL3R5cGUvVGltZVwiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgZ2V0RGVmYXVsdHNGcm9tSW5zdGFuY2UsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzQm9vbGVhbiwgaXNEZWZpbmVkLCBpc051bWJlciwgaXNTdHJpbmcsIGlzVW5kZWYgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVGhlIEJhc2UgY2xhc3MgZm9yIGFsbCBub2RlcyB0aGF0IGhhdmUgYW4gQXVkaW9Db250ZXh0LlxuICovXG5leHBvcnQgY2xhc3MgVG9uZVdpdGhDb250ZXh0IGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjb250ZXh0XCJdKTtcbiAgICAgICAgaWYgKHRoaXMuZGVmYXVsdENvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dCA9IHRoaXMuZGVmYXVsdENvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSBvcHRpb25zLmNvbnRleHQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29udGV4dDogZ2V0Q29udGV4dCgpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBvZiB0aGUgQ29udGV4dCBjbG9jayBwbHVzIHRoZSBsb29rQWhlYWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICogXHRjb25zb2xlLmxvZyhUb25lLm5vdygpKTtcbiAgICAgKiB9LCAxMDApO1xuICAgICAqL1xuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSArIHRoaXMuY29udGV4dC5sb29rQWhlYWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSBDb250ZXh0IGNsb2NrIHdpdGhvdXQgYW55IGxvb2tBaGVhZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgKiBcdGNvbnNvbGUubG9nKFRvbmUuaW1tZWRpYXRlKCkpO1xuICAgICAqIH0sIDEwMCk7XG4gICAgICovXG4gICAgaW1tZWRpYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBvZiBvbmUgc2FtcGxlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc29sZS5sb2coVG9uZS5UcmFuc3BvcnQuc2FtcGxlVGltZSk7XG4gICAgICovXG4gICAgZ2V0IHNhbXBsZVRpbWUoKSB7XG4gICAgICAgIHJldHVybiAxIC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2Vjb25kcyBvZiAxIHByb2Nlc3NpbmcgYmxvY2sgKDEyOCBzYW1wbGVzKVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc29sZS5sb2coVG9uZS5EZXN0aW5hdGlvbi5ibG9ja1RpbWUpO1xuICAgICAqL1xuICAgIGdldCBibG9ja1RpbWUoKSB7XG4gICAgICAgIHJldHVybiAxMjggLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgaW5jb21pbmcgdGltZSB0byBzZWNvbmRzLlxuICAgICAqIFRoaXMgaXMgY2FsY3VsYXRlZCBhZ2FpbnN0IHRoZSBjdXJyZW50IFtbVG9uZS5UcmFuc3BvcnRdXSBicG1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2coZ2Fpbi50b1NlY29uZHMoXCI0blwiKSksIDEwMCk7XG4gICAgICogLy8gcmFtcCB0aGUgdGVtcG8gdG8gNjAgYnBtIG92ZXIgMzAgc2Vjb25kc1xuICAgICAqIFRvbmUuZ2V0VHJhbnNwb3J0KCkuYnBtLnJhbXBUbyg2MCwgMzApO1xuICAgICAqL1xuICAgIHRvU2Vjb25kcyh0aW1lKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGlucHV0IHRvIGEgZnJlcXVlbmN5IG51bWJlclxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZ2FpbiA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhnYWluLnRvRnJlcXVlbmN5KFwiNG5cIikpO1xuICAgICAqL1xuICAgIHRvRnJlcXVlbmN5KGZyZXEpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIGZyZXEpLnRvRnJlcXVlbmN5KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGlucHV0IHRpbWUgaW50byB0aWNrc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZ2FpbiA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhnYWluLnRvVGlja3MoXCI0blwiKSk7XG4gICAgICovXG4gICAgdG9UaWNrcyh0aW1lKSB7XG4gICAgICAgIHJldHVybiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdEdFVC9TRVRcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBHZXQgYSBzdWJzZXQgb2YgdGhlIHByb3BlcnRpZXMgd2hpY2ggYXJlIGluIHRoZSBwYXJ0aWFsIHByb3BzXG4gICAgICovXG4gICAgX2dldFBhcnRpYWxQcm9wZXJ0aWVzKHByb3BzKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmdldCgpO1xuICAgICAgICAvLyByZW1vdmUgYXR0cmlidXRlcyBmcm9tIHRoZSBwcm9wIHRoYXQgYXJlIG5vdCBpbiB0aGUgcGFydGlhbFxuICAgICAgICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYocHJvcHNbbmFtZV0pKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIG9wdGlvbnNbbmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gb3B0aW9ucztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBvYmplY3QncyBhdHRyaWJ1dGVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpO1xuICAgICAqIGNvbnNvbGUubG9nKG9zYy5nZXQoKSk7XG4gICAgICovXG4gICAgZ2V0KCkge1xuICAgICAgICBjb25zdCBkZWZhdWx0cyA9IGdldERlZmF1bHRzRnJvbUluc3RhbmNlKHRoaXMpO1xuICAgICAgICBPYmplY3Qua2V5cyhkZWZhdWx0cykuZm9yRWFjaChhdHRyaWJ1dGUgPT4ge1xuICAgICAgICAgICAgaWYgKFJlZmxlY3QuaGFzKHRoaXMsIGF0dHJpYnV0ZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtZW1iZXIgPSB0aGlzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChtZW1iZXIpICYmIGlzRGVmaW5lZChtZW1iZXIudmFsdWUpICYmIGlzRGVmaW5lZChtZW1iZXIuc2V0VmFsdWVBdFRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzW2F0dHJpYnV0ZV0gPSBtZW1iZXIudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG1lbWJlciBpbnN0YW5jZW9mIFRvbmVXaXRoQ29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0c1thdHRyaWJ1dGVdID0gbWVtYmVyLl9nZXRQYXJ0aWFsUHJvcGVydGllcyhkZWZhdWx0c1thdHRyaWJ1dGVdKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIG1ha2Ugc3VyZSBpdCdzIGEgc2VyaWFsaXphYmxlIHR5cGVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNBcnJheShtZW1iZXIpIHx8IGlzTnVtYmVyKG1lbWJlcikgfHwgaXNTdHJpbmcobWVtYmVyKSB8fCBpc0Jvb2xlYW4obWVtYmVyKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0c1thdHRyaWJ1dGVdID0gbWVtYmVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVtb3ZlIGFsbCB1bmRlZmluZWQgYW5kIHVuc2VyaWFsaXphYmxlIGF0dHJpYnV0ZXNcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGRlZmF1bHRzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgbXVsdGlwbGUgcHJvcGVydGllcyBhdCBvbmNlIHdpdGggYW4gb2JqZWN0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZmlsdGVyID0gbmV3IFRvbmUuRmlsdGVyKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHNldCB2YWx1ZXMgdXNpbmcgYW4gb2JqZWN0XG4gICAgICogZmlsdGVyLnNldCh7XG4gICAgICogXHRmcmVxdWVuY3k6IFwiQzZcIixcbiAgICAgKiBcdHR5cGU6IFwiaGlnaHBhc3NcIlxuICAgICAqIH0pO1xuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL0FuYWxvZ3N5bnRoX29jdGF2ZXNfaGlnaG1pZC5tcDNcIikuY29ubmVjdChmaWx0ZXIpO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqL1xuICAgIHNldChwcm9wcykge1xuICAgICAgICBPYmplY3Qua2V5cyhwcm9wcykuZm9yRWFjaChhdHRyaWJ1dGUgPT4ge1xuICAgICAgICAgICAgaWYgKFJlZmxlY3QuaGFzKHRoaXMsIGF0dHJpYnV0ZSkgJiYgaXNEZWZpbmVkKHRoaXNbYXR0cmlidXRlXSkpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpc1thdHRyaWJ1dGVdICYmIGlzRGVmaW5lZCh0aGlzW2F0dHJpYnV0ZV0udmFsdWUpICYmIGlzRGVmaW5lZCh0aGlzW2F0dHJpYnV0ZV0uc2V0VmFsdWVBdFRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHNtYWxsIG9wdGltaXphdGlvblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpc1thdHRyaWJ1dGVdLnZhbHVlICE9PSBwcm9wc1thdHRyaWJ1dGVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2F0dHJpYnV0ZV0udmFsdWUgPSBwcm9wc1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKHRoaXNbYXR0cmlidXRlXSBpbnN0YW5jZW9mIFRvbmVXaXRoQ29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW2F0dHJpYnV0ZV0uc2V0KHByb3BzW2F0dHJpYnV0ZV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdID0gcHJvcHNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lV2l0aENvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi9UaW1lbGluZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi9EZWJ1Z1wiO1xuLyoqXG4gKiBBIFRpbWVsaW5lIFN0YXRlLiBQcm92aWRlcyB0aGUgbWV0aG9kczogYHNldFN0YXRlQXRUaW1lKFwic3RhdGVcIiwgdGltZSlgIGFuZCBgZ2V0VmFsdWVBdFRpbWUodGltZSlgXG4gKiBAcGFyYW0gaW5pdGlhbCBUaGUgaW5pdGlhbCBzdGF0ZSBvZiB0aGUgU3RhdGVUaW1lbGluZS4gIERlZmF1bHRzIHRvIGB1bmRlZmluZWRgXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGF0ZVRpbWVsaW5lIGV4dGVuZHMgVGltZWxpbmUge1xuICAgIGNvbnN0cnVjdG9yKGluaXRpYWwgPSBcInN0b3BwZWRcIikge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN0YXRlVGltZWxpbmVcIjtcbiAgICAgICAgdGhpcy5faW5pdGlhbCA9IGluaXRpYWw7XG4gICAgICAgIHRoaXMuc2V0U3RhdGVBdFRpbWUodGhpcy5faW5pdGlhbCwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNjaGVkdWxlZCBzdGF0ZSBzY2hlZHVsZWQgYmVmb3JlIG9yIGF0XG4gICAgICogdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJuICBUaGUgbmFtZSBvZiB0aGUgc3RhdGUgaW5wdXQgaW4gc2V0U3RhdGVBdFRpbWUuXG4gICAgICovXG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuZ2V0KHRpbWUpO1xuICAgICAgICBpZiAoZXZlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudC5zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbml0aWFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIHN0YXRlIHRvIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIHN0YXRlIFRoZSBuYW1lIG9mIHRoZSBzdGF0ZSB0byBzZXQuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKiBAcGFyYW0gb3B0aW9ucyBBbnkgYWRkaXRpb25hbCBvcHRpb25zIHRoYXQgYXJlIG5lZWRlZCBpbiB0aGUgdGltZWxpbmUuXG4gICAgICovXG4gICAgc2V0U3RhdGVBdFRpbWUoc3RhdGUsIHRpbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgYXNzZXJ0UmFuZ2UodGltZSwgMCk7XG4gICAgICAgIHRoaXMuYWRkKE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMsIHtcbiAgICAgICAgICAgIHN0YXRlLFxuICAgICAgICAgICAgdGltZSxcbiAgICAgICAgfSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBldmVudCBiZWZvcmUgdGhlIHRpbWUgd2l0aCB0aGUgZ2l2ZW4gc3RhdGVcbiAgICAgKiBAcGFyYW0gIHN0YXRlIFRoZSBzdGF0ZSB0byBsb29rIGZvclxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBjaGVjayBiZWZvcmVcbiAgICAgKiBAcmV0dXJuICBUaGUgZXZlbnQgd2l0aCB0aGUgZ2l2ZW4gc3RhdGUgYmVmb3JlIHRoZSB0aW1lXG4gICAgICovXG4gICAgZ2V0TGFzdFN0YXRlKHN0YXRlLCB0aW1lKSB7XG4gICAgICAgIC8vIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSBpbmRleDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhdGUgPT09IHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZXZlbnQgYWZ0ZXIgdGhlIHRpbWUgd2l0aCB0aGUgZ2l2ZW4gc3RhdGVcbiAgICAgKiBAcGFyYW0gIHN0YXRlIFRoZSBzdGF0ZSB0byBsb29rIGZvclxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBjaGVjayBmcm9tXG4gICAgICogQHJldHVybiAgVGhlIGV2ZW50IHdpdGggdGhlIGdpdmVuIHN0YXRlIGFmdGVyIHRoZSB0aW1lXG4gICAgICovXG4gICAgZ2V0TmV4dFN0YXRlKHN0YXRlLCB0aW1lKSB7XG4gICAgICAgIC8vIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBpbmRleDsgaSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl90aW1lbGluZVtpXTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuc3RhdGUgPT09IHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGF0ZVRpbWVsaW5lLmpzLm1hcCIsImltcG9ydCB7IGRiVG9HYWluLCBnYWluVG9EYiB9IGZyb20gXCIuLi90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IEVRIH0gZnJvbSBcIi4uL3V0aWwvTWF0aFwiO1xuaW1wb3J0IHsgYXNzZXJ0LCBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBhcmFtIHdyYXBzIHRoZSBuYXRpdmUgV2ViIEF1ZGlvJ3MgQXVkaW9QYXJhbSB0byBwcm92aWRlXG4gKiBhZGRpdGlvbmFsIHVuaXQgY29udmVyc2lvbiBmdW5jdGlvbmFsaXR5LiBJdCBhbHNvXG4gKiBzZXJ2ZXMgYXMgYSBiYXNlLWNsYXNzIGZvciBjbGFzc2VzIHdoaWNoIGhhdmUgYSBzaW5nbGUsXG4gKiBhdXRvbWF0YWJsZSBwYXJhbWV0ZXIuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgUGFyYW0gZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJhbS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhcmFtXCIsIFwidW5pdHNcIiwgXCJjb252ZXJ0XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFyYW1cIjtcbiAgICAgICAgdGhpcy5vdmVycmlkZGVuID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWluaW11bSBvdXRwdXQgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX21pbk91dHB1dCA9IDFlLTc7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJhbS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhcmFtXCIsIFwidW5pdHNcIiwgXCJjb252ZXJ0XCJdKTtcbiAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZChvcHRpb25zLnBhcmFtKSAmJlxuICAgICAgICAgICAgKGlzQXVkaW9QYXJhbShvcHRpb25zLnBhcmFtKSB8fCBvcHRpb25zLnBhcmFtIGluc3RhbmNlb2YgUGFyYW0pLCBcInBhcmFtIG11c3QgYmUgYW4gQXVkaW9QYXJhbVwiKTtcbiAgICAgICAgd2hpbGUgKCFpc0F1ZGlvUGFyYW0ob3B0aW9ucy5wYXJhbSkpIHtcbiAgICAgICAgICAgIG9wdGlvbnMucGFyYW0gPSBvcHRpb25zLnBhcmFtLl9wYXJhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zd2FwcGFibGUgPSBpc0RlZmluZWQob3B0aW9ucy5zd2FwcGFibGUpID8gb3B0aW9ucy5zd2FwcGFibGUgOiBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuX3N3YXBwYWJsZSkge1xuICAgICAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAvLyBpbml0aWFsaXplXG4gICAgICAgICAgICB0aGlzLl9wYXJhbSA9IG9wdGlvbnMucGFyYW07XG4gICAgICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fcGFyYW0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcGFyYW0gPSB0aGlzLmlucHV0ID0gb3B0aW9ucy5wYXJhbTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVGltZWxpbmUoMTAwMCk7XG4gICAgICAgIHRoaXMuX2luaXRpYWxWYWx1ZSA9IHRoaXMuX3BhcmFtLmRlZmF1bHRWYWx1ZTtcbiAgICAgICAgdGhpcy51bml0cyA9IG9wdGlvbnMudW5pdHM7XG4gICAgICAgIHRoaXMuY29udmVydCA9IG9wdGlvbnMuY29udmVydDtcbiAgICAgICAgdGhpcy5fbWluVmFsdWUgPSBvcHRpb25zLm1pblZhbHVlO1xuICAgICAgICB0aGlzLl9tYXhWYWx1ZSA9IG9wdGlvbnMubWF4VmFsdWU7XG4gICAgICAgIC8vIGlmIHRoZSB2YWx1ZSBpcyBkZWZpbmVkLCBzZXQgaXQgaW1tZWRpYXRlbHlcbiAgICAgICAgaWYgKGlzRGVmaW5lZChvcHRpb25zLnZhbHVlKSAmJiBvcHRpb25zLnZhbHVlICE9PSB0aGlzLl90b1R5cGUodGhpcy5faW5pdGlhbFZhbHVlKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXQgdmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhbHVlQXRUaW1lKG5vdyk7XG4gICAgfVxuICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aGlzLm5vdygpKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGhpcy5ub3coKSk7XG4gICAgfVxuICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgLy8gaWYgaXQncyBub3QgdGhlIGRlZmF1bHQgbWluVmFsdWUsIHJldHVybiBpdFxuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX21pblZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX21pblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwidGltZVwiIHx8IHRoaXMudW5pdHMgPT09IFwiZnJlcXVlbmN5XCIgfHxcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPT09IFwibm9ybWFsUmFuZ2VcIiB8fCB0aGlzLnVuaXRzID09PSBcInBvc2l0aXZlXCIgfHxcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPT09IFwidHJhbnNwb3J0VGltZVwiIHx8IHRoaXMudW5pdHMgPT09IFwidGlja3NcIiB8fFxuICAgICAgICAgICAgdGhpcy51bml0cyA9PT0gXCJicG1cIiB8fCB0aGlzLnVuaXRzID09PSBcImhlcnR6XCIgfHwgdGhpcy51bml0cyA9PT0gXCJzYW1wbGVzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwiYXVkaW9SYW5nZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJkZWNpYmVsc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gLUluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1pblZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBtYXhWYWx1ZSgpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl9tYXhWYWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXhWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcIm5vcm1hbFJhbmdlXCIgfHxcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPT09IFwiYXVkaW9SYW5nZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tYXhWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUeXBlIGd1YXJkIGJhc2VkIG9uIHRoZSB1bml0IG5hbWVcbiAgICAgKi9cbiAgICBfaXMoYXJnLCB0eXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnVuaXRzID09PSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYWtlIHN1cmUgdGhlIHZhbHVlIGlzIGFsd2F5cyBpbiB0aGUgZGVmaW5lZCByYW5nZVxuICAgICAqL1xuICAgIF9hc3NlcnRSYW5nZSh2YWx1ZSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMubWF4VmFsdWUpICYmIGlzRGVmaW5lZCh0aGlzLm1pblZhbHVlKSkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodmFsdWUsIHRoaXMuX2Zyb21UeXBlKHRoaXMubWluVmFsdWUpLCB0aGlzLl9mcm9tVHlwZSh0aGlzLm1heFZhbHVlKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBnaXZlbiB2YWx1ZSBmcm9tIHRoZSB0eXBlIHNwZWNpZmllZCBieSBQYXJhbS51bml0c1xuICAgICAqIGludG8gdGhlIGRlc3RpbmF0aW9uIHZhbHVlIChzdWNoIGFzIEdhaW4gb3IgRnJlcXVlbmN5KS5cbiAgICAgKi9cbiAgICBfZnJvbVR5cGUodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnZlcnQgJiYgIXRoaXMub3ZlcnJpZGRlbikge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzKHZhbCwgXCJ0aW1lXCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9TZWNvbmRzKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9pcyh2YWwsIFwiZGVjaWJlbHNcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGJUb0dhaW4odmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX2lzKHZhbCwgXCJmcmVxdWVuY3lcIikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b0ZyZXF1ZW5jeSh2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLm92ZXJyaWRkZW4pIHtcbiAgICAgICAgICAgIC8vIGlmIGl0J3Mgb3ZlcnJpZGRlbiwgc2hvdWxkIG9ubHkgc2NoZWR1bGUgMHNcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBwYXJhbWV0ZXJzIHZhbHVlIGludG8gdGhlIHVuaXRzIHNwZWNpZmllZCBieSBQYXJhbS51bml0cy5cbiAgICAgKi9cbiAgICBfdG9UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy5jb252ZXJ0ICYmIHRoaXMudW5pdHMgPT09IFwiZGVjaWJlbHNcIikge1xuICAgICAgICAgICAgcmV0dXJuIGdhaW5Ub0RiKHZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEFCU1RSQUNUIFBBUkFNIElOVEVSRkFDRVxuICAgIC8vIGFsbCBkb2NzIGFyZSBnZW5lcmF0ZWQgZnJvbSBQYXJhbUludGVyZmFjZS50c1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShudW1lcmljVmFsdWUpICYmIGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50KHMpIHRvIHNldFZhbHVlQXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkodGltZSl9YCk7XG4gICAgICAgIHRoaXMuX2Fzc2VydFJhbmdlKG51bWVyaWNWYWx1ZSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwic2V0VmFsdWVBdFRpbWVcIiwgdmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQXRUaW1lKG51bWVyaWNWYWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gTWF0aC5tYXgodGhpcy50b1NlY29uZHModGltZSksIDApO1xuICAgICAgICBjb25zdCBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcihjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBiZWZvcmUgPSB0aGlzLl9ldmVudHMuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGxldCB2YWx1ZSA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgLy8gaWYgaXQgd2FzIHNldCBieVxuICAgICAgICBpZiAoYmVmb3JlID09PSBudWxsKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiZWZvcmUudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIiAmJiAoYWZ0ZXIgPT09IG51bGwgfHwgYWZ0ZXIudHlwZSA9PT0gXCJzZXRWYWx1ZUF0VGltZVwiKSkge1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXMgPSB0aGlzLl9ldmVudHMuZ2V0QmVmb3JlKGJlZm9yZS50aW1lKTtcbiAgICAgICAgICAgIGxldCBwcmV2aW91c1ZhbDtcbiAgICAgICAgICAgIGlmIChwcmV2aW91cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzVmFsID0gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNWYWwgPSBwcmV2aW91cy52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChiZWZvcmUudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fZXhwb25lbnRpYWxBcHByb2FjaChiZWZvcmUudGltZSwgcHJldmlvdXNWYWwsIGJlZm9yZS52YWx1ZSwgYmVmb3JlLmNvbnN0YW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGFmdGVyID09PSBudWxsKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJlZm9yZS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIgfHwgYWZ0ZXIudHlwZSA9PT0gXCJleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgIGxldCBiZWZvcmVWYWx1ZSA9IGJlZm9yZS52YWx1ZTtcbiAgICAgICAgICAgIGlmIChiZWZvcmUudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5fZXZlbnRzLmdldEJlZm9yZShiZWZvcmUudGltZSk7XG4gICAgICAgICAgICAgICAgaWYgKHByZXZpb3VzID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVZhbHVlID0gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYmVmb3JlVmFsdWUgPSBwcmV2aW91cy52YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9saW5lYXJJbnRlcnBvbGF0ZShiZWZvcmUudGltZSwgYmVmb3JlVmFsdWUsIGFmdGVyLnRpbWUsIGFmdGVyLnZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9leHBvbmVudGlhbEludGVycG9sYXRlKGJlZm9yZS50aW1lLCBiZWZvcmVWYWx1ZSwgYWZ0ZXIudGltZSwgYWZ0ZXIudmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YWx1ZSA9IGJlZm9yZS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdG9UeXBlKHZhbHVlKTtcbiAgICB9XG4gICAgc2V0UmFtcFBvaW50KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBsZXQgY3VycmVudFZhbCA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgICAgIHRoaXMuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX2Zyb21UeXBlKGN1cnJlbnRWYWwpID09PSAwKSB7XG4gICAgICAgICAgICBjdXJyZW50VmFsID0gdGhpcy5fdG9UeXBlKHRoaXMuX21pbk91dHB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShjdXJyZW50VmFsLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMoZW5kVGltZSk7XG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShudW1lcmljVmFsdWUpICYmIGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50KHMpIHRvIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkoZW5kVGltZSl9YCk7XG4gICAgICAgIHRoaXMuX2Fzc2VydFJhbmdlKG51bWVyaWNWYWx1ZSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIiwgdmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKG51bWVyaWNWYWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgbGV0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgLy8gdGhlIHZhbHVlIGNhbid0IGJlIDBcbiAgICAgICAgbnVtZXJpY1ZhbHVlID0gRVEobnVtZXJpY1ZhbHVlLCAwKSA/IHRoaXMuX21pbk91dHB1dCA6IG51bWVyaWNWYWx1ZTtcbiAgICAgICAgdGhpcy5fYXNzZXJ0UmFuZ2UobnVtZXJpY1ZhbHVlKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMoZW5kVGltZSk7XG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShudW1lcmljVmFsdWUpICYmIGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50KHMpIHRvIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeShlbmRUaW1lKX1gKTtcbiAgICAgICAgLy8gc3RvcmUgdGhlIGV2ZW50XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogbnVtZXJpY1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKG51bWVyaWNWYWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lICsgdGhpcy50b1NlY29uZHMocmFtcFRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHJhbXBUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSwgcmFtcFRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByYW1wVGltZSA9IHRoaXMudG9TZWNvbmRzKHJhbXBUaW1lKTtcbiAgICAgICAgY29uc3QgdGltZUNvbnN0YW50ID0gTWF0aC5sb2cocmFtcFRpbWUgKyAxKSAvIE1hdGgubG9nKDIwMCk7XG4gICAgICAgIHRoaXMuc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCB0aW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAvLyBhdCA5MCUgc3RhcnQgYSBsaW5lYXIgcmFtcCB0byB0aGUgZmluYWwgdmFsdWVcbiAgICAgICAgdGhpcy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUgKyByYW1wVGltZSAqIDAuOSk7XG4gICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUgKyByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlKTtcbiAgICAgICAgLy8gVGhlIHZhbHVlIHdpbGwgbmV2ZXIgYmUgYWJsZSB0byBhcHByb2FjaCB3aXRob3V0IHRpbWVDb25zdGFudCA+IDAuXG4gICAgICAgIGFzc2VydChpc0Zpbml0ZSh0aW1lQ29uc3RhbnQpICYmIHRpbWVDb25zdGFudCA+IDAsIFwidGltZUNvbnN0YW50IG11c3QgYmUgYSBudW1iZXIgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuX2Fzc2VydFJhbmdlKG51bWVyaWNWYWx1ZSk7XG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShudW1lcmljVmFsdWUpICYmIGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50KHMpIHRvIHNldFRhcmdldEF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KHN0YXJ0VGltZSl9YCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgY29uc3RhbnQ6IHRpbWVDb25zdGFudCxcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VGFyZ2V0QXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogbnVtZXJpY1ZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJzZXRUYXJnZXRBdFRpbWVcIiwgdmFsdWUsIGNvbXB1dGVkVGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VGFyZ2V0QXRUaW1lKG51bWVyaWNWYWx1ZSwgY29tcHV0ZWRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcgPSAxKSB7XG4gICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICBjb25zdCBzdGFydGluZ1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWVzWzBdKSAqIHNjYWxpbmc7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHN0YXJ0aW5nVmFsdWUpLCBzdGFydFRpbWUpO1xuICAgICAgICBjb25zdCBzZWdUaW1lID0gZHVyYXRpb24gLyAodmFsdWVzLmxlbmd0aCAtIDEpO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWVzW2ldKSAqIHNjYWxpbmc7XG4gICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShudW1lcmljVmFsdWUpLCBzdGFydFRpbWUgKyBpICogc2VnVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQgdG8gY2FuY2VsU2NoZWR1bGVkVmFsdWVzOiAke0pTT04uc3RyaW5naWZ5KHRpbWUpfWApO1xuICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImNhbmNlbFNjaGVkdWxlZFZhbHVlc1wiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCB2YWx1ZUF0VGltZSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgc2NoZWR1bGUgZXZlbnRzXG4gICAgICAgIGFzc2VydChpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudCB0byBjYW5jZWxBbmRIb2xkQXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHRpbWUpfWApO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImNhbmNlbEFuZEhvbGRBdFRpbWVcIiwgY29tcHV0ZWRUaW1lLCBcInZhbHVlPVwiICsgdmFsdWVBdFRpbWUpO1xuICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBldmVudCBhdCB0aGUgZ2l2ZW4gY29tcHV0ZWRUaW1lXG4gICAgICAgIC8vIGFuZCB0aGF0IGV2ZW4gaXMgbm90IGEgXCJzZXRcIlxuICAgICAgICBjb25zdCBiZWZvcmUgPSB0aGlzLl9ldmVudHMuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmIChiZWZvcmUgJiYgRVEoYmVmb3JlLnRpbWUsIGNvbXB1dGVkVGltZSkpIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSBldmVyeXRoaW5nIGFmdGVyXG4gICAgICAgICAgICBpZiAoYWZ0ZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChhZnRlci50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKGNvbXB1dGVkVGltZSArIHRoaXMuc2FtcGxlVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWZ0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhhZnRlci50aW1lKTtcbiAgICAgICAgICAgIC8vIGNhbmNlbCB0aGUgbmV4dCBldmVudChzKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChhZnRlci50aW1lKTtcbiAgICAgICAgICAgIGlmIChhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZSh2YWx1ZUF0VGltZSksIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChhZnRlci50eXBlID09PSBcImV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUodmFsdWVBdFRpbWUpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHNldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogdmFsdWVBdFRpbWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZUF0VGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUgPSAwLjEsIHN0YXJ0VGltZSkge1xuICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gXCJmcmVxdWVuY3lcIiB8fCB0aGlzLnVuaXRzID09PSBcImJwbVwiIHx8IHRoaXMudW5pdHMgPT09IFwiZGVjaWJlbHNcIikge1xuICAgICAgICAgICAgdGhpcy5leHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFwcGx5IGFsbCBvZiB0aGUgcHJldmlvdXNseSBzY2hlZHVsZWQgZXZlbnRzIHRvIHRoZSBwYXNzZWQgaW4gUGFyYW0gb3IgQXVkaW9QYXJhbS5cbiAgICAgKiBUaGUgYXBwbGllZCB2YWx1ZXMgd2lsbCBzdGFydCBhdCB0aGUgY29udGV4dCdzIGN1cnJlbnQgdGltZSBhbmQgc2NoZWR1bGVcbiAgICAgKiBhbGwgb2YgdGhlIGV2ZW50cyB3aGljaCBhcmUgc2NoZWR1bGVkIG9uIHRoaXMgUGFyYW0gb250byB0aGUgcGFzc2VkIGluIHBhcmFtLlxuICAgICAqL1xuICAgIGFwcGx5KHBhcmFtKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgLy8gc2V0IHRoZSBwYXJhbSdzIHZhbHVlIGF0IHRoZSBjdXJyZW50IHRpbWUgYW5kIHNjaGVkdWxlIGV2ZXJ5dGhpbmcgZWxzZVxuICAgICAgICBwYXJhbS5zZXRWYWx1ZUF0VGltZSh0aGlzLmdldFZhbHVlQXRUaW1lKG5vdyksIG5vdyk7XG4gICAgICAgIC8vIGlmIHRoZSBwcmV2aW91cyBldmVudCB3YXMgYSBjdXJ2ZSwgdGhlbiBzZXQgdGhlIHJlc3Qgb2YgaXRcbiAgICAgICAgY29uc3QgcHJldmlvdXNFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQobm93KTtcbiAgICAgICAgaWYgKHByZXZpb3VzRXZlbnQgJiYgcHJldmlvdXNFdmVudC50eXBlID09PSBcInNldFRhcmdldEF0VGltZVwiKSB7XG4gICAgICAgICAgICAvLyBhcHByb3ggaXQgdW50aWwgdGhlIG5leHQgZXZlbnQgd2l0aCBsaW5lYXIgcmFtcHNcbiAgICAgICAgICAgIGNvbnN0IG5leHRFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcihwcmV2aW91c0V2ZW50LnRpbWUpO1xuICAgICAgICAgICAgLy8gb3IgZm9yIDIgc2Vjb25kcyBpZiB0aGVyZSBpcyBubyBldmVudFxuICAgICAgICAgICAgY29uc3QgZW5kVGltZSA9IG5leHRFdmVudCA/IG5leHRFdmVudC50aW1lIDogbm93ICsgMjtcbiAgICAgICAgICAgIGNvbnN0IHN1YmRpdmlzaW9ucyA9IChlbmRUaW1lIC0gbm93KSAvIDEwO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IG5vdzsgaSA8IGVuZFRpbWU7IGkgKz0gc3ViZGl2aXNpb25zKSB7XG4gICAgICAgICAgICAgICAgcGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5nZXRWYWx1ZUF0VGltZShpKSwgaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZXZlbnRzLmZvckVhY2hBZnRlcih0aGlzLmNvbnRleHQuY3VycmVudFRpbWUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBcImNhbmNlbFNjaGVkdWxlZFZhbHVlc1wiKSB7XG4gICAgICAgICAgICAgICAgcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHBhcmFtLnNldFRhcmdldEF0VGltZShldmVudC52YWx1ZSwgZXZlbnQudGltZSwgZXZlbnQuY29uc3RhbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyYW1bZXZlbnQudHlwZV0oZXZlbnQudmFsdWUsIGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2UgdGhlIFBhcmFtJ3MgaW50ZXJuYWwgQXVkaW9QYXJhbS4gV2lsbCBhcHBseSBzY2hlZHVsZWQgY3VydmVzXG4gICAgICogb250byB0aGUgcGFyYW1ldGVyIGFuZCByZXBsYWNlIHRoZSBjb25uZWN0aW9ucy5cbiAgICAgKi9cbiAgICBzZXRQYXJhbShwYXJhbSkge1xuICAgICAgICBhc3NlcnQodGhpcy5fc3dhcHBhYmxlLCBcIlRoZSBQYXJhbSBtdXN0IGJlIGFzc2lnbmVkIGFzICdzd2FwcGFibGUnIGluIHRoZSBjb25zdHJ1Y3RvclwiKTtcbiAgICAgICAgY29uc3QgaW5wdXQgPSB0aGlzLmlucHV0O1xuICAgICAgICBpbnB1dC5kaXNjb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgdGhpcy5hcHBseShwYXJhbSk7XG4gICAgICAgIHRoaXMuX3BhcmFtID0gcGFyYW07XG4gICAgICAgIGlucHV0LmNvbm5lY3QodGhpcy5fcGFyYW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudHMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0IGRlZmF1bHRWYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9wYXJhbS5kZWZhdWx0VmFsdWUpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdEFVVE9NQVRJT04gQ1VSVkUgQ0FMQ1VMQVRJT05TXG4gICAgLy8gXHRNSVQgTGljZW5zZSwgY29weXJpZ2h0IChjKSAyMDE0IEpvcmRhbiBTYW50ZWxsXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQ2FsY3VsYXRlcyB0aGUgdGhlIHZhbHVlIGFsb25nIHRoZSBjdXJ2ZSBwcm9kdWNlZCBieSBzZXRUYXJnZXRBdFRpbWVcbiAgICBfZXhwb25lbnRpYWxBcHByb2FjaCh0MCwgdjAsIHYxLCB0aW1lQ29uc3RhbnQsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYxICsgKHYwIC0gdjEpICogTWF0aC5leHAoLSh0IC0gdDApIC8gdGltZUNvbnN0YW50KTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlcyB0aGUgdGhlIHZhbHVlIGFsb25nIHRoZSBjdXJ2ZSBwcm9kdWNlZCBieSBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVxuICAgIF9saW5lYXJJbnRlcnBvbGF0ZSh0MCwgdjAsIHQxLCB2MSwgdCkge1xuICAgICAgICByZXR1cm4gdjAgKyAodjEgLSB2MCkgKiAoKHQgLSB0MCkgLyAodDEgLSB0MCkpO1xuICAgIH1cbiAgICAvLyBDYWxjdWxhdGVzIHRoZSB0aGUgdmFsdWUgYWxvbmcgdGhlIGN1cnZlIHByb2R1Y2VkIGJ5IGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWVcbiAgICBfZXhwb25lbnRpYWxJbnRlcnBvbGF0ZSh0MCwgdjAsIHQxLCB2MSwgdCkge1xuICAgICAgICByZXR1cm4gdjAgKiBNYXRoLnBvdyh2MSAvIHYwLCAodCAtIHQwKSAvICh0MSAtIHQwKSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGFyYW0uanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGUsIGlzQXVkaW9QYXJhbSB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4vUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuL1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgYXNzZXJ0LCB3YXJuIH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogVG9uZUF1ZGlvTm9kZSBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgY2xhc3NlcyB3aGljaCBwcm9jZXNzIGF1ZGlvLlxuICovXG5leHBvcnQgY2xhc3MgVG9uZUF1ZGlvTm9kZSBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmFtZSBvZiB0aGUgY2xhc3NcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvTm9kZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogTGlzdCBhbGwgb2YgdGhlIG5vZGUgdGhhdCBtdXN0IGJlIHNldCB0byBtYXRjaCB0aGUgQ2hhbm5lbFByb3BlcnRpZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpbnB1dHMgZmVlZGluZyBpbnRvIHRoZSBBdWRpb05vZGUuXG4gICAgICogRm9yIHNvdXJjZSBub2RlcywgdGhpcyB3aWxsIGJlIDAuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBub2RlID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIGNvbnNvbGUubG9nKG5vZGUubnVtYmVyT2ZJbnB1dHMpO1xuICAgICAqL1xuICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgaWYgKGlzQXVkaW9QYXJhbSh0aGlzLmlucHV0KSB8fCB0aGlzLmlucHV0IGluc3RhbmNlb2YgUGFyYW0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlucHV0Lm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvdXRwdXRzIG9mIHRoZSBBdWRpb05vZGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBub2RlID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIGNvbnNvbGUubG9nKG5vZGUubnVtYmVyT2ZPdXRwdXRzKTtcbiAgICAgKi9cbiAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMub3V0cHV0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub3V0cHV0Lm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEFVRElPIFBST1BFUlRJRVNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBVc2VkIHRvIGRlY2lkZSB3aGljaCBub2RlcyB0byBnZXQvc2V0IHByb3BlcnRpZXMgb25cbiAgICAgKi9cbiAgICBfaXNBdWRpb05vZGUobm9kZSkge1xuICAgICAgICByZXR1cm4gaXNEZWZpbmVkKG5vZGUpICYmIChub2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBpc0F1ZGlvTm9kZShub2RlKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgb2YgdGhlIGF1ZGlvIG5vZGVzIChlaXRoZXIgaW50ZXJuYWwgb3IgaW5wdXQvb3V0cHV0KSB3aGljaCB0b2dldGhlclxuICAgICAqIG1ha2UgdXAgaG93IHRoZSBjbGFzcyBub2RlIHJlc3BvbmRzIHRvIGNoYW5uZWwgaW5wdXQvb3V0cHV0XG4gICAgICovXG4gICAgX2dldEludGVybmFsTm9kZXMoKSB7XG4gICAgICAgIGNvbnN0IG5vZGVMaXN0ID0gdGhpcy5faW50ZXJuYWxDaGFubmVscy5zbGljZSgwKTtcbiAgICAgICAgaWYgKHRoaXMuX2lzQXVkaW9Ob2RlKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICBub2RlTGlzdC5wdXNoKHRoaXMuaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9pc0F1ZGlvTm9kZSh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlucHV0ICE9PSB0aGlzLm91dHB1dCkge1xuICAgICAgICAgICAgICAgIG5vZGVMaXN0LnB1c2godGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlTGlzdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBhdWRpbyBvcHRpb25zIGZvciB0aGlzIG5vZGUgc3VjaCBhcyBjaGFubmVsSW50ZXJwcmV0YXRpb25cbiAgICAgKiBjaGFubmVsQ291bnQsIGV0Yy5cbiAgICAgKiBAcGFyYW0gb3B0aW9uc1xuICAgICAqL1xuICAgIF9zZXRDaGFubmVsUHJvcGVydGllcyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IG5vZGVMaXN0ID0gdGhpcy5fZ2V0SW50ZXJuYWxOb2RlcygpO1xuICAgICAgICBub2RlTGlzdC5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgbm9kZS5jaGFubmVsQ291bnQgPSBvcHRpb25zLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIG5vZGUuY2hhbm5lbENvdW50TW9kZSA9IG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIG5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgYXVkaW8gb3B0aW9ucyBmb3IgdGhpcyBub2RlIHN1Y2ggYXMgY2hhbm5lbEludGVycHJldGF0aW9uXG4gICAgICogY2hhbm5lbENvdW50LCBldGMuXG4gICAgICovXG4gICAgX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2dldEludGVybmFsTm9kZXMoKTtcbiAgICAgICAgYXNzZXJ0KG5vZGVMaXN0Lmxlbmd0aCA+IDAsIFwiVG9uZUF1ZGlvTm9kZSBkb2VzIG5vdCBoYXZlIGFueSBpbnRlcm5hbCBub2Rlc1wiKTtcbiAgICAgICAgLy8gdXNlIHRoZSBmaXJzdCBub2RlIHRvIGdldCBwcm9wZXJ0aWVzXG4gICAgICAgIC8vIHRoZXkgc2hvdWxkIGFsbCBiZSB0aGUgc2FtZVxuICAgICAgICBjb25zdCBub2RlID0gbm9kZUxpc3RbMF07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBub2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhbm5lbENvdW50IGlzIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgdXNlZCB3aGVuIHVwLW1peGluZyBhbmQgZG93bi1taXhpbmdcbiAgICAgKiBjb25uZWN0aW9ucyB0byBhbnkgaW5wdXRzIHRvIHRoZSBub2RlLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyAyIGV4Y2VwdCBmb3JcbiAgICAgKiBzcGVjaWZpYyBub2RlcyB3aGVyZSBpdHMgdmFsdWUgaXMgc3BlY2lhbGx5IGRldGVybWluZWQuXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkuY2hhbm5lbENvdW50O1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbENvdW50KGNoYW5uZWxDb3VudCkge1xuICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCk7XG4gICAgICAgIC8vIG1lcmdlIGl0IHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5fc2V0Q2hhbm5lbFByb3BlcnRpZXMoT2JqZWN0LmFzc2lnbihwcm9wcywgeyBjaGFubmVsQ291bnQgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFubmVsQ291bnRNb2RlIGRldGVybWluZXMgaG93IGNoYW5uZWxzIHdpbGwgYmUgY291bnRlZCB3aGVuIHVwLW1peGluZyBhbmRcbiAgICAgKiBkb3duLW1peGluZyBjb25uZWN0aW9ucyB0byBhbnkgaW5wdXRzIHRvIHRoZSBub2RlLlxuICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwibWF4XCIuIFRoaXMgYXR0cmlidXRlIGhhcyBubyBlZmZlY3QgZm9yIG5vZGVzIHdpdGggbm8gaW5wdXRzLlxuICAgICAqICogXCJtYXhcIiAtIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyB0aGUgbWF4aW11bSBvZiB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIGFsbCBjb25uZWN0aW9ucyB0byBhbiBpbnB1dC4gSW4gdGhpcyBtb2RlIGNoYW5uZWxDb3VudCBpcyBpZ25vcmVkLlxuICAgICAqICogXCJjbGFtcGVkLW1heFwiIC0gY29tcHV0ZWROdW1iZXJPZkNoYW5uZWxzIGlzIGRldGVybWluZWQgYXMgZm9yIFwibWF4XCIgYW5kIHRoZW4gY2xhbXBlZCB0byBhIG1heGltdW0gdmFsdWUgb2YgdGhlIGdpdmVuIGNoYW5uZWxDb3VudC5cbiAgICAgKiAqIFwiZXhwbGljaXRcIiAtIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyB0aGUgZXhhY3QgdmFsdWUgYXMgc3BlY2lmaWVkIGJ5IHRoZSBjaGFubmVsQ291bnQuXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgfVxuICAgIHNldCBjaGFubmVsQ291bnRNb2RlKGNoYW5uZWxDb3VudE1vZGUpIHtcbiAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpO1xuICAgICAgICAvLyBtZXJnZSBpdCB3aXRoIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuX3NldENoYW5uZWxQcm9wZXJ0aWVzKE9iamVjdC5hc3NpZ24ocHJvcHMsIHsgY2hhbm5lbENvdW50TW9kZSB9KSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYW5uZWxJbnRlcnByZXRhdGlvbiBkZXRlcm1pbmVzIGhvdyBpbmRpdmlkdWFsIGNoYW5uZWxzIHdpbGwgYmUgdHJlYXRlZFxuICAgICAqIHdoZW4gdXAtbWl4aW5nIGFuZCBkb3duLW1peGluZyBjb25uZWN0aW9ucyB0byBhbnkgaW5wdXRzIHRvIHRoZSBub2RlLlxuICAgICAqIFRoZSBkZWZhdWx0IHZhbHVlIGlzIFwic3BlYWtlcnNcIi5cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgfVxuICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oY2hhbm5lbEludGVycHJldGF0aW9uKSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKTtcbiAgICAgICAgLy8gbWVyZ2UgaXQgd2l0aCB0aGUgb3RoZXIgcHJvcGVydGllc1xuICAgICAgICB0aGlzLl9zZXRDaGFubmVsUHJvcGVydGllcyhPYmplY3QuYXNzaWduKHByb3BzLCB7IGNoYW5uZWxJbnRlcnByZXRhdGlvbiB9KSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENPTk5FQ1RJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIGEgVG9uZUF1ZGlvTm9kZSB0byBhbiBBdWRpb1BhcmFtLCBBdWRpb05vZGUsIG9yIFRvbmVBdWRpb05vZGVcbiAgICAgKiBAcGFyYW0gZGVzdGluYXRpb24gVGhlIG91dHB1dCB0byBjb25uZWN0IHRvXG4gICAgICogQHBhcmFtIG91dHB1dE51bSBUaGUgb3V0cHV0IHRvIGNvbm5lY3QgZnJvbVxuICAgICAqIEBwYXJhbSBpbnB1dE51bSBUaGUgaW5wdXQgdG8gY29ubmVjdCB0b1xuICAgICAqL1xuICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bSA9IDAsIGlucHV0TnVtID0gMCkge1xuICAgICAgICBjb25uZWN0KHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG91dHB1dCB0byB0aGUgY29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKFwiQzJcIikuc3RhcnQoKTtcbiAgICAgKiBvc2MudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIHRvRGVzdGluYXRpb24oKSB7XG4gICAgICAgIHRoaXMuY29ubmVjdCh0aGlzLmNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgb3V0cHV0IHRvIHRoZSBjb250ZXh0J3MgZGVzdGluYXRpb24gbm9kZS5cbiAgICAgKiBTZWUgW1t0b0Rlc3RpbmF0aW9uXV1cbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqL1xuICAgIHRvTWFzdGVyKCkge1xuICAgICAgICB3YXJuKFwidG9NYXN0ZXIoKSBoYXMgYmVlbiByZW5hbWVkIHRvRGVzdGluYXRpb24oKVwiKTtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9EZXN0aW5hdGlvbigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBkaXNjb25uZWN0IHRoZSBvdXRwdXRcbiAgICAgKi9cbiAgICBkaXNjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgZGlzY29ubmVjdCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBvdXRwdXQgb2YgdGhpcyBub2RlIHRvIHRoZSByZXN0IG9mIHRoZSBub2RlcyBpbiBzZXJpZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vZHJ1bS1zYW1wbGVzL2hhbmRkcnVtLWxvb3AubXAzXCIpO1xuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoNCkuc3RhcnQoKTtcbiAgICAgKiBjb25zdCBkaXN0b3J0aW9uID0gbmV3IFRvbmUuRGlzdG9ydGlvbigwLjUpO1xuICAgICAqIC8vIGNvbm5lY3QgdGhlIHBsYXllciB0byB0aGUgZmlsdGVyLCBkaXN0b3J0aW9uIGFuZCB0aGVuIHRvIHRoZSBtYXN0ZXIgb3V0cHV0XG4gICAgICogcGxheWVyLmNoYWluKGZpbHRlciwgZGlzdG9ydGlvbiwgVG9uZS5EZXN0aW5hdGlvbik7XG4gICAgICovXG4gICAgY2hhaW4oLi4ubm9kZXMpIHtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLCAuLi5ub2Rlcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjb25uZWN0IHRoZSBvdXRwdXQgb2YgdGhpcyBub2RlIHRvIHRoZSByZXN0IG9mIHRoZSBub2RlcyBpbiBwYXJhbGxlbC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9kcnVtLXNhbXBsZXMvY29uZ2Etcmh5dGhtLm1wM1wiKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKiBjb25zdCBwaXRjaFNoaWZ0ID0gbmV3IFRvbmUuUGl0Y2hTaGlmdCg0KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3QgZmlsdGVyID0gbmV3IFRvbmUuRmlsdGVyKFwiRzVcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIGNvbm5lY3QgYSBub2RlIHRvIHRoZSBwaXRjaCBzaGlmdCBhbmQgZmlsdGVyIGluIHBhcmFsbGVsXG4gICAgICogcGxheWVyLmZhbihwaXRjaFNoaWZ0LCBmaWx0ZXIpO1xuICAgICAqL1xuICAgIGZhbiguLi5ub2Rlcykge1xuICAgICAgICBub2Rlcy5mb3JFYWNoKG5vZGUgPT4gdGhpcy5jb25uZWN0KG5vZGUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERpc3Bvc2UgYW5kIGRpc2Nvbm5lY3RcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlucHV0IGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNBdWRpb05vZGUodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMub3V0cHV0KSkge1xuICAgICAgICAgICAgaWYgKHRoaXMub3V0cHV0IGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKHRoaXMub3V0cHV0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMub3V0cHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQ09OTkVDVElPTlNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBjb25uZWN0IHRvZ2V0aGVyIGFsbCBvZiB0aGUgYXJndW1lbnRzIGluIHNlcmllc1xuICogQHBhcmFtIG5vZGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0U2VyaWVzKC4uLm5vZGVzKSB7XG4gICAgY29uc3QgZmlyc3QgPSBub2Rlcy5zaGlmdCgpO1xuICAgIG5vZGVzLnJlZHVjZSgocHJldiwgY3VycmVudCkgPT4ge1xuICAgICAgICBpZiAocHJldiBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgIHByZXYuY29ubmVjdChjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZShwcmV2KSkge1xuICAgICAgICAgICAgY29ubmVjdChwcmV2LCBjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3VycmVudDtcbiAgICB9LCBmaXJzdCk7XG59XG4vKipcbiAqIENvbm5lY3QgdHdvIG5vZGVzIHRvZ2V0aGVyIHNvIHRoYXQgc2lnbmFsIGZsb3dzIGZyb20gdGhlXG4gKiBmaXJzdCBub2RlIHRvIHRoZSBzZWNvbmQuIE9wdGlvbmFsbHkgc3BlY2lmeSB0aGUgaW5wdXQgYW5kIG91dHB1dCBjaGFubmVscy5cbiAqIEBwYXJhbSBzcmNOb2RlIFRoZSBzb3VyY2Ugbm9kZVxuICogQHBhcmFtIGRzdE5vZGUgVGhlIGRlc3RpbmF0aW9uIG5vZGVcbiAqIEBwYXJhbSBvdXRwdXROdW1iZXIgVGhlIG91dHB1dCBjaGFubmVsIG9mIHRoZSBzcmNOb2RlXG4gKiBAcGFyYW0gaW5wdXROdW1iZXIgVGhlIGlucHV0IGNoYW5uZWwgb2YgdGhlIGRzdE5vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3Qoc3JjTm9kZSwgZHN0Tm9kZSwgb3V0cHV0TnVtYmVyID0gMCwgaW5wdXROdW1iZXIgPSAwKSB7XG4gICAgYXNzZXJ0KGlzRGVmaW5lZChzcmNOb2RlKSwgXCJDYW5ub3QgY29ubmVjdCBmcm9tIHVuZGVmaW5lZCBub2RlXCIpO1xuICAgIGFzc2VydChpc0RlZmluZWQoZHN0Tm9kZSksIFwiQ2Fubm90IGNvbm5lY3QgdG8gdW5kZWZpbmVkIG5vZGVcIik7XG4gICAgaWYgKGRzdE5vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlIHx8IGlzQXVkaW9Ob2RlKGRzdE5vZGUpKSB7XG4gICAgICAgIGFzc2VydChkc3ROb2RlLm51bWJlck9mSW5wdXRzID4gMCwgXCJDYW5ub3QgY29ubmVjdCB0byBub2RlIHdpdGggbm8gaW5wdXRzXCIpO1xuICAgIH1cbiAgICBhc3NlcnQoc3JjTm9kZS5udW1iZXJPZk91dHB1dHMgPiAwLCBcIkNhbm5vdCBjb25uZWN0IGZyb20gbm9kZSB3aXRoIG5vIG91dHB1dHNcIik7XG4gICAgLy8gcmVzb2x2ZSB0aGUgaW5wdXQgb2YgdGhlIGRzdE5vZGVcbiAgICB3aGlsZSAoKGRzdE5vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlIHx8IGRzdE5vZGUgaW5zdGFuY2VvZiBQYXJhbSkpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChkc3ROb2RlLmlucHV0KSkge1xuICAgICAgICAgICAgZHN0Tm9kZSA9IGRzdE5vZGUuaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgd2hpbGUgKHNyY05vZGUgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoc3JjTm9kZS5vdXRwdXQpKSB7XG4gICAgICAgICAgICBzcmNOb2RlID0gc3JjTm9kZS5vdXRwdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gbWFrZSB0aGUgY29ubmVjdGlvblxuICAgIGlmIChpc0F1ZGlvUGFyYW0oZHN0Tm9kZSkpIHtcbiAgICAgICAgc3JjTm9kZS5jb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzcmNOb2RlLmNvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyLCBpbnB1dE51bWJlcik7XG4gICAgfVxufVxuLyoqXG4gKiBEaXNjb25uZWN0IGEgbm9kZSBmcm9tIGFsbCBub2RlcyBvciBvcHRpb25hbGx5IGluY2x1ZGUgYSBkZXN0aW5hdGlvbiBub2RlIGFuZCBpbnB1dC9vdXRwdXQgY2hhbm5lbHMuXG4gKiBAcGFyYW0gc3JjTm9kZSBUaGUgc291cmNlIG5vZGVcbiAqIEBwYXJhbSBkc3ROb2RlIFRoZSBkZXN0aW5hdGlvbiBub2RlXG4gKiBAcGFyYW0gb3V0cHV0TnVtYmVyIFRoZSBvdXRwdXQgY2hhbm5lbCBvZiB0aGUgc3JjTm9kZVxuICogQHBhcmFtIGlucHV0TnVtYmVyIFRoZSBpbnB1dCBjaGFubmVsIG9mIHRoZSBkc3ROb2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNjb25uZWN0KHNyY05vZGUsIGRzdE5vZGUsIG91dHB1dE51bWJlciA9IDAsIGlucHV0TnVtYmVyID0gMCkge1xuICAgIC8vIHJlc29sdmUgdGhlIGRlc3RpbmF0aW9uIG5vZGVcbiAgICBpZiAoaXNEZWZpbmVkKGRzdE5vZGUpKSB7XG4gICAgICAgIHdoaWxlIChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgZHN0Tm9kZSA9IGRzdE5vZGUuaW5wdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gcmVzb2x2ZSB0aGUgc3JjIG5vZGVcbiAgICB3aGlsZSAoIShpc0F1ZGlvTm9kZShzcmNOb2RlKSkpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZChzcmNOb2RlLm91dHB1dCkpIHtcbiAgICAgICAgICAgIHNyY05vZGUgPSBzcmNOb2RlLm91dHB1dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNBdWRpb1BhcmFtKGRzdE5vZGUpKSB7XG4gICAgICAgIHNyY05vZGUuZGlzY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZShkc3ROb2RlKSkge1xuICAgICAgICBzcmNOb2RlLmRpc2Nvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyLCBpbnB1dE51bWJlcik7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzcmNOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9Ob2RlLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBBIHRoaW4gd3JhcHBlciBhcm91bmQgdGhlIE5hdGl2ZSBXZWIgQXVkaW8gR2Fpbk5vZGUuXG4gKiBUaGUgR2Fpbk5vZGUgaXMgYSBiYXNpYyBidWlsZGluZyBibG9jayBvZiB0aGUgV2ViIEF1ZGlvXG4gKiBBUEkgYW5kIGlzIHVzZWZ1bCBmb3Igcm91dGluZyBhdWRpbyBhbmQgYWRqdXN0aW5nIGdhaW5zLlxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZ2Fpbk5vZGUgPSBuZXcgVG9uZS5HYWluKDApLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigzMCkuY29ubmVjdChnYWluTm9kZSkuc3RhcnQoKTtcbiAqIFx0Z2Fpbk5vZGUuZ2Fpbi5yYW1wVG8oMSwgMC4xKTtcbiAqIFx0Z2Fpbk5vZGUuZ2Fpbi5yYW1wVG8oMCwgMC40LCAwLjIpO1xuICogfSwgMC43LCAxKTtcbiAqL1xuZXhwb3J0IGNsYXNzIEdhaW4gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoR2Fpbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImdhaW5cIiwgXCJ1bml0c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdhaW5cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB3cmFwcGVkIEdhaW5Ob2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUgPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAvLyBpbnB1dCA9IG91dHB1dFxuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHYWluLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZ2FpblwiLCBcInVuaXRzXCJdKTtcbiAgICAgICAgdGhpcy5nYWluID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IG9wdGlvbnMuY29udmVydCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9nYWluTm9kZS5nYWluLFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5nYWluLFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZ2FpblwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbnZlcnQ6IHRydWUsXG4gICAgICAgICAgICBnYWluOiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiZ2FpblwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuZ2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdhaW4uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSwgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBmaXJlLWFuZC1mb3JnZXQgbm9kZXNcbiAqL1xuZXhwb3J0IGNsYXNzIE9uZVNob3RTb3VyY2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNhbGxiYWNrIHRvIGludm9rZSBhZnRlciB0aGVcbiAgICAgICAgICogc291cmNlIGlzIGRvbmUgcGxheWluZy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25lbmRlZCA9IG5vT3A7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3RhcnQgdGltZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3RvcCB0aW1lXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlkIG9mIHRoZSB0aW1lb3V0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lb3V0ID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcHVibGljIG91dHB1dCBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBnYWluIG5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nYWluTm9kZSA9IHRoaXMub3V0cHV0O1xuICAgICAgICAvKipcbiAgICAgICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5nZXRTdGF0ZUF0VGltZSA9IGZ1bmN0aW9uICh0aW1lKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGFydFRpbWUgIT09IC0xICYmXG4gICAgICAgICAgICAgICAgY29tcHV0ZWRUaW1lID49IHRoaXMuX3N0YXJ0VGltZSAmJlxuICAgICAgICAgICAgICAgICh0aGlzLl9zdG9wVGltZSA9PT0gLTEgfHwgY29tcHV0ZWRUaW1lIDw9IHRoaXMuX3N0b3BUaW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcInN0YXJ0ZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBcInN0b3BwZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgICAgIHRoaXMuX2N1cnZlID0gb3B0aW9ucy5jdXJ2ZTtcbiAgICAgICAgdGhpcy5vbmVuZGVkID0gb3B0aW9ucy5vbmVuZGVkO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY3VydmU6IFwibGluZWFyXCIsXG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgb25lbmRlZDogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzb3VyY2UgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgc291cmNlXG4gICAgICovXG4gICAgX3N0YXJ0R2Fpbih0aW1lLCBnYWluID0gMSkge1xuICAgICAgICBhc3NlcnQodGhpcy5fc3RhcnRUaW1lID09PSAtMSwgXCJTb3VyY2UgY2Fubm90IGJlIHN0YXJ0ZWQgbW9yZSB0aGFuIG9uY2VcIik7XG4gICAgICAgIC8vIGFwcGx5IGEgZmFkZSBpbiBlbnZlbG9wZVxuICAgICAgICBjb25zdCBmYWRlSW5UaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5fZmFkZUluKTtcbiAgICAgICAgLy8gcmVjb3JkIHRoZSBzdGFydCB0aW1lXG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IHRpbWUgKyBmYWRlSW5UaW1lO1xuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSBNYXRoLm1heCh0aGlzLl9zdGFydFRpbWUsIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBlbnZlbG9wZVxuICAgICAgICBpZiAoZmFkZUluVGltZSA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fY3VydmUgPT09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKGdhaW4sIHRpbWUgKyBmYWRlSW5UaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKGdhaW4sIHRpbWUsIGZhZGVJblRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZShnYWluLCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgc291cmNlIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0byBzdG9wIHRoZSBzb3VyY2VcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJzdG9wXCIsIHRpbWUpO1xuICAgICAgICB0aGlzLl9zdG9wR2Fpbih0aGlzLnRvU2Vjb25kcyh0aW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBzb3VyY2UgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdG9wIHRoZSBzb3VyY2VcbiAgICAgKi9cbiAgICBfc3RvcEdhaW4odGltZSkge1xuICAgICAgICBhc3NlcnQodGhpcy5fc3RhcnRUaW1lICE9PSAtMSwgXCInc3RhcnQnIG11c3QgYmUgY2FsbGVkIGJlZm9yZSAnc3RvcCdcIik7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICB0aGlzLmNhbmNlbFN0b3AoKTtcbiAgICAgICAgLy8gdGhlIGZhZGVPdXQgdGltZVxuICAgICAgICBjb25zdCBmYWRlT3V0VGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuX2ZhZGVPdXQpO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgc3RvcCBjYWxsYmFja1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpICsgZmFkZU91dFRpbWU7XG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gTWF0aC5tYXgodGhpcy5fc3RvcFRpbWUsIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgIGlmIChmYWRlT3V0VGltZSA+IDApIHtcbiAgICAgICAgICAgIC8vIHN0YXJ0IHRoZSBmYWRlIG91dCBjdXJ2ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAgICAgICAgaWYgKHRoaXMuX2N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5saW5lYXJSYW1wVG8oMCwgZmFkZU91dFRpbWUsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi50YXJnZXRSYW1wVG8oMCwgZmFkZU91dFRpbWUsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gc3RvcCBhbnkgb25nb2luZyByYW1wcywgYW5kIHNldCB0aGUgdmFsdWUgdG8gMFxuICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbnRleHQuY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgICAgICB0aGlzLl90aW1lb3V0ID0gdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgLy8gYWxsb3cgYWRkaXRpb25hbCB0aW1lIGZvciB0aGUgZXhwb25lbnRpYWwgY3VydmUgdG8gZnVsbHkgZGVjYXlcbiAgICAgICAgICAgIGNvbnN0IGFkZGl0aW9uYWxUYWlsID0gdGhpcy5fY3VydmUgPT09IFwiZXhwb25lbnRpYWxcIiA/IGZhZGVPdXRUaW1lICogMiA6IDA7XG4gICAgICAgICAgICB0aGlzLl9zdG9wU291cmNlKHRoaXMubm93KCkgKyBhZGRpdGlvbmFsVGFpbCk7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkKCk7XG4gICAgICAgIH0sIHRoaXMuX3N0b3BUaW1lIC0gdGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgb25lbmRlZCBjYWxsYmFja1xuICAgICAqL1xuICAgIF9vbmVuZGVkKCkge1xuICAgICAgICBpZiAodGhpcy5vbmVuZGVkICE9PSBub09wKSB7XG4gICAgICAgICAgICB0aGlzLm9uZW5kZWQodGhpcyk7XG4gICAgICAgICAgICAvLyBvdmVyd3JpdGUgb25lbmRlZCB0byBtYWtlIHN1cmUgaXQgb25seSBpcyBjYWxsZWQgb25jZVxuICAgICAgICAgICAgdGhpcy5vbmVuZGVkID0gbm9PcDtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2Ugd2hlbiBpdCdzIGVuZGVkIHRvIGZyZWUgdXAgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbiBvbmx5IGluIHRoZSBvbmxpbmUgY29udGV4dFxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbnRleHQuaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGlzcG9zZUNhbGxiYWNrID0gKCkgPT4gdGhpcy5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93LnJlcXVlc3RJZGxlQ2FsbGJhY2sgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cucmVxdWVzdElkbGVDYWxsYmFjayhkaXNwb3NlQ2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dChkaXNwb3NlQ2FsbGJhY2ssIDEwMDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHBsYXliYWNrIHN0YXRlIGF0IHRoZSBjdXJyZW50IHRpbWVcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFN0YXRlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYSBzY2hlZHVsZWQgc3RvcCBldmVudFxuICAgICAqL1xuICAgIGNhbmNlbFN0b3AoKSB7XG4gICAgICAgIHRoaXMubG9nKFwiY2FuY2VsU3RvcFwiKTtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSAhPT0gLTEsIFwiU291cmNlIGlzIG5vdCBzdGFydGVkXCIpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHN0b3AgZW52ZWxvcGVcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGhpcy5fc3RhcnRUaW1lICsgdGhpcy5zYW1wbGVUaW1lKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSAtMTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbmVTaG90U291cmNlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVTaG90U291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9PbmVTaG90U291cmNlXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgZmlyZS1hbmQtZm9yZ2V0IENvbnN0YW50U291cmNlLlxuICogQWRkcyB0aGUgYWJpbGl0eSB0byByZXNjaGVkdWxlIHRoZSBzdG9wIG1ldGhvZC5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVDb25zdGFudFNvdXJjZSBleHRlbmRzIE9uZVNob3RTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQ29uc3RhbnRTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvZmZzZXRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQ29uc3RhbnRTb3VyY2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzaWduYWwgZ2VuZXJhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zb3VyY2UgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ29uc3RhbnRTb3VyY2UoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVDb25zdGFudFNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9mZnNldFwiXSk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc291cmNlLCB0aGlzLl9nYWluTm9kZSk7XG4gICAgICAgIHRoaXMub2Zmc2V0ID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IG9wdGlvbnMuY29udmVydCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9zb3VyY2Uub2Zmc2V0LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vZmZzZXQsXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPbmVTaG90U291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbnZlcnQ6IHRydWUsXG4gICAgICAgICAgICBvZmZzZXQ6IDEsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzb3VyY2Ugbm9kZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRvIHN0YXJ0IHRoZSBzb3VyY2VcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0R2Fpbihjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9zdG9wU291cmNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fc291cmNlLnN0b3AodGltZSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLm9mZnNldC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVDb25zdGFudFNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGlzQXVkaW9QYXJhbSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVG9uZUNvbnN0YW50U291cmNlIH0gZnJvbSBcIi4vVG9uZUNvbnN0YW50U291cmNlXCI7XG4vKipcbiAqIEEgc2lnbmFsIGlzIGFuIGF1ZGlvLXJhdGUgdmFsdWUuIFRvbmUuU2lnbmFsIGlzIGEgY29yZSBjb21wb25lbnQgb2YgdGhlIGxpYnJhcnkuXG4gKiBVbmxpa2UgYSBudW1iZXIsIFNpZ25hbHMgY2FuIGJlIHNjaGVkdWxlZCB3aXRoIHNhbXBsZS1sZXZlbCBhY2N1cmFjeS4gVG9uZS5TaWduYWxcbiAqIGhhcyBhbGwgb2YgdGhlIG1ldGhvZHMgYXZhaWxhYmxlIHRvIG5hdGl2ZSBXZWIgQXVkaW9cbiAqIFtBdWRpb1BhcmFtXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1hdWRpb3BhcmFtLWludGVyZmFjZSlcbiAqIGFzIHdlbGwgYXMgYWRkaXRpb25hbCBjb252ZW5pZW5jZXMuIFJlYWQgbW9yZSBhYm91dCB3b3JraW5nIHdpdGggc2lnbmFsc1xuICogW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9Ub25lanMvVG9uZS5qcy93aWtpL1NpZ25hbHMpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBhIHNjaGVkdWxlYWJsZSBzaWduYWwgd2hpY2ggY2FuIGJlIGNvbm5lY3RlZCB0byBjb250cm9sIGFuIEF1ZGlvUGFyYW0gb3IgYW5vdGhlciBTaWduYWxcbiAqIGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCh7XG4gKiBcdHZhbHVlOiBcIkM0XCIsXG4gKiBcdHVuaXRzOiBcImZyZXF1ZW5jeVwiXG4gKiB9KS5jb25uZWN0KG9zYy5mcmVxdWVuY3kpO1xuICogLy8gdGhlIHNjaGVkdWxlZCByYW1wIGNvbnRyb2xzIHRoZSBjb25uZWN0ZWQgc2lnbmFsXG4gKiBzaWduYWwucmFtcFRvKFwiQzJcIiwgNCwgXCIrMC41XCIpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgU2lnbmFsIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCIsIFwidW5pdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTaWduYWxcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIG92ZXJyaWRkZW4gb24gY29ubmVjdGlvbi5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSB0cnVlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIiwgXCJ1bml0c1wiXSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fY29uc3RhbnRTb3VyY2UgPSBuZXcgVG9uZUNvbnN0YW50U291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IG9wdGlvbnMuY29udmVydCxcbiAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLnN0YXJ0KDApO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fcGFyYW0gPSB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dE51bSA9IDAsIGlucHV0TnVtID0gMCkge1xuICAgICAgICAvLyBzdGFydCBpdCBvbmx5IHdoZW4gY29ubmVjdGVkIHRvIHNvbWV0aGluZ1xuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBQlNUUkFDVCBQQVJBTSBJTlRFUkZBQ0VcbiAgICAvLyBqdXN0IGEgcHJveHkgZm9yIHRoZSBDb25zdGFudFNvdXJjZU5vZGUncyBvZmZzZXQgQXVkaW9QYXJhbVxuICAgIC8vIGFsbCBkb2NzIGFyZSBnZW5lcmF0ZWQgZnJvbSBBYnN0cmFjdFBhcmFtLnRzXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIHNldFJhbXBQb2ludCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFJhbXBQb2ludCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5leHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ubGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS50YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lLCByYW1wVGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUsIHJhbXBUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZykge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5yYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0udmFsdWU7XG4gICAgfVxuICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBnZXQgY29udmVydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmNvbnZlcnQ7XG4gICAgfVxuICAgIHNldCBjb252ZXJ0KGNvbnZlcnQpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uY29udmVydCA9IGNvbnZlcnQ7XG4gICAgfVxuICAgIGdldCB1bml0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLnVuaXRzO1xuICAgIH1cbiAgICBnZXQgb3ZlcnJpZGRlbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm92ZXJyaWRkZW47XG4gICAgfVxuICAgIHNldCBvdmVycmlkZGVuKG92ZXJyaWRkZW4pIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ub3ZlcnJpZGRlbiA9IG92ZXJyaWRkZW47XG4gICAgfVxuICAgIGdldCBtYXhWYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm1heFZhbHVlO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5taW5WYWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VlIFtbUGFyYW0uYXBwbHldXS5cbiAgICAgKi9cbiAgICBhcHBseShwYXJhbSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5hcHBseShwYXJhbSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogV2hlbiBjb25uZWN0aW5nIGZyb20gYSBzaWduYWwsIGl0J3MgbmVjZXNzYXJ5IHRvIHplcm8gb3V0IHRoZSBub2RlIGRlc3RpbmF0aW9uXG4gKiBub2RlIGlmIHRoYXQgbm9kZSBpcyBhbHNvIGEgc2lnbmFsLiBJZiB0aGUgZGVzdGluYXRpb24gaXMgbm90IDAsIHRoZW4gdGhlIHZhbHVlc1xuICogd2lsbCBiZSBzdW1tZWQuIFRoaXMgbWV0aG9kIGluc3VyZXMgdGhhdCB0aGUgb3V0cHV0IG9mIHRoZSBkZXN0aW5hdGlvbiBzaWduYWwgd2lsbFxuICogYmUgdGhlIHNhbWUgYXMgdGhlIHNvdXJjZSBzaWduYWwsIG1ha2luZyB0aGUgZGVzdGluYXRpb24gc2lnbmFsIGEgcGFzcyB0aHJvdWdoIG5vZGUuXG4gKiBAcGFyYW0gc2lnbmFsIFRoZSBvdXRwdXQgc2lnbmFsIHRvIGNvbm5lY3QgZnJvbVxuICogQHBhcmFtIGRlc3RpbmF0aW9uIHRoZSBkZXN0aW5hdGlvbiB0byBjb25uZWN0IHRvXG4gKiBAcGFyYW0gb3V0cHV0TnVtIHRoZSBvcHRpb25hbCBvdXRwdXQgbnVtYmVyXG4gKiBAcGFyYW0gaW5wdXROdW0gdGhlIGlucHV0IG51bWJlclxuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdFNpZ25hbChzaWduYWwsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKSB7XG4gICAgaWYgKGRlc3RpbmF0aW9uIGluc3RhbmNlb2YgUGFyYW0gfHwgaXNBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKSB8fFxuICAgICAgICAoZGVzdGluYXRpb24gaW5zdGFuY2VvZiBTaWduYWwgJiYgZGVzdGluYXRpb24ub3ZlcnJpZGUpKSB7XG4gICAgICAgIC8vIGNhbmNlbCBjaGFuZ2VzXG4gICAgICAgIGRlc3RpbmF0aW9uLmNhbmNlbFNjaGVkdWxlZFZhbHVlcygwKTtcbiAgICAgICAgLy8gcmVzZXQgdGhlIHZhbHVlXG4gICAgICAgIGRlc3RpbmF0aW9uLnNldFZhbHVlQXRUaW1lKDAsIDApO1xuICAgICAgICAvLyBtYXJrIHRoZSB2YWx1ZSBhcyBvdmVycmlkZGVuXG4gICAgICAgIGlmIChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIFNpZ25hbCkge1xuICAgICAgICAgICAgZGVzdGluYXRpb24ub3ZlcnJpZGRlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29ubmVjdChzaWduYWwsIGRlc3RpbmF0aW9uLCBvdXRwdXROdW0sIGlucHV0TnVtKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNpZ25hbC5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc1VuZGVmIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIEEgUGFyYW0gY2xhc3MganVzdCBmb3IgY29tcHV0aW5nIHRpY2tzLiBTaW1pbGFyIHRvIHRoZSBbW1BhcmFtXV0gY2xhc3MsXG4gKiBidXQgb2ZmZXJzIGNvbnZlcnNpb24gdG8gQlBNIHZhbHVlcyBhcyB3ZWxsIGFzIGFiaWxpdHkgdG8gY29tcHV0ZSB0aWNrXG4gKiBkdXJhdGlvbiBhbmQgZWxhcHNlZCB0aWNrc1xuICovXG5leHBvcnQgY2xhc3MgVGlja1BhcmFtIGV4dGVuZHMgUGFyYW0ge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpY2tQYXJhbVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVsaW5lIHdoaWNoIHRyYWNrcyBhbGwgb2YgdGhlIGF1dG9tYXRpb25zLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRpbWVsaW5lKEluZmluaXR5KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnRlcm5hbCBob2xkZXIgZm9yIHRoZSBtdWx0aXBsaWVyIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tdWx0aXBsaWVyID0gMTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tQYXJhbS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgLy8gc2V0IHRoZSBtdWx0aXBsaWVyXG4gICAgICAgIHRoaXMuX211bHRpcGxpZXIgPSBvcHRpb25zLm11bHRpcGxpZXI7XG4gICAgICAgIC8vIGNsZWFyIHRoZSB0aWNrcyBmcm9tIHRoZSBiZWdpbm5pbmdcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbCgwKTtcbiAgICAgICAgLy8gc2V0IGFuIGluaXRpYWwgZXZlbnRcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZCh7XG4gICAgICAgICAgICB0aWNrczogMCxcbiAgICAgICAgICAgIHRpbWU6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5fZnJvbVR5cGUob3B0aW9ucy52YWx1ZSksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMudmFsdWUsIDApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFBhcmFtLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11bHRpcGxpZXI6IDEsXG4gICAgICAgICAgICB1bml0czogXCJoZXJ0elwiLFxuICAgICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzZXRUYXJnZXRBdFRpbWUodmFsdWUsIHRpbWUsIGNvbnN0YW50KSB7XG4gICAgICAgIC8vIGFwcHJveGltYXRlIGl0IHdpdGggbXVsdGlwbGUgbGluZWFyIHJhbXBzXG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQodGltZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIHN0YXJ0IGZyb20gcHJldmlvdXNseSBzY2hlZHVsZWQgdmFsdWVcbiAgICAgICAgY29uc3QgcHJldkV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldCh0aW1lKTtcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSBNYXRoLnJvdW5kKE1hdGgubWF4KDEgLyBjb25zdGFudCwgMSkpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSBzZWdtZW50czsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBzZWdUaW1lID0gY29uc3RhbnQgKiBpICsgdGltZTtcbiAgICAgICAgICAgIGNvbnN0IHJhbXBWYWwgPSB0aGlzLl9leHBvbmVudGlhbEFwcHJvYWNoKHByZXZFdmVudC50aW1lLCBwcmV2RXZlbnQudmFsdWUsIGNvbXB1dGVkVmFsdWUsIGNvbnN0YW50LCBzZWdUaW1lKTtcbiAgICAgICAgICAgIHRoaXMubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHJhbXBWYWwpLCBzZWdUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHN1cGVyLnNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMucHJldmlvdXNFdmVudChldmVudCk7XG4gICAgICAgIGNvbnN0IHRpY2tzVW50aWxUaW1lID0gdGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KHByZXZpb3VzRXZlbnQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGV2ZW50LnRpY2tzID0gTWF0aC5tYXgodGlja3NVbnRpbFRpbWUsIDApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHN1cGVyLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMucHJldmlvdXNFdmVudChldmVudCk7XG4gICAgICAgIGNvbnN0IHRpY2tzVW50aWxUaW1lID0gdGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KHByZXZpb3VzRXZlbnQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGV2ZW50LnRpY2tzID0gTWF0aC5tYXgodGlja3NVbnRpbFRpbWUsIDApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICAvLyBhcHJveGltYXRlIGl0IHdpdGggbXVsdGlwbGUgbGluZWFyIHJhbXBzXG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRWYWwgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIHN0YXJ0IGZyb20gcHJldmlvdXNseSBzY2hlZHVsZWQgdmFsdWVcbiAgICAgICAgY29uc3QgcHJldkV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldCh0aW1lKTtcbiAgICAgICAgLy8gYXBwcm94IDEwIHNlZ21lbnRzIHBlciBzZWNvbmRcbiAgICAgICAgY29uc3Qgc2VnbWVudHMgPSBNYXRoLnJvdW5kKE1hdGgubWF4KCh0aW1lIC0gcHJldkV2ZW50LnRpbWUpICogMTAsIDEpKTtcbiAgICAgICAgY29uc3Qgc2VnbWVudER1ciA9ICgodGltZSAtIHByZXZFdmVudC50aW1lKSAvIHNlZ21lbnRzKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gc2VnbWVudHM7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc2VnVGltZSA9IHNlZ21lbnREdXIgKiBpICsgcHJldkV2ZW50LnRpbWU7XG4gICAgICAgICAgICBjb25zdCByYW1wVmFsID0gdGhpcy5fZXhwb25lbnRpYWxJbnRlcnBvbGF0ZShwcmV2RXZlbnQudGltZSwgcHJldkV2ZW50LnZhbHVlLCB0aW1lLCBjb21wdXRlZFZhbCwgc2VnVGltZSk7XG4gICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShyYW1wVmFsKSwgc2VnVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRpY2sgdmFsdWUgYXQgdGhlIHRpbWUuIFRha2VzIGludG8gYWNjb3VudFxuICAgICAqIGFueSBhdXRvbWF0aW9uIGN1cnZlcyBzY2hlZHVsZWQgb24gdGhlIHNpZ25hbC5cbiAgICAgKiBAcGFyYW0gIGV2ZW50IFRoZSB0aW1lIHRvIGdldCB0aGUgdGljayBjb3VudCBhdFxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrcyB3aGljaCBoYXZlIGVsYXBzZWQgYXQgdGhlIHRpbWUgZ2l2ZW4gYW55IGF1dG9tYXRpb25zLlxuICAgICAqL1xuICAgIF9nZXRUaWNrc1VudGlsRXZlbnQoZXZlbnQsIHRpbWUpIHtcbiAgICAgICAgaWYgKGV2ZW50ID09PSBudWxsKSB7XG4gICAgICAgICAgICBldmVudCA9IHtcbiAgICAgICAgICAgICAgICB0aWNrczogMCxcbiAgICAgICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNVbmRlZihldmVudC50aWNrcykpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMucHJldmlvdXNFdmVudChldmVudCk7XG4gICAgICAgICAgICBldmVudC50aWNrcyA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBldmVudC50aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWwwID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShldmVudC50aW1lKSk7XG4gICAgICAgIGxldCB2YWwxID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKSk7XG4gICAgICAgIC8vIGlmIGl0J3MgcmlnaHQgb24gdGhlIGxpbmUsIHRha2UgdGhlIHByZXZpb3VzIHZhbHVlXG4gICAgICAgIGNvbnN0IG9uVGhlTGluZUV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKG9uVGhlTGluZUV2ZW50ICYmIG9uVGhlTGluZUV2ZW50LnRpbWUgPT09IHRpbWUgJiYgb25UaGVMaW5lRXZlbnQudHlwZSA9PT0gXCJzZXRWYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICB2YWwxID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lIC0gdGhpcy5zYW1wbGVUaW1lKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDAuNSAqICh0aW1lIC0gZXZlbnQudGltZSkgKiAodmFsMCArIHZhbDEpICsgZXZlbnQudGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRpY2sgdmFsdWUgYXQgdGhlIHRpbWUuIFRha2VzIGludG8gYWNjb3VudFxuICAgICAqIGFueSBhdXRvbWF0aW9uIGN1cnZlcyBzY2hlZHVsZWQgb24gdGhlIHNpZ25hbC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gZ2V0IHRoZSB0aWNrIGNvdW50IGF0XG4gICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRpY2tzIHdoaWNoIGhhdmUgZWxhcHNlZCBhdCB0aGUgdGltZSBnaXZlbiBhbnkgYXV0b21hdGlvbnMuXG4gICAgICovXG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQoZXZlbnQsIGNvbXB1dGVkVGltZSksIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgdGltZSBvZiB0aGUgbnVtYmVyIG9mIHRpY2tzIGZyb20gdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gdGlja3MgVGhlIG51bWJlciBvZiB0aWNrcyB0byBjYWxjdWxhdGVcbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gZ2V0IHRoZSBuZXh0IHRpY2sgZnJvbVxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIG9mIHRoZSBudW1iZXIgb2YgdGlja3MgZnJvbSB0aGUgZ2l2ZW4gdGltZSBpbiBzZWNvbmRzXG4gICAgICovXG4gICAgZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjdXJyZW50VGljayA9IHRoaXMuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRpbWVPZlRpY2soY3VycmVudFRpY2sgKyB0aWNrcykgLSBjb21wdXRlZFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdpdmVuIGEgdGljaywgcmV0dXJucyB0aGUgdGltZSB0aGF0IHRpY2sgb2NjdXJzIGF0LlxuICAgICAqIEByZXR1cm4gVGhlIHRpbWUgdGhhdCB0aGUgdGljayBvY2N1cnMuXG4gICAgICovXG4gICAgZ2V0VGltZU9mVGljayh0aWNrKSB7XG4gICAgICAgIGNvbnN0IGJlZm9yZSA9IHRoaXMuX2V2ZW50cy5nZXQodGljaywgXCJ0aWNrc1wiKTtcbiAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIodGljaywgXCJ0aWNrc1wiKTtcbiAgICAgICAgaWYgKGJlZm9yZSAmJiBiZWZvcmUudGlja3MgPT09IHRpY2spIHtcbiAgICAgICAgICAgIHJldHVybiBiZWZvcmUudGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiZWZvcmUgJiYgYWZ0ZXIgJiZcbiAgICAgICAgICAgIGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIiAmJlxuICAgICAgICAgICAgYmVmb3JlLnZhbHVlICE9PSBhZnRlci52YWx1ZSkge1xuICAgICAgICAgICAgY29uc3QgdmFsMCA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoYmVmb3JlLnRpbWUpKTtcbiAgICAgICAgICAgIGNvbnN0IHZhbDEgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGFmdGVyLnRpbWUpKTtcbiAgICAgICAgICAgIGNvbnN0IGRlbHRhID0gKHZhbDEgLSB2YWwwKSAvIChhZnRlci50aW1lIC0gYmVmb3JlLnRpbWUpO1xuICAgICAgICAgICAgY29uc3QgayA9IE1hdGguc3FydChNYXRoLnBvdyh2YWwwLCAyKSAtIDIgKiBkZWx0YSAqIChiZWZvcmUudGlja3MgLSB0aWNrKSk7XG4gICAgICAgICAgICBjb25zdCBzb2wxID0gKC12YWwwICsgaykgLyBkZWx0YTtcbiAgICAgICAgICAgIGNvbnN0IHNvbDIgPSAoLXZhbDAgLSBrKSAvIGRlbHRhO1xuICAgICAgICAgICAgcmV0dXJuIChzb2wxID4gMCA/IHNvbDEgOiBzb2wyKSArIGJlZm9yZS50aW1lO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJlZm9yZSkge1xuICAgICAgICAgICAgaWYgKGJlZm9yZS52YWx1ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBJbmZpbml0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBiZWZvcmUudGltZSArICh0aWNrIC0gYmVmb3JlLnRpY2tzKSAvIGJlZm9yZS52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aWNrIC8gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgc29tZSBudW1iZXIgb2YgdGlja3MgdGhlaXIgdGhlIGR1cmF0aW9uIGluIHNlY29uZHMgYWNjb3VudGluZ1xuICAgICAqIGZvciBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgbnVtYmVyIG9mIHRpY2tzIHRvIGNvbnZlcnQgdG8gc2Vjb25kcy5cbiAgICAgKiBAcGFyYW0gIHdoZW4gIFdoZW4gYWxvbmcgdGhlIGF1dG9tYXRpb24gdGltZWxpbmUgdG8gY29udmVydCB0aGUgdGlja3MuXG4gICAgICogQHJldHVybiBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBvZiB0aGUgdGlja3MuXG4gICAgICovXG4gICAgdGlja3NUb1RpbWUodGlja3MsIHdoZW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB3aGVuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGludmVyc2Ugb2YgW1t0aWNrc1RvVGltZV1dLiBDb252ZXJ0IGEgZHVyYXRpb24gaW5cbiAgICAgKiBzZWNvbmRzIHRvIHRoZSBjb3JyZXNwb25kaW5nIG51bWJlciBvZiB0aWNrcyBhY2NvdW50aW5nIGZvciBhbnlcbiAgICAgKiBhdXRvbWF0aW9uIGN1cnZlcyBzdGFydGluZyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIFRoZSB0aW1lIGludGVydmFsIHRvIGNvbnZlcnQgdG8gdGlja3MuXG4gICAgICogQHBhcmFtICB3aGVuIFdoZW4gYWxvbmcgdGhlIGF1dG9tYXRpb24gdGltZWxpbmUgdG8gY29udmVydCB0aGUgdGlja3MuXG4gICAgICogQHJldHVybiBUaGUgZHVyYXRpb24gaW4gdGlja3MuXG4gICAgICovXG4gICAgdGltZVRvVGlja3MoZHVyYXRpb24sIHdoZW4pIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMod2hlbik7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkRHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGlja3MgPSB0aGlzLmdldFRpY2tzQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGNvbnN0IGVuZFRpY2tzID0gdGhpcy5nZXRUaWNrc0F0VGltZShjb21wdXRlZFRpbWUgKyBjb21wdXRlZER1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIGVuZFRpY2tzIC0gc3RhcnRUaWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBmcm9tIHRoZSB0eXBlIHdoZW4gdGhlIHVuaXQgdmFsdWUgaXMgQlBNXG4gICAgICovXG4gICAgX2Zyb21UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gXCJicG1cIiAmJiB0aGlzLm11bHRpcGxpZXIpIHtcbiAgICAgICAgICAgIHJldHVybiAxIC8gKDYwIC8gdmFsIC8gdGhpcy5tdWx0aXBsaWVyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdXBlci5fZnJvbVR5cGUodmFsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTcGVjaWFsIGNhc2Ugb2YgdHlwZSBjb252ZXJzaW9uIHdoZXJlIHRoZSB1bml0cyA9PT0gXCJicG1cIlxuICAgICAqL1xuICAgIF90b1R5cGUodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLnVuaXRzID09PSBcImJwbVwiICYmIHRoaXMubXVsdGlwbGllcikge1xuICAgICAgICAgICAgcmV0dXJuICh2YWwgLyB0aGlzLm11bHRpcGxpZXIpICogNjA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuX3RvVHlwZSh2YWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgbXVsdGlwbGllciBvbiB0aGUgYnBtIHZhbHVlLiBVc2VmdWwgZm9yIHNldHRpbmcgYSBQUFEgcmVsYXRpdmUgdG8gdGhlIGJhc2UgZnJlcXVlbmN5IHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBtdWx0aXBsaWVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbXVsdGlwbGllcjtcbiAgICB9XG4gICAgc2V0IG11bHRpcGxpZXIobSkge1xuICAgICAgICAvLyBnZXQgYW5kIHJlc2V0IHRoZSBjdXJyZW50IHZhbHVlIHdpdGggdGhlIG5ldyBtdWx0aXBsaWVyXG4gICAgICAgIC8vIG1pZ2h0IGJlIG5lY2Vzc2FyeSB0byBjbGVhciBhbGwgdGhlIHByZXZpb3VzIHZhbHVlc1xuICAgICAgICBjb25zdCBjdXJyZW50VmFsID0gdGhpcy52YWx1ZTtcbiAgICAgICAgdGhpcy5fbXVsdGlwbGllciA9IG07XG4gICAgICAgIHRoaXMuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKDApO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKGN1cnJlbnRWYWwsIDApO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tQYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGlja1BhcmFtIH0gZnJvbSBcIi4vVGlja1BhcmFtXCI7XG4vKipcbiAqIFRpY2tTaWduYWwgZXh0ZW5kcyBUb25lLlNpZ25hbCwgYnV0IGFkZHMgdGhlIGNhcGFiaWxpdHlcbiAqIHRvIGNhbGN1bGF0ZSB0aGUgbnVtYmVyIG9mIGVsYXBzZWQgdGlja3MuIGV4cG9uZW50aWFsIGFuZCB0YXJnZXQgY3VydmVzXG4gKiBhcmUgYXBwcm94aW1hdGVkIHdpdGggbXVsdGlwbGUgbGluZWFyIHJhbXBzLlxuICpcbiAqIFRoYW5rIHlvdSBCcnVubyBEaWFzLCBILiBTb2ZpYSBQaW50bywgYW5kIERhdmlkIE0uIE1hdG9zLFxuICogZm9yIHlvdXIgW1dBQyBwYXBlcl0oaHR0cHM6Ly9zbWFydGVjaC5nYXRlY2guZWR1L2JpdHN0cmVhbS9oYW5kbGUvMTg1My81NDU4OC9XQUMyMDE2LTQ5LnBkZilcbiAqIGRlc2NyaWJpbmcgaW50ZWdyYXRpbmcgdGltaW5nIGZ1bmN0aW9ucyBmb3IgdGVtcG8gY2FsY3VsYXRpb25zLlxuICovXG5leHBvcnQgY2xhc3MgVGlja1NpZ25hbCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpY2tTaWduYWxcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9wYXJhbSA9IG5ldyBUaWNrUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogb3B0aW9ucy5jb252ZXJ0LFxuICAgICAgICAgICAgbXVsdGlwbGllcjogb3B0aW9ucy5tdWx0aXBsaWVyLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldCxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdWx0aXBsaWVyOiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiaGVydHpcIixcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgdGlja3NUb1RpbWUodGlja3MsIHdoZW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLnRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKTtcbiAgICB9XG4gICAgdGltZVRvVGlja3MoZHVyYXRpb24sIHdoZW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLnRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKTtcbiAgICB9XG4gICAgZ2V0VGltZU9mVGljayh0aWNrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXRUaW1lT2ZUaWNrKHRpY2spO1xuICAgIH1cbiAgICBnZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSk7XG4gICAgfVxuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIG11bHRpcGxpZXIgb24gdGhlIGJwbSB2YWx1ZS4gVXNlZnVsIGZvciBzZXR0aW5nIGEgUFBRIHJlbGF0aXZlIHRvIHRoZSBiYXNlIGZyZXF1ZW5jeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgbXVsdGlwbGllcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLm11bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBtdWx0aXBsaWVyKG0pIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ubXVsdGlwbGllciA9IG07XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrU2lnbmFsLmpzLm1hcCIsImltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRpY2tTaWduYWwgfSBmcm9tIFwiLi9UaWNrU2lnbmFsXCI7XG5pbXBvcnQgeyBFUSB9IGZyb20gXCIuLi91dGlsL01hdGhcIjtcbi8qKlxuICogVXNlcyBbVGlja1NpZ25hbF0oVGlja1NpZ25hbCkgdG8gdHJhY2sgZWxhcHNlZCB0aWNrcyB3aXRoIGNvbXBsZXggYXV0b21hdGlvbiBjdXJ2ZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrU291cmNlIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpY2tTb3VyY2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzdGF0ZSB0aW1lbGluZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9mZnNldCB2YWx1ZXMgb2YgdGhlIHRpY2tzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0ID0gbmV3IFRpbWVsaW5lKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgVGlja1NpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZnJlcXVlbmN5XCIpO1xuICAgICAgICAvLyBzZXQgdGhlIGluaXRpYWwgc3RhdGVcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIDApO1xuICAgICAgICAvLyBhZGQgdGhlIGZpcnN0IGV2ZW50XG4gICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUoMCwgMCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiaGVydHpcIixcbiAgICAgICAgfSwgVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiIG9yIFwicGF1c2VkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGNsb2NrIGF0IHRoZSBnaXZlbiB0aW1lLiBPcHRpb25hbGx5IHBhc3MgaW4gYW4gb2Zmc2V0XG4gICAgICogb2Ygd2hlcmUgdG8gc3RhcnQgdGhlIHRpY2sgY291bnRlciBmcm9tLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBUaGUgdGltZSB0aGUgY2xvY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIG9mZnNldCBUaGUgbnVtYmVyIG9mIHRpY2tzIHRvIHN0YXJ0IHRoZSBzb3VyY2UgYXRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKG9mZnNldCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKG9mZnNldCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgY2xvY2suIFN0b3BwaW5nIHRoZSBjbG9jayByZXNldHMgdGhlIHRpY2sgY291bnRlciB0byAwLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIGNsb2NrIHNob3VsZCBzdG9wLlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBwcmV2aW91cyBzdG9wXG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0b3BwZWRcIikge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmIChldmVudCAmJiBldmVudC50aW1lID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKGV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUoMCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhdXNlIHRoZSBjbG9jay4gUGF1c2luZyBkb2VzIG5vdCByZXNldCB0aGUgdGljayBjb3VudGVyLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIGNsb2NrIHNob3VsZCBzdG9wLlxuICAgICAqL1xuICAgIHBhdXNlKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJwYXVzZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIHN0YXJ0L3N0b3AvcGF1c2UgYW5kIHNldFRpY2tBdFRpbWUgZXZlbnRzIHNjaGVkdWxlZCBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRvIGNsZWFyIHRoZSBldmVudHMgYWZ0ZXJcbiAgICAgKi9cbiAgICBjYW5jZWwodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aW1lKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5jYW5jZWwodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGVsYXBzZWQgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgbnVtYmVyIG9mIHRpY2tzXG4gICAgICovXG4gICAgZ2V0VGlja3NBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3Qgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TGFzdFN0YXRlKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAvLyB0aGlzIGV2ZW50IGFsbG93cyBmb3JFYWNoQmV0d2VlbiB0byBpdGVyYXRlIHVudGlsIHRoZSBjdXJyZW50IHRpbWVcbiAgICAgICAgY29uc3QgdG1wRXZlbnQgPSB7IHN0YXRlOiBcInBhdXNlZFwiLCB0aW1lOiBjb21wdXRlZFRpbWUgfTtcbiAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHRtcEV2ZW50KTtcbiAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGUgcHJldmlvdXMgb2Zmc2V0IGV2ZW50XG4gICAgICAgIGxldCBsYXN0U3RhdGUgPSBzdG9wRXZlbnQ7XG4gICAgICAgIGxldCBlbGFwc2VkVGlja3MgPSAwO1xuICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggYWxsIHRoZSBldmVudHMgc2luY2UgdGhlIGxhc3Qgc3RvcFxuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoQmV0d2VlbihzdG9wRXZlbnQudGltZSwgY29tcHV0ZWRUaW1lICsgdGhpcy5zYW1wbGVUaW1lLCBlID0+IHtcbiAgICAgICAgICAgIGxldCBwZXJpb2RTdGFydFRpbWUgPSBsYXN0U3RhdGUudGltZTtcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIG9mZnNldCBldmVudCBpbiB0aGlzIHBlcmlvZCB1c2UgdGhhdFxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0RXZlbnQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChlLnRpbWUpO1xuICAgICAgICAgICAgaWYgKG9mZnNldEV2ZW50ICYmIG9mZnNldEV2ZW50LnRpbWUgPj0gbGFzdFN0YXRlLnRpbWUpIHtcbiAgICAgICAgICAgICAgICBlbGFwc2VkVGlja3MgPSBvZmZzZXRFdmVudC50aWNrcztcbiAgICAgICAgICAgICAgICBwZXJpb2RTdGFydFRpbWUgPSBvZmZzZXRFdmVudC50aW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZS5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiYgZS5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBlbGFwc2VkVGlja3MgKz0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUoZS50aW1lKSAtIHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKHBlcmlvZFN0YXJ0VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U3RhdGUgPSBlO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSB0ZW1wb3JhcnkgZXZlbnRcbiAgICAgICAgdGhpcy5fc3RhdGUucmVtb3ZlKHRtcEV2ZW50KTtcbiAgICAgICAgLy8gcmV0dXJuIHRoZSB0aWNrc1xuICAgICAgICByZXR1cm4gZWxhcHNlZFRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC4gU3RhcnRzIGNvdW50aW5nIGF0IDBcbiAgICAgKiBhbmQgaW5jcmVtZW50cyBhZnRlciB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuIFJldHVybnMgLTEgd2hlbiBzdG9wcGVkLlxuICAgICAqL1xuICAgIGdldCB0aWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VGlja3NBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUodCwgdGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIHNpbmNlIHRpY2tzPTAgdGhhdCB0aGUgVGlja1NvdXJjZSBoYXMgYmVlbiBydW5uaW5nLiBBY2NvdW50c1xuICAgICAqIGZvciB0ZW1wbyBjdXJ2ZXNcbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2Vjb25kc0F0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgc2V0IHNlY29uZHMocykge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuZnJlcXVlbmN5LnRpbWVUb1RpY2tzKHMsIG5vdyk7XG4gICAgICAgIHRoaXMuc2V0VGlja3NBdFRpbWUodGlja3MsIG5vdyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZWxhcHNlZCBzZWNvbmRzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqIEByZXR1cm4gIFRoZSBudW1iZXIgb2YgZWxhcHNlZCBzZWNvbmRzXG4gICAgICovXG4gICAgZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3Qgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TGFzdFN0YXRlKFwic3RvcHBlZFwiLCB0aW1lKTtcbiAgICAgICAgLy8gdGhpcyBldmVudCBhbGxvd3MgZm9yRWFjaEJldHdlZW4gdG8gaXRlcmF0ZSB1bnRpbCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgIGNvbnN0IHRtcEV2ZW50ID0geyBzdGF0ZTogXCJwYXVzZWRcIiwgdGltZSB9O1xuICAgICAgICB0aGlzLl9zdGF0ZS5hZGQodG1wRXZlbnQpO1xuICAgICAgICAvLyBrZWVwIHRyYWNrIG9mIHRoZSBwcmV2aW91cyBvZmZzZXQgZXZlbnRcbiAgICAgICAgbGV0IGxhc3RTdGF0ZSA9IHN0b3BFdmVudDtcbiAgICAgICAgbGV0IGVsYXBzZWRTZWNvbmRzID0gMDtcbiAgICAgICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGFsbCB0aGUgZXZlbnRzIHNpbmNlIHRoZSBsYXN0IHN0b3BcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RvcEV2ZW50LnRpbWUsIHRpbWUgKyB0aGlzLnNhbXBsZVRpbWUsIGUgPT4ge1xuICAgICAgICAgICAgbGV0IHBlcmlvZFN0YXJ0VGltZSA9IGxhc3RTdGF0ZS50aW1lO1xuICAgICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gb2Zmc2V0IGV2ZW50IGluIHRoaXMgcGVyaW9kIHVzZSB0aGF0XG4gICAgICAgICAgICBjb25zdCBvZmZzZXRFdmVudCA9IHRoaXMuX3RpY2tPZmZzZXQuZ2V0KGUudGltZSk7XG4gICAgICAgICAgICBpZiAob2Zmc2V0RXZlbnQgJiYgb2Zmc2V0RXZlbnQudGltZSA+PSBsYXN0U3RhdGUudGltZSkge1xuICAgICAgICAgICAgICAgIGVsYXBzZWRTZWNvbmRzID0gb2Zmc2V0RXZlbnQuc2Vjb25kcztcbiAgICAgICAgICAgICAgICBwZXJpb2RTdGFydFRpbWUgPSBvZmZzZXRFdmVudC50aW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZS5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiYgZS5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBlbGFwc2VkU2Vjb25kcyArPSBlLnRpbWUgLSBwZXJpb2RTdGFydFRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U3RhdGUgPSBlO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSB0ZW1wb3JhcnkgZXZlbnRcbiAgICAgICAgdGhpcy5fc3RhdGUucmVtb3ZlKHRtcEV2ZW50KTtcbiAgICAgICAgLy8gcmV0dXJuIHRoZSB0aWNrc1xuICAgICAgICByZXR1cm4gZWxhcHNlZFNlY29uZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpY2tzIFRoZSB0aWNrIHZhbHVlIHRvIHNldFxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzZXQgdGhlIHRpY2sgdmFsdWVcbiAgICAgKi9cbiAgICBzZXRUaWNrc0F0VGltZSh0aWNrcywgdGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKHRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmFkZCh7XG4gICAgICAgICAgICBzZWNvbmRzOiB0aGlzLmZyZXF1ZW5jeS5nZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpLFxuICAgICAgICAgICAgdGlja3MsXG4gICAgICAgICAgICB0aW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHNjaGVkdWxlZCBzdGF0ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGdldFN0YXRlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGltZSBvZiB0aGUgZ2l2ZW4gdGljay4gVGhlIHNlY29uZCBhcmd1bWVudFxuICAgICAqIGlzIHdoZW4gdG8gdGVzdCBiZWZvcmUuIFNpbmNlIHRpY2tzIGNhbiBiZSBzZXQgKHdpdGggc2V0VGlja3NBdFRpbWUpXG4gICAgICogdGhlcmUgbWF5IGJlIG11bHRpcGxlIHRpbWVzIGZvciBhIGdpdmVuIHRpY2sgdmFsdWUuXG4gICAgICogQHBhcmFtICB0aWNrIFRoZSB0aWNrIG51bWJlci5cbiAgICAgKiBAcGFyYW0gIGJlZm9yZSBXaGVuIHRvIG1lYXN1cmUgdGhlIHRpY2sgdmFsdWUgZnJvbS5cbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIG9mIHRoZSB0aWNrXG4gICAgICovXG4gICAgZ2V0VGltZU9mVGljayh0aWNrLCBiZWZvcmUgPSB0aGlzLm5vdygpKSB7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuX3RpY2tPZmZzZXQuZ2V0KGJlZm9yZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGJlZm9yZSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IE1hdGgubWF4KG9mZnNldC50aW1lLCBldmVudC50aW1lKTtcbiAgICAgICAgY29uc3QgYWJzb2x1dGVUaWNrcyA9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKHN0YXJ0VGltZSkgKyB0aWNrIC0gb2Zmc2V0LnRpY2tzO1xuICAgICAgICByZXR1cm4gdGhpcy5mcmVxdWVuY3kuZ2V0VGltZU9mVGljayhhYnNvbHV0ZVRpY2tzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBjYWxsYmFjayBldmVudCBhdCBhbGwgc2NoZWR1bGVkIHRpY2tzIGJldHdlZW4gdGhlXG4gICAgICogc3RhcnQgdGltZSBhbmQgdGhlIGVuZCB0aW1lXG4gICAgICogQHBhcmFtICBzdGFydFRpbWUgIFRoZSBiZWdpbm5pbmcgb2YgdGhlIHNlYXJjaCByYW5nZVxuICAgICAqIEBwYXJhbSAgZW5kVGltZSAgICBUaGUgZW5kIG9mIHRoZSBzZWFyY2ggcmFuZ2VcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGVhY2ggdGlja1xuICAgICAqL1xuICAgIGZvckVhY2hUaWNrQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIG9ubHkgaXRlcmF0ZSB0aHJvdWdoIHRoZSBzZWN0aW9ucyB3aGVyZSBpdCBpcyBcInN0YXJ0ZWRcIlxuICAgICAgICBsZXQgbGFzdFN0YXRlRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAobGFzdFN0YXRlRXZlbnQgJiYgbGFzdFN0YXRlRXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGV2ZW50LnN0YXRlICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9yRWFjaFRpY2tCZXR3ZWVuKE1hdGgubWF4KGxhc3RTdGF0ZUV2ZW50LnRpbWUsIHN0YXJ0VGltZSksIGV2ZW50LnRpbWUgLSB0aGlzLnNhbXBsZVRpbWUsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxhc3RTdGF0ZUV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgZXJyb3IgPSBudWxsO1xuICAgICAgICBpZiAobGFzdFN0YXRlRXZlbnQgJiYgbGFzdFN0YXRlRXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBjb25zdCBtYXhTdGFydFRpbWUgPSBNYXRoLm1heChsYXN0U3RhdGVFdmVudC50aW1lLCBzdGFydFRpbWUpO1xuICAgICAgICAgICAgLy8gZmlndXJlIG91dCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBmcmVxdWVuY3kgdGlja3MgYW5kIHRoZVxuICAgICAgICAgICAgY29uc3Qgc3RhcnRUaWNrcyA9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKG1heFN0YXJ0VGltZSk7XG4gICAgICAgICAgICBjb25zdCB0aWNrc0F0U3RhcnQgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShsYXN0U3RhdGVFdmVudC50aW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGRpZmYgPSBzdGFydFRpY2tzIC0gdGlja3NBdFN0YXJ0O1xuICAgICAgICAgICAgbGV0IG9mZnNldCA9IE1hdGguY2VpbChkaWZmKSAtIGRpZmY7XG4gICAgICAgICAgICAvLyBndWFyZCBhZ2FpbnN0IGZsb2F0aW5nIHBvaW50IGlzc3Vlc1xuICAgICAgICAgICAgb2Zmc2V0ID0gRVEob2Zmc2V0LCAxKSA/IDAgOiBvZmZzZXQ7XG4gICAgICAgICAgICBsZXQgbmV4dFRpY2tUaW1lID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGltZU9mVGljayhzdGFydFRpY2tzICsgb2Zmc2V0KTtcbiAgICAgICAgICAgIHdoaWxlIChuZXh0VGlja1RpbWUgPCBlbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobmV4dFRpY2tUaW1lLCBNYXRoLnJvdW5kKHRoaXMuZ2V0VGlja3NBdFRpbWUobmV4dFRpY2tUaW1lKSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBuZXh0VGlja1RpbWUgKz0gdGhpcy5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKDEsIG5leHRUaWNrVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja1NvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVtaXR0ZXIgfSBmcm9tIFwiLi4vdXRpbC9FbWl0dGVyXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3RhdGVUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmltcG9ydCB7IFRpY2tTb3VyY2UgfSBmcm9tIFwiLi9UaWNrU291cmNlXCI7XG5pbXBvcnQgeyBhc3NlcnRDb250ZXh0UnVubmluZyB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEEgc2FtcGxlIGFjY3VyYXRlIGNsb2NrIHdoaWNoIHByb3ZpZGVzIGEgY2FsbGJhY2sgYXQgdGhlIGdpdmVuIHJhdGUuXG4gKiBXaGlsZSB0aGUgY2FsbGJhY2sgaXMgbm90IHNhbXBsZS1hY2N1cmF0ZSAoaXQgaXMgc3RpbGwgc3VzY2VwdGlibGUgdG9cbiAqIGxvb3NlIEpTIHRpbWluZyksIHRoZSB0aW1lIHBhc3NlZCBpbiBhcyB0aGUgYXJndW1lbnQgdG8gdGhlIGNhbGxiYWNrXG4gKiBpcyBwcmVjaXNlLiBGb3IgbW9zdCBhcHBsaWNhdGlvbnMsIGl0IGlzIGJldHRlciB0byB1c2UgVG9uZS5UcmFuc3BvcnRcbiAqIGluc3RlYWQgb2YgdGhlIENsb2NrIGJ5IGl0c2VsZiBzaW5jZSB5b3UgY2FuIHN5bmNocm9uaXplIG11bHRpcGxlIGNhbGxiYWNrcy5cbiAqIEBleGFtcGxlXG4gKiAvLyB0aGUgY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkIGFwcHJveGltYXRlbHkgb25jZSBhIHNlY29uZFxuICogLy8gYW5kIHdpbGwgcHJpbnQgdGhlIHRpbWUgZXhhY3RseSBvbmNlIGEgc2Vjb25kIGFwYXJ0LlxuICogY29uc3QgY2xvY2sgPSBuZXcgVG9uZS5DbG9jayh0aW1lID0+IHtcbiAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gKiB9LCAxKTtcbiAqIGNsb2NrLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgQ2xvY2sgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDbG9jay5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2xvY2tcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byBpbnZva2UgYXQgdGhlIHNjaGVkdWxlZCB0aWNrLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG5vT3A7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbGFzdCB0aW1lIHRoZSBsb29wIGNhbGxiYWNrIHdhcyBpbnZva2VkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sYXN0VXBkYXRlID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIHBsYXliYWNrIHN0YXRlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnRleHQgYm91bmQgcmVmZXJlbmNlIHRvIHRoZSBfbG9vcCBtZXRob2RcbiAgICAgICAgICogVGhpcyBpcyBuZWNlc3NhcnkgdG8gcmVtb3ZlIHRoZSBldmVudCBpbiB0aGUgZW5kLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYm91bmRMb29wID0gdGhpcy5fbG9vcC5iaW5kKHRoaXMpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2xvY2suZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLl90aWNrU291cmNlID0gbmV3IFRpY2tTb3VyY2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IDA7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fdGlja1NvdXJjZS5mcmVxdWVuY3k7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZnJlcXVlbmN5XCIpO1xuICAgICAgICAvLyBhZGQgYW4gaW5pdGlhbCBzdGF0ZVxuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgMCk7XG4gICAgICAgIC8vIGJpbmQgYSBjYWxsYmFjayB0byB0aGUgd29ya2VyIHRocmVhZFxuICAgICAgICB0aGlzLmNvbnRleHQub24oXCJ0aWNrXCIsIHRoaXMuX2JvdW5kTG9vcCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiaGVydHpcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIgb3IgXCJwYXVzZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGNsb2NrIGF0IHRoZSBnaXZlbiB0aW1lLiBPcHRpb25hbGx5IHBhc3MgaW4gYW4gb2Zmc2V0XG4gICAgICogb2Ygd2hlcmUgdG8gc3RhcnQgdGhlIHRpY2sgY291bnRlciBmcm9tLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBUaGUgdGltZSB0aGUgY2xvY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIG9mZnNldCAgV2hlcmUgdGhlIHRpY2sgY291bnRlciBzdGFydHMgY291bnRpbmcgZnJvbS5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSBjb250ZXh0IGlzIHJ1bm5pbmdcbiAgICAgICAgYXNzZXJ0Q29udGV4dFJ1bm5pbmcodGhpcy5jb250ZXh0KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIGxvb3BcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc3RhcnQoY29tcHV0ZWRUaW1lLCBvZmZzZXQpO1xuICAgICAgICAgICAgaWYgKGNvbXB1dGVkVGltZSA8IHRoaXMuX2xhc3RVcGRhdGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCBjb21wdXRlZFRpbWUsIG9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGNsb2NrLiBTdG9wcGluZyB0aGUgY2xvY2sgcmVzZXRzIHRoZSB0aWNrIGNvdW50ZXIgdG8gMC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGNsb2NrID0gbmV3IFRvbmUuQ2xvY2sodGltZSA9PiB7XG4gICAgICogXHRjb25zb2xlLmxvZyh0aW1lKTtcbiAgICAgKiB9LCAxKTtcbiAgICAgKiBjbG9jay5zdGFydCgpO1xuICAgICAqIC8vIHN0b3AgdGhlIGNsb2NrIGFmdGVyIDEwIHNlY29uZHNcbiAgICAgKiBjbG9jay5zdG9wKFwiKzEwXCIpO1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdG9wXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmIChjb21wdXRlZFRpbWUgPCB0aGlzLl9sYXN0VXBkYXRlKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhdXNlIHRoZSBjbG9jay4gUGF1c2luZyBkb2VzIG5vdCByZXNldCB0aGUgdGljayBjb3VudGVyLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIGNsb2NrIHNob3VsZCBzdG9wLlxuICAgICAqL1xuICAgIHBhdXNlKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJwYXVzZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3RpY2tTb3VyY2UucGF1c2UoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIGlmIChjb21wdXRlZFRpbWUgPCB0aGlzLl9sYXN0VXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwicGF1c2VcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiB0aW1lcyB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuIFN0YXJ0cyBjb3VudGluZyBhdCAwXG4gICAgICogYW5kIGluY3JlbWVudHMgYWZ0ZXIgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLlxuICAgICAqL1xuICAgIGdldCB0aWNrcygpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguY2VpbCh0aGlzLmdldFRpY2tzQXRUaW1lKHRoaXMubm93KCkpKTtcbiAgICB9XG4gICAgc2V0IHRpY2tzKHQpIHtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS50aWNrcyA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIHNpbmNlIHRpY2tzPTAgdGhhdCB0aGUgQ2xvY2sgaGFzIGJlZW4gcnVubmluZy4gQWNjb3VudHMgZm9yIHRlbXBvIGN1cnZlc1xuICAgICAqL1xuICAgIGdldCBzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5zZWNvbmRzO1xuICAgIH1cbiAgICBzZXQgc2Vjb25kcyhzKSB7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc2Vjb25kcyA9IHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZWxhcHNlZCBzZWNvbmRzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqIEByZXR1cm4gIFRoZSBudW1iZXIgb2YgZWxhcHNlZCBzZWNvbmRzXG4gICAgICovXG4gICAgZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFNlY29uZHNBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpY2tzIFRoZSB0aWNrIHZhbHVlIHRvIHNldFxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzZXQgdGhlIHRpY2sgdmFsdWVcbiAgICAgKi9cbiAgICBzZXRUaWNrc0F0VGltZSh0aWNrcywgdGltZSkge1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnNldFRpY2tzQXRUaW1lKHRpY2tzLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGltZSBvZiB0aGUgZ2l2ZW4gdGljay4gVGhlIHNlY29uZCBhcmd1bWVudFxuICAgICAqIGlzIHdoZW4gdG8gdGVzdCBiZWZvcmUuIFNpbmNlIHRpY2tzIGNhbiBiZSBzZXQgKHdpdGggc2V0VGlja3NBdFRpbWUpXG4gICAgICogdGhlcmUgbWF5IGJlIG11bHRpcGxlIHRpbWVzIGZvciBhIGdpdmVuIHRpY2sgdmFsdWUuXG4gICAgICogQHBhcmFtICB0aWNrIFRoZSB0aWNrIG51bWJlci5cbiAgICAgKiBAcGFyYW0gIGJlZm9yZSBXaGVuIHRvIG1lYXN1cmUgdGhlIHRpY2sgdmFsdWUgZnJvbS5cbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIG9mIHRoZSB0aWNrXG4gICAgICovXG4gICAgZ2V0VGltZU9mVGljayh0aWNrLCBiZWZvcmUgPSB0aGlzLm5vdygpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIHRpY2sgdmFsdWVcbiAgICAgKiBAcmV0dXJuIFRoZSB0aWNrIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdGltZSBvZiB0aGUgbmV4dCB0aWNrXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIHRpY2sgbnVtYmVyLlxuICAgICAqL1xuICAgIG5leHRUaWNrVGltZShvZmZzZXQsIHdoZW4pIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMod2hlbik7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUaWNrID0gdGhpcy5nZXRUaWNrc0F0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRUaW1lT2ZUaWNrKGN1cnJlbnRUaWNrICsgb2Zmc2V0LCBjb21wdXRlZFRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2NoZWR1bGluZyBsb29wLlxuICAgICAqL1xuICAgIF9sb29wKCkge1xuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSB0aGlzLl9sYXN0VXBkYXRlO1xuICAgICAgICBjb25zdCBlbmRUaW1lID0gdGhpcy5ub3coKTtcbiAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IGVuZFRpbWU7XG4gICAgICAgIHRoaXMubG9nKFwibG9vcFwiLCBzdGFydFRpbWUsIGVuZFRpbWUpO1xuICAgICAgICBpZiAoc3RhcnRUaW1lICE9PSBlbmRUaW1lKSB7XG4gICAgICAgICAgICAvLyB0aGUgc3RhdGUgY2hhbmdlIGV2ZW50c1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBlID0+IHtcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGUuc3RhdGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0YXJ0ZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9mZnNldCA9IHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGlja3NBdFRpbWUoZS50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIGUudGltZSwgb2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwic3RvcHBlZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUudGltZSAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgZS50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBjYXNlIFwicGF1c2VkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJwYXVzZVwiLCBlLnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyB0aGUgdGljayBjYWxsYmFja3NcbiAgICAgICAgICAgIHRoaXMuX3RpY2tTb3VyY2UuZm9yRWFjaFRpY2tCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgKHRpbWUsIHRpY2tzKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB0aWNrcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKiBAcmV0dXJuICBUaGUgbmFtZSBvZiB0aGUgc3RhdGUgaW5wdXQgaW4gc2V0U3RhdGVBdFRpbWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjbG9jayA9IG5ldyBUb25lLkNsb2NrKCk7XG4gICAgICogY2xvY2suc3RhcnQoXCIrMC4xXCIpO1xuICAgICAqIGNsb2NrLmdldFN0YXRlQXRUaW1lKFwiKzAuMVwiKTsgLy8gcmV0dXJucyBcInN0YXJ0ZWRcIlxuICAgICAqL1xuICAgIGdldFN0YXRlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0Lm9mZihcInRpY2tcIiwgdGhpcy5fYm91bmRMb29wKTtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuRW1pdHRlci5taXhpbihDbG9jayk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DbG9jay5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgV2ViIEF1ZGlvJ3MgbmF0aXZlIFtEZWxheU5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWRlbGF5bm9kZS1pbnRlcmZhY2UpLlxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZGVsYXkgPSBuZXcgVG9uZS5EZWxheSgwLjEpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Ly8gY29ubmVjdCB0aGUgc2lnbmFsIHRvIGJvdGggdGhlIGRlbGF5IGFuZCB0aGUgZGVzdGluYXRpb25cbiAqIFx0Y29uc3QgcHVsc2UgPSBuZXcgVG9uZS5QdWxzZU9zY2lsbGF0b3IoKS5jb25uZWN0KGRlbGF5KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIHN0YXJ0IGFuZCBzdG9wIHRoZSBwdWxzZVxuICogXHRwdWxzZS5zdGFydCgwKS5zdG9wKDAuMDEpO1xuICogfSwgMC41LCAxKTtcbiAqL1xuZXhwb3J0IGNsYXNzIERlbGF5IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKERlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwibWF4RGVsYXlcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEZWxheVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJtYXhEZWxheVwiXSk7XG4gICAgICAgIGNvbnN0IG1heERlbGF5SW5TZWNvbmRzID0gdGhpcy50b1NlY29uZHMob3B0aW9ucy5tYXhEZWxheSk7XG4gICAgICAgIHRoaXMuX21heERlbGF5ID0gTWF0aC5tYXgobWF4RGVsYXlJblNlY29uZHMsIHRoaXMudG9TZWNvbmRzKG9wdGlvbnMuZGVsYXlUaW1lKSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZSA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVEZWxheShtYXhEZWxheUluU2Vjb25kcyk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgbWluVmFsdWU6IDAsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5tYXhEZWxheSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZGVsYXlUaW1lXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBkZWxheSB0aW1lLiBUaGlzIGNhbm5vdCBiZSBjaGFuZ2VkIGFmdGVyXG4gICAgICogdGhlIHZhbHVlIGlzIHBhc3NlZCBpbnRvIHRoZSBjb25zdHJ1Y3Rvci5cbiAgICAgKi9cbiAgICBnZXQgbWF4RGVsYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXhEZWxheTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlbGF5LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCwgc2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4vT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuLyoqXG4gKiBHZW5lcmF0ZSBhIGJ1ZmZlciBieSByZW5kZXJpbmcgYWxsIG9mIHRoZSBUb25lLmpzIGNvZGUgd2l0aGluIHRoZSBjYWxsYmFjayB1c2luZyB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAqIFRoZSBPZmZsaW5lQXVkaW9Db250ZXh0IGlzIGNhcGFibGUgb2YgcmVuZGVyaW5nIG11Y2ggZmFzdGVyIHRoYW4gcmVhbCB0aW1lIGluIG1hbnkgY2FzZXMuXG4gKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gYWxzbyBwYXNzZXMgaW4gYW4gb2ZmbGluZSBpbnN0YW5jZSBvZiBbW0NvbnRleHRdXSB3aGljaCBjYW4gYmUgdXNlZFxuICogdG8gc2NoZWR1bGUgZXZlbnRzIGFsb25nIHRoZSBUcmFuc3BvcnQuXG4gKiBAcGFyYW0gIGNhbGxiYWNrICBBbGwgVG9uZS5qcyBub2RlcyB3aGljaCBhcmUgY3JlYXRlZCBhbmQgc2NoZWR1bGVkIHdpdGhpbiB0aGlzIGNhbGxiYWNrIGFyZSByZWNvcmRlZCBpbnRvIHRoZSBvdXRwdXQgQnVmZmVyLlxuICogQHBhcmFtICBkdXJhdGlvbiAgICAgdGhlIGFtb3VudCBvZiB0aW1lIHRvIHJlY29yZCBmb3IuXG4gKiBAcmV0dXJuICBUaGUgcHJvbWlzZSB3aGljaCBpcyBpbnZva2VkIHdpdGggdGhlIFRvbmVBdWRpb0J1ZmZlciBvZiB0aGUgcmVjb3JkZWQgb3V0cHV0LlxuICogQGV4YW1wbGVcbiAqIC8vIHJlbmRlciAyIHNlY29uZHMgb2YgdGhlIG9zY2lsbGF0b3JcbiAqIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdC8vIG9ubHkgbm9kZXMgY3JlYXRlZCBpbiB0aGlzIGNhbGxiYWNrIHdpbGwgYmUgcmVjb3JkZWRcbiAqIFx0Y29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoMCk7XG4gKiB9LCAyKS50aGVuKChidWZmZXIpID0+IHtcbiAqIFx0Ly8gZG8gc29tZXRoaW5nIHdpdGggdGhlIG91dHB1dCBidWZmZXJcbiAqIFx0Y29uc29sZS5sb2coYnVmZmVyKTtcbiAqIH0pO1xuICogQGV4YW1wbGVcbiAqIC8vIGNhbiBhbHNvIHNjaGVkdWxlIGV2ZW50cyBhbG9uZyB0aGUgVHJhbnNwb3J0XG4gKiAvLyB1c2luZyB0aGUgcGFzc2VkIGluIE9mZmxpbmUgVHJhbnNwb3J0XG4gKiBUb25lLk9mZmxpbmUoKHsgdHJhbnNwb3J0IH0pID0+IHtcbiAqIFx0Y29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0dHJhbnNwb3J0LnNjaGVkdWxlKHRpbWUgPT4ge1xuICogXHRcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpO1xuICogXHR9LCAxKTtcbiAqIFx0Ly8gbWFrZSBzdXJlIHRvIHN0YXJ0IHRoZSB0cmFuc3BvcnRcbiAqIFx0dHJhbnNwb3J0LnN0YXJ0KDAuMik7XG4gKiB9LCA0KS50aGVuKChidWZmZXIpID0+IHtcbiAqIFx0Ly8gZG8gc29tZXRoaW5nIHdpdGggdGhlIG91dHB1dCBidWZmZXJcbiAqIFx0Y29uc29sZS5sb2coYnVmZmVyKTtcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE9mZmxpbmUoY2FsbGJhY2ssIGR1cmF0aW9uLCBjaGFubmVscyA9IDIsIHNhbXBsZVJhdGUgPSBnZXRDb250ZXh0KCkuc2FtcGxlUmF0ZSkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIC8vIHNldCB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dCBiYXNlZCBvbiB0aGUgY3VycmVudCBjb250ZXh0XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsQ29udGV4dCA9IGdldENvbnRleHQoKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dChjaGFubmVscywgZHVyYXRpb24sIHNhbXBsZVJhdGUpO1xuICAgICAgICBzZXRDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrL3NjaGVkdWxpbmdcbiAgICAgICAgeWllbGQgY2FsbGJhY2soY29udGV4dCk7XG4gICAgICAgIC8vIHRoZW4gcmVuZGVyIHRoZSBhdWRpb1xuICAgICAgICBjb25zdCBidWZmZXJQcm9taXNlID0gY29udGV4dC5yZW5kZXIoKTtcbiAgICAgICAgLy8gcmV0dXJuIHRoZSBvcmlnaW5hbCBBdWRpb0NvbnRleHRcbiAgICAgICAgc2V0Q29udGV4dChvcmlnaW5hbENvbnRleHQpO1xuICAgICAgICAvLyBhd2FpdCB0aGUgcmVuZGVyaW5nXG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIGJ1ZmZlclByb21pc2U7XG4gICAgICAgIC8vIHJldHVybiB0aGUgYXVkaW9cbiAgICAgICAgcmV0dXJuIG5ldyBUb25lQXVkaW9CdWZmZXIoYnVmZmVyKTtcbiAgICB9KTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9mZmxpbmUuanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc1N0cmluZyB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4vVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBBIGRhdGEgc3RydWN0dXJlIGZvciBob2xkaW5nIG11bHRpcGxlIGJ1ZmZlcnMgaW4gYSBNYXAtbGlrZSBkYXRhc3RydWN0dXJlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwaWFub1NhbXBsZXMgPSBuZXcgVG9uZS5Ub25lQXVkaW9CdWZmZXJzKHtcbiAqIFx0QTE6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0ExLm1wM1wiLFxuICogXHRBMjogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vQTIubXAzXCIsXG4gKiB9LCAoKSA9PiB7XG4gKiBcdGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcigpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Ly8gcGxheSBvbmUgb2YgdGhlIHNhbXBsZXMgd2hlbiB0aGV5IGFsbCBsb2FkXG4gKiBcdHBsYXllci5idWZmZXIgPSBwaWFub1NhbXBsZXMuZ2V0KFwiQTJcIik7XG4gKiBcdHBsYXllci5zdGFydCgpO1xuICogfSk7XG4gKiBAZXhhbXBsZVxuICogLy8gVG8gcGFzcyBpbiBhZGRpdGlvbmFsIHBhcmFtZXRlcnMgaW4gdGhlIHNlY29uZCBwYXJhbWV0ZXJcbiAqIGNvbnN0IGJ1ZmZlcnMgPSBuZXcgVG9uZS5Ub25lQXVkaW9CdWZmZXJzKHtcbiAqIFx0IHVybHM6IHtcbiAqIFx0XHQgQTE6IFwiQTEubXAzXCIsXG4gKiBcdFx0IEEyOiBcIkEyLm1wM1wiLFxuICogXHQgfSxcbiAqIFx0IG9ubG9hZDogKCkgPT4gY29uc29sZS5sb2coXCJsb2FkZWRcIiksXG4gKiBcdCBiYXNlVXJsOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9cIlxuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUF1ZGlvQnVmZmVycyBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb0J1ZmZlcnNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgYnVmZmVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiBsb2FkZWQgYnVmZmVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50ID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVBdWRpb0J1ZmZlcnMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCIsIFwiYmFzZVVybFwiXSwgXCJ1cmxzXCIpO1xuICAgICAgICB0aGlzLmJhc2VVcmwgPSBvcHRpb25zLmJhc2VVcmw7XG4gICAgICAgIC8vIGFkZCBlYWNoIG9uZVxuICAgICAgICBPYmplY3Qua2V5cyhvcHRpb25zLnVybHMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkaW5nQ291bnQrKztcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IG9wdGlvbnMudXJsc1tuYW1lXTtcbiAgICAgICAgICAgIHRoaXMuYWRkKG5hbWUsIHVybCwgdGhpcy5fYnVmZmVyTG9hZGVkLmJpbmQodGhpcywgb3B0aW9ucy5vbmxvYWQpLCBvcHRpb25zLm9uZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYmFzZVVybDogXCJcIixcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICB1cmxzOiB7fSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJ1ZSBpZiB0aGUgYnVmZmVycyBvYmplY3QgaGFzIGEgYnVmZmVyIGJ5IHRoYXQgbmFtZS5cbiAgICAgKiBAcGFyYW0gIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5oYXMobmFtZS50b1N0cmluZygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgYnVmZmVyIGJ5IG5hbWUuIElmIGFuIGFycmF5IHdhcyBsb2FkZWQsXG4gICAgICogdGhlbiB1c2UgdGhlIGFycmF5IGluZGV4LlxuICAgICAqIEBwYXJhbSAgbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGdldChuYW1lKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLmhhcyhuYW1lKSwgYFRvbmVBdWRpb0J1ZmZlcnMgaGFzIG5vIGJ1ZmZlciBuYW1lZDogJHtuYW1lfWApO1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycy5nZXQobmFtZS50b1N0cmluZygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBidWZmZXIgd2FzIGxvYWRlZC4gZGVjcmVtZW50IHRoZSBjb3VudGVyLlxuICAgICAqL1xuICAgIF9idWZmZXJMb2FkZWQoY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50LS07XG4gICAgICAgIGlmICh0aGlzLl9sb2FkaW5nQ291bnQgPT09IDAgJiYgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlcnMgYXJlIGxvYWRlZCBvciBub3RcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLl9idWZmZXJzKS5ldmVyeSgoW18sIGJ1ZmZlcl0pID0+IGJ1ZmZlci5sb2FkZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBidWZmZXIgYnkgbmFtZSBhbmQgdXJsIHRvIHRoZSBCdWZmZXJzXG4gICAgICogQHBhcmFtICBuYW1lICAgICAgQSB1bmlxdWUgbmFtZSB0byBnaXZlIHRoZSBidWZmZXJcbiAgICAgKiBAcGFyYW0gIHVybCAgRWl0aGVyIHRoZSB1cmwgb2YgdGhlIGJ1ZmVyLCBvciBhIGJ1ZmZlciB3aGljaCB3aWxsIGJlIGFkZGVkIHdpdGggdGhlIGdpdmVuIG5hbWUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqIEBwYXJhbSAgb25lcnJvciAgSW52b2tlZCBpZiB0aGUgYnVmZmVyIGNhbid0IGJlIGxvYWRlZFxuICAgICAqL1xuICAgIGFkZChuYW1lLCB1cmwsIGNhbGxiYWNrID0gbm9PcCwgb25lcnJvciA9IG5vT3ApIHtcbiAgICAgICAgaWYgKGlzU3RyaW5nKHVybCkpIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuc2V0KG5hbWUudG9TdHJpbmcoKSwgbmV3IFRvbmVBdWRpb0J1ZmZlcih0aGlzLmJhc2VVcmwgKyB1cmwsIGNhbGxiYWNrLCBvbmVycm9yKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLnNldChuYW1lLnRvU3RyaW5nKCksIG5ldyBUb25lQXVkaW9CdWZmZXIodXJsLCBjYWxsYmFjaywgb25lcnJvcikpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuZm9yRWFjaChidWZmZXIgPT4gYnVmZmVyLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvQnVmZmVycy5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgZnRvbSwgbXRvZiB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuL0ZyZXF1ZW5jeVwiO1xuLyoqXG4gKiBNaWRpIGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIFRpbWUgdmFsdWVzLlxuICogTWlkaSBjYW4gYmUgY29uc3RydWN0ZWQgd2l0aCBvciB3aXRob3V0IHRoZSBgbmV3YCBrZXl3b3JkLiBNaWRpIGNhbiBiZSBwYXNzZWRcbiAqIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgY2xhc3MgTWlkaUNsYXNzIGV4dGVuZHMgRnJlcXVlbmN5Q2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZGlDbGFzc1wiO1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwibWlkaVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIGZyZXF1ZW5jeSBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oc3VwZXIuX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHRpY2sgaW4gdGhlIGN1cnJlbnQgdGltZSB1bml0c1xuICAgICAqL1xuICAgIF90aWNrc1RvVW5pdHModGlja3MpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oc3VwZXIuX3RpY2tzVG9Vbml0cyh0aWNrcykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9iZWF0c1RvVW5pdHMoYmVhdHMpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oc3VwZXIuX2JlYXRzVG9Vbml0cyhiZWF0cykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5NaWRpKDYwKS50b01pZGkoKTsgLy8gNjBcbiAgICAgKi9cbiAgICB0b01pZGkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGFzIGEgTUlESSBub3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLk1pZGkoNjApLnRvRnJlcXVlbmN5KCk7IC8vIDI2MS42MjU1NjUzMDA1OTg2XG4gICAgICovXG4gICAgdG9GcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiBtdG9mKHRoaXMudG9NaWRpKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmFuc3Bvc2VzIHRoZSBmcmVxdWVuY3kgYnkgdGhlIGdpdmVuIG51bWJlciBvZiBzZW1pdG9uZXMuXG4gICAgICogQHJldHVybiBBIG5ldyB0cmFuc3Bvc2VkIE1pZGlDbGFzc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5NaWRpKFwiQTRcIikudHJhbnNwb3NlKDMpOyAvLyBcIkM1XCJcbiAgICAgKi9cbiAgICB0cmFuc3Bvc2UoaW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNaWRpQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLnRvTWlkaSgpICsgaW50ZXJ2YWwpO1xuICAgIH1cbn1cbi8qKlxuICogQ29udmVydCBhIHZhbHVlIGludG8gYSBGcmVxdWVuY3lDbGFzcyBvYmplY3QuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgZnVuY3Rpb24gTWlkaSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IE1pZGlDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRpLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi9UcmFuc3BvcnRUaW1lXCI7XG4vKipcbiAqIFRpY2tzIGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIFRpbWUgdmFsdWVzLlxuICogVGlja3MgY2FuIGJlIGNvbnN0cnVjdGVkIHdpdGggb3Igd2l0aG91dCB0aGUgYG5ld2Aga2V5d29yZC4gVGlja3MgY2FuIGJlIHBhc3NlZFxuICogaW50byB0aGUgcGFyYW1ldGVyIG9mIGFueSBtZXRob2Qgd2hpY2ggdGFrZXMgdGltZSBhcyBhbiBhcmd1bWVudC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCB0ID0gVG9uZS5UaWNrcyhcIjRuXCIpOyAvLyBhIHF1YXJ0ZXIgbm90ZSBhcyB0aWNrc1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tzQ2xhc3MgZXh0ZW5kcyBUcmFuc3BvcnRUaW1lQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpY2tzXCI7XG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJpXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCB0aW1lIGluIHRoZSBnaXZlbiB1bml0c1xuICAgICAqL1xuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBiZWF0cyBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9iZWF0c1RvVW5pdHMoYmVhdHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFBQUSgpICogYmVhdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3Ioc2Vjb25kcyAvICg2MCAvIHRoaXMuX2dldEJwbSgpKSAqIHRoaXMuX2dldFBQUSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiB0aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHRpY2tzXG4gICAgICovXG4gICAgdG9UaWNrcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWVPZigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIHRvU2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnZhbHVlT2YoKSAvIHRoaXMuX2dldFBQUSgpKSAqICg2MCAvIHRoaXMuX2dldEJwbSgpKTtcbiAgICB9XG59XG4vKipcbiAqIENvbnZlcnQgYSB0aW1lIHJlcHJlc2VudGF0aW9uIHRvIHRpY2tzXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICovXG5leHBvcnQgZnVuY3Rpb24gVGlja3ModmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tzLmpzLm1hcCIsImltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi9UaW1lbGluZVwiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi4vY29udGV4dC9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbi8qKlxuICogRHJhdyBpcyB1c2VmdWwgZm9yIHN5bmNocm9uaXppbmcgdmlzdWFscyBhbmQgYXVkaW8gZXZlbnRzLlxuICogQ2FsbGJhY2tzIGZyb20gVG9uZS5UcmFuc3BvcnQgb3IgYW55IG9mIHRoZSBUb25lLkV2ZW50IGNsYXNzZXNcbiAqIGFsd2F5cyBoYXBwZW4gX2JlZm9yZV8gdGhlIHNjaGVkdWxlZCB0aW1lIGFuZCBhcmUgbm90IHN5bmNocm9uaXplZFxuICogdG8gdGhlIGFuaW1hdGlvbiBmcmFtZSBzbyB0aGV5IGFyZSBub3QgZ29vZCBmb3IgdHJpZ2dlcmluZyB0aWdodGx5XG4gKiBzeW5jaHJvbml6ZWQgdmlzdWFscyBhbmQgc291bmQuIERyYXcgbWFrZXMgaXQgZWFzeSB0byBzY2hlZHVsZVxuICogY2FsbGJhY2tzIHVzaW5nIHRoZSBBdWRpb0NvbnRleHQgdGltZSBhbmQgdXNlcyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUuXG4gKiBAZXhhbXBsZVxuICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGUoKHRpbWUpID0+IHtcbiAqIFx0Ly8gdXNlIHRoZSB0aW1lIGFyZ3VtZW50IHRvIHNjaGVkdWxlIGEgY2FsbGJhY2sgd2l0aCBEcmF3XG4gKiBcdFRvbmUuRHJhdy5zY2hlZHVsZSgoKSA9PiB7XG4gKiBcdFx0Ly8gZG8gZHJhd2luZyBvciBET00gbWFuaXB1bGF0aW9uIGhlcmVcbiAqIFx0XHRjb25zb2xlLmxvZyh0aW1lKTtcbiAqIFx0fSwgdGltZSk7XG4gKiB9LCBcIiswLjVcIik7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIERyYXcgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRyYXdcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkdXJhdGlvbiBhZnRlciB3aGljaCBldmVudHMgYXJlIG5vdCBpbnZva2VkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5leHBpcmF0aW9uID0gMC4yNTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbW91bnQgb2YgdGltZSBiZWZvcmUgdGhlIHNjaGVkdWxlZCB0aW1lXG4gICAgICAgICAqIHRoYXQgdGhlIGNhbGxiYWNrIGNhbiBiZSBpbnZva2VkLiBEZWZhdWx0IGlzXG4gICAgICAgICAqIGhhbGYgdGhlIHRpbWUgb2YgYW4gYW5pbWF0aW9uIGZyYW1lICgwLjAwOCBzZWNvbmRzKS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYW50aWNpcGF0aW9uID0gMC4wMDg7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGV2ZW50cy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRyYXcgbG9vcFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYm91bmREcmF3TG9vcCA9IHRoaXMuX2RyYXdMb29wLmJpbmQodGhpcyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYW5pbWF0aW9uIGZyYW1lIGlkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbmltYXRpb25GcmFtZSA9IC0xO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhIGZ1bmN0aW9uIGF0IHRoZSBnaXZlbiB0aW1lIHRvIGJlIGludm9rZWRcbiAgICAgKiBvbiB0aGUgbmVhcmVzdCBhbmltYXRpb24gZnJhbWUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgQ2FsbGJhY2sgaXMgaW52b2tlZCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgICBUaGUgdGltZSByZWxhdGl2ZSB0byB0aGUgQXVkaW9Db250ZXh0IHRpbWUgdG8gaW52b2tlIHRoZSBjYWxsYmFjay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KHRpbWUgPT4ge1xuICAgICAqIFx0VG9uZS5EcmF3LnNjaGVkdWxlKCgpID0+IGNvbnNvbGUubG9nKHRpbWUpLCB0aW1lKTtcbiAgICAgKiB9LCAxKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICAgICAqL1xuICAgIHNjaGVkdWxlKGNhbGxiYWNrLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICB0aW1lOiB0aGlzLnRvU2Vjb25kcyh0aW1lKSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBkcmF3IGxvb3Agb24gdGhlIGZpcnN0IGV2ZW50XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmltYXRpb25GcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLl9ib3VuZERyYXdMb29wKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGV2ZW50cyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIGFmdGVyICBUaW1lIGFmdGVyIHdoaWNoIHNjaGVkdWxlZCBldmVudHMgd2lsbCBiZSByZW1vdmVkIGZyb20gdGhlIHNjaGVkdWxpbmcgdGltZWxpbmUuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwodGhpcy50b1NlY29uZHMoYWZ0ZXIpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkcmF3IGxvb3BcbiAgICAgKi9cbiAgICBfZHJhd0xvb3AoKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgd2hpbGUgKHRoaXMuX2V2ZW50cy5sZW5ndGggJiYgdGhpcy5fZXZlbnRzLnBlZWsoKS50aW1lIC0gdGhpcy5hbnRpY2lwYXRpb24gPD0gbm93KSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2V2ZW50cy5zaGlmdCgpO1xuICAgICAgICAgICAgaWYgKGV2ZW50ICYmIG5vdyAtIGV2ZW50LnRpbWUgPD0gdGhpcy5leHBpcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgZXZlbnQuY2FsbGJhY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuX2JvdW5kRHJhd0xvb3ApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmRpc3Bvc2UoKTtcbiAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5fYW5pbWF0aW9uRnJhbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRyYXcgPSBuZXcgRHJhdyh7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZHJhdy5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURyYXcuanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuL0RlYnVnXCI7XG4vKipcbiAqIFNpbWlsYXIgdG8gVG9uZS5UaW1lbGluZSwgYnV0IGFsbCBldmVudHMgcmVwcmVzZW50XG4gKiBpbnRlcnZhbHMgd2l0aCBib3RoIFwidGltZVwiIGFuZCBcImR1cmF0aW9uXCIgdGltZXMuIFRoZVxuICogZXZlbnRzIGFyZSBwbGFjZWQgaW4gYSB0cmVlIHN0cnVjdHVyZSBvcHRpbWl6ZWRcbiAqIGZvciBxdWVyeWluZyBhbiBpbnRlcnNlY3Rpb24gcG9pbnQgd2l0aCB0aGUgdGltZWxpbmVcbiAqIGV2ZW50cy4gSW50ZXJuYWxseSB1c2VzIGFuIFtJbnRlcnZhbCBUcmVlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JbnRlcnZhbF90cmVlKVxuICogdG8gcmVwcmVzZW50IHRoZSBkYXRhLlxuICovXG5leHBvcnQgY2xhc3MgSW50ZXJ2YWxUaW1lbGluZSBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkludGVydmFsVGltZWxpbmVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSByb290IG5vZGUgb2YgdGhlIGludGV2YWwgdHJlZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcm9vdCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBsZW5ndGggb2YgdGhlIHRpbWVsaW5lLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbGVuZ3RoID0gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGV2ZW50IHRvIGFkZCB0byB0aGUgdGltZWxpbmUuIEFsbCBldmVudHMgbXVzdFxuICAgICAqIGhhdmUgYSB0aW1lIGFuZCBkdXJhdGlvbiB2YWx1ZVxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBldmVudCB0byBhZGQgdG8gdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgYWRkKGV2ZW50KSB7XG4gICAgICAgIGFzc2VydChpc0RlZmluZWQoZXZlbnQudGltZSksIFwiRXZlbnRzIG11c3QgaGF2ZSBhIHRpbWUgcHJvcGVydHlcIik7XG4gICAgICAgIGFzc2VydChpc0RlZmluZWQoZXZlbnQuZHVyYXRpb24pLCBcIkV2ZW50cyBtdXN0IGhhdmUgYSBkdXJhdGlvbiBwYXJhbWV0ZXJcIik7XG4gICAgICAgIGV2ZW50LnRpbWUgPSBldmVudC50aW1lLnZhbHVlT2YoKTtcbiAgICAgICAgbGV0IG5vZGUgPSBuZXcgSW50ZXJ2YWxOb2RlKGV2ZW50LnRpbWUsIGV2ZW50LnRpbWUgKyBldmVudC5kdXJhdGlvbiwgZXZlbnQpO1xuICAgICAgICBpZiAodGhpcy5fcm9vdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdCA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9yb290Lmluc2VydChub2RlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sZW5ndGgrKztcbiAgICAgICAgLy8gUmVzdHJ1Y3R1cmUgdHJlZSB0byBiZSBiYWxhbmNlZFxuICAgICAgICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbm9kZS51cGRhdGVIZWlnaHQoKTtcbiAgICAgICAgICAgIG5vZGUudXBkYXRlTWF4KCk7XG4gICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2Uobm9kZSk7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbiBldmVudCBmcm9tIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgZXZlbnQgdG8gcmVtb3ZlIGZyb20gdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgcmVtb3ZlKGV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnNlYXJjaChldmVudC50aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiByZXN1bHRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQgPT09IGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlbW92ZU5vZGUobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2xlbmd0aC0tO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqIEByZWFkT25seVxuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBldmVudHMgd2hvc2UgdGltZSB0aW1lIGlzIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIHRoaXMuZm9yRWFjaEZyb20oYWZ0ZXIsIGV2ZW50ID0+IHRoaXMucmVtb3ZlKGV2ZW50KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHJvb3Qgbm9kZSBhcyB0aGUgZ2l2ZW4gbm9kZVxuICAgICAqL1xuICAgIF9zZXRSb290KG5vZGUpIHtcbiAgICAgICAgdGhpcy5fcm9vdCA9IG5vZGU7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yb290LnBhcmVudCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVwbGFjZSB0aGUgcmVmZXJlbmNlcyB0byB0aGUgbm9kZSBpbiB0aGUgbm9kZSdzIHBhcmVudFxuICAgICAqIHdpdGggdGhlIHJlcGxhY2VtZW50IG5vZGUuXG4gICAgICovXG4gICAgX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgcmVwbGFjZW1lbnQpIHtcbiAgICAgICAgaWYgKG5vZGUucGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAobm9kZS5pc0xlZnRDaGlsZCgpKSB7XG4gICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQucmlnaHQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3JlYmFsYW5jZShub2RlLnBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRSb290KHJlcGxhY2VtZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhlIG5vZGUgZnJvbSB0aGUgdHJlZSBhbmQgcmVwbGFjZSBpdCB3aXRoXG4gICAgICogYSBzdWNjZXNzb3Igd2hpY2ggZm9sbG93cyB0aGUgc2NoZW1hLlxuICAgICAqL1xuICAgIF9yZW1vdmVOb2RlKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUubGVmdCA9PT0gbnVsbCAmJiBub2RlLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5vZGUucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgbm9kZS5sZWZ0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlcGxhY2VOb2RlSW5QYXJlbnQobm9kZSwgbm9kZS5yaWdodCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBiYWxhbmNlID0gbm9kZS5nZXRCYWxhbmNlKCk7XG4gICAgICAgICAgICBsZXQgcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICBsZXQgdGVtcCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoYmFsYW5jZSA+IDApIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5sZWZ0LnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5yaWdodCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5sZWZ0LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAocmVwbGFjZW1lbnQucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcGxhY2VtZW50LnBhcmVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucGFyZW50LnJpZ2h0ID0gcmVwbGFjZW1lbnQubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudC5wYXJlbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAobm9kZS5yaWdodC5sZWZ0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LmxlZnQgPSBub2RlLmxlZnQ7XG4gICAgICAgICAgICAgICAgdGVtcCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSBub2RlLnJpZ2h0LmxlZnQ7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHJlcGxhY2VtZW50LmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSByZXBsYWNlbWVudC5sZWZ0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmVwbGFjZW1lbnQucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQucmlnaHQ7XG4gICAgICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudC5wYXJlbnQ7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LmxlZnQgPSBub2RlLmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobm9kZS5wYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5pc0xlZnRDaGlsZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LnJpZ2h0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChyZXBsYWNlbWVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGVtcCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JlYmFsYW5jZSh0ZW1wKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBub2RlLmRpc3Bvc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUm90YXRlIHRoZSB0cmVlIHRvIHRoZSBsZWZ0XG4gICAgICovXG4gICAgX3JvdGF0ZUxlZnQobm9kZSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcbiAgICAgICAgY29uc3QgaXNMZWZ0Q2hpbGQgPSBub2RlLmlzTGVmdENoaWxkKCk7XG4gICAgICAgIC8vIE1ha2Ugbm9kZS5yaWdodCB0aGUgbmV3IHJvb3Qgb2YgdGhpcyBzdWIgdHJlZSAoaW5zdGVhZCBvZiBub2RlKVxuICAgICAgICBjb25zdCBwaXZvdE5vZGUgPSBub2RlLnJpZ2h0O1xuICAgICAgICBpZiAocGl2b3ROb2RlKSB7XG4gICAgICAgICAgICBub2RlLnJpZ2h0ID0gcGl2b3ROb2RlLmxlZnQ7XG4gICAgICAgICAgICBwaXZvdE5vZGUubGVmdCA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKGlzTGVmdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LmxlZnQgPSBwaXZvdE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQucmlnaHQgPSBwaXZvdE5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zZXRSb290KHBpdm90Tm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUm90YXRlIHRoZSB0cmVlIHRvIHRoZSByaWdodFxuICAgICAqL1xuICAgIF9yb3RhdGVSaWdodChub2RlKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50O1xuICAgICAgICBjb25zdCBpc0xlZnRDaGlsZCA9IG5vZGUuaXNMZWZ0Q2hpbGQoKTtcbiAgICAgICAgLy8gTWFrZSBub2RlLmxlZnQgdGhlIG5ldyByb290IG9mIHRoaXMgc3ViIHRyZWUgKGluc3RlYWQgb2Ygbm9kZSlcbiAgICAgICAgY29uc3QgcGl2b3ROb2RlID0gbm9kZS5sZWZ0O1xuICAgICAgICBpZiAocGl2b3ROb2RlKSB7XG4gICAgICAgICAgICBub2RlLmxlZnQgPSBwaXZvdE5vZGUucmlnaHQ7XG4gICAgICAgICAgICBwaXZvdE5vZGUucmlnaHQgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0xlZnRDaGlsZCkge1xuICAgICAgICAgICAgICAgIHBhcmVudC5sZWZ0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LnJpZ2h0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChwaXZvdE5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEJhbGFuY2UgdGhlIEJTVFxuICAgICAqL1xuICAgIF9yZWJhbGFuY2Uobm9kZSkge1xuICAgICAgICBjb25zdCBiYWxhbmNlID0gbm9kZS5nZXRCYWxhbmNlKCk7XG4gICAgICAgIGlmIChiYWxhbmNlID4gMSAmJiBub2RlLmxlZnQpIHtcbiAgICAgICAgICAgIGlmIChub2RlLmxlZnQuZ2V0QmFsYW5jZSgpIDwgMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZUxlZnQobm9kZS5sZWZ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZVJpZ2h0KG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGJhbGFuY2UgPCAtMSAmJiBub2RlLnJpZ2h0KSB7XG4gICAgICAgICAgICBpZiAobm9kZS5yaWdodC5nZXRCYWxhbmNlKCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlUmlnaHQobm9kZS5yaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVMZWZ0KG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhbiBldmVudCB3aG9zZSB0aW1lIGFuZCBkdXJhdGlvbiBzcGFuIHRoZSBnaXZlIHRpbWUuIFdpbGxcbiAgICAgKiByZXR1cm4gdGhlIG1hdGNoIHdob3NlIFwidGltZVwiIHZhbHVlIGlzIGNsb3Nlc3QgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHJldHVybiAgVGhlIGV2ZW50IHdoaWNoIHNwYW5zIHRoZSBkZXNpcmVkIHRpbWVcbiAgICAgKi9cbiAgICBnZXQodGltZSkge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2godGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IG1heCA9IHJlc3VsdHNbMF07XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCByZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHRzW2ldLmxvdyA+IG1heC5sb3cpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1heCA9IHJlc3VsdHNbaV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1heC5ldmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBhbGxOb2RlcyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC50cmF2ZXJzZShub2RlID0+IGFsbE5vZGVzLnB1c2gobm9kZSkpO1xuICAgICAgICAgICAgYWxsTm9kZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhub2RlLmV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGluIHdoaWNoIHRoZSBnaXZlbiB0aW1lXG4gICAgICogb3ZlcmxhcHMgd2l0aCB0aGUgdGltZSBhbmQgZHVyYXRpb24gdGltZSBvZiB0aGUgZXZlbnQuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBvdmVybGFwcGluZ1xuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQXRUaW1lKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnNlYXJjaCh0aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIHJlc3VsdHMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhub2RlLmV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGluIHdoaWNoIHRoZSB0aW1lIGlzIGdyZWF0ZXJcbiAgICAgKiB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hGcm9tKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgICAgICB0aGlzLl9yb290LnNlYXJjaEFmdGVyKHRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgcmVzdWx0cy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5vZGUuZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QudHJhdmVyc2Uobm9kZSA9PiBub2RlLmRpc3Bvc2UoKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcm9vdCA9IG51bGw7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTlRFUlZBTCBOT0RFIEhFTFBFUlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vKipcbiAqIFJlcHJlc2VudHMgYSBub2RlIGluIHRoZSBiaW5hcnkgc2VhcmNoIHRyZWUsIHdpdGggdGhlIGFkZGl0aW9uXG4gKiBvZiBhIFwiaGlnaFwiIHZhbHVlIHdoaWNoIGtlZXBzIHRyYWNrIG9mIHRoZSBoaWdoZXN0IHZhbHVlIG9mXG4gKiBpdHMgY2hpbGRyZW4uXG4gKiBSZWZlcmVuY2VzOlxuICogaHR0cHM6Ly9icm9va25vdmFrLndvcmRwcmVzcy5jb20vMjAxMy8xMi8wNy9hdWdtZW50ZWQtaW50ZXJ2YWwtdHJlZS1pbi1jL1xuICogaHR0cDovL3d3dy5taWYudnUubHQvfnZhbGRhcy9BTEdPUklUTUFJL0xJVEVSQVRVUkEvQ29ybWVuL0Nvcm1lbi5wZGZcbiAqIEBwYXJhbSBsb3dcbiAqIEBwYXJhbSBoaWdoXG4gKi9cbmNsYXNzIEludGVydmFsTm9kZSB7XG4gICAgY29uc3RydWN0b3IobG93LCBoaWdoLCBldmVudCkge1xuICAgICAgICAvLyB0aGUgbm9kZXMgdG8gdGhlIGxlZnRcbiAgICAgICAgdGhpcy5fbGVmdCA9IG51bGw7XG4gICAgICAgIC8vIHRoZSBub2RlcyB0byB0aGUgcmlnaHRcbiAgICAgICAgdGhpcy5fcmlnaHQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgcGFyZW50IG5vZGVcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgbnVtYmVyIG9mIGNoaWxkIG5vZGVzXG4gICAgICAgIHRoaXMuaGVpZ2h0ID0gMDtcbiAgICAgICAgdGhpcy5ldmVudCA9IGV2ZW50O1xuICAgICAgICAvLyB0aGUgbG93IHZhbHVlXG4gICAgICAgIHRoaXMubG93ID0gbG93O1xuICAgICAgICAvLyB0aGUgaGlnaCB2YWx1ZVxuICAgICAgICB0aGlzLmhpZ2ggPSBoaWdoO1xuICAgICAgICAvLyB0aGUgaGlnaCB2YWx1ZSBmb3IgdGhpcyBhbmQgYWxsIGNoaWxkIG5vZGVzXG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5oaWdoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnNlcnQgYSBub2RlIGludG8gdGhlIGNvcnJlY3Qgc3BvdCBpbiB0aGUgdHJlZVxuICAgICAqL1xuICAgIGluc2VydChub2RlKSB7XG4gICAgICAgIGlmIChub2RlLmxvdyA8PSB0aGlzLmxvdykge1xuICAgICAgICAgICAgaWYgKHRoaXMubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVmdCA9IG5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQuaW5zZXJ0KG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yaWdodC5pbnNlcnQobm9kZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VhcmNoIHRoZSB0cmVlIGZvciBub2RlcyB3aGljaCBvdmVybGFwXG4gICAgICogd2l0aCB0aGUgZ2l2ZW4gcG9pbnRcbiAgICAgKiBAcGFyYW0gIHBvaW50ICBUaGUgcG9pbnQgdG8gcXVlcnlcbiAgICAgKiBAcGFyYW0gIHJlc3VsdHMgIFRoZSBhcnJheSB0byBwdXQgdGhlIHJlc3VsdHNcbiAgICAgKi9cbiAgICBzZWFyY2gocG9pbnQsIHJlc3VsdHMpIHtcbiAgICAgICAgLy8gSWYgcCBpcyB0byB0aGUgcmlnaHQgb2YgdGhlIHJpZ2h0bW9zdCBwb2ludCBvZiBhbnkgaW50ZXJ2YWxcbiAgICAgICAgLy8gaW4gdGhpcyBub2RlIGFuZCBhbGwgY2hpbGRyZW4sIHRoZXJlIHdvbid0IGJlIGFueSBtYXRjaGVzLlxuICAgICAgICBpZiAocG9pbnQgPiB0aGlzLm1heCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlYXJjaCBsZWZ0IGNoaWxkcmVuXG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubGVmdC5zZWFyY2gocG9pbnQsIHJlc3VsdHMpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENoZWNrIHRoaXMgbm9kZVxuICAgICAgICBpZiAodGhpcy5sb3cgPD0gcG9pbnQgJiYgdGhpcy5oaWdoID4gcG9pbnQpIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiBwIGlzIHRvIHRoZSBsZWZ0IG9mIHRoZSB0aW1lIG9mIHRoaXMgaW50ZXJ2YWwsXG4gICAgICAgIC8vIHRoZW4gaXQgY2FuJ3QgYmUgaW4gYW55IGNoaWxkIHRvIHRoZSByaWdodC5cbiAgICAgICAgaWYgKHRoaXMubG93ID4gcG9pbnQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTZWFyY2ggcmlnaHQgY2hpbGRyZW5cbiAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQuc2VhcmNoKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWFyY2ggdGhlIHRyZWUgZm9yIG5vZGVzIHdoaWNoIGFyZSBsZXNzXG4gICAgICogdGhhbiB0aGUgZ2l2ZW4gcG9pbnRcbiAgICAgKiBAcGFyYW0gIHBvaW50ICBUaGUgcG9pbnQgdG8gcXVlcnlcbiAgICAgKiBAcGFyYW0gIHJlc3VsdHMgIFRoZSBhcnJheSB0byBwdXQgdGhlIHJlc3VsdHNcbiAgICAgKi9cbiAgICBzZWFyY2hBZnRlcihwb2ludCwgcmVzdWx0cykge1xuICAgICAgICAvLyBDaGVjayB0aGlzIG5vZGVcbiAgICAgICAgaWYgKHRoaXMubG93ID49IHBvaW50KSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2godGhpcyk7XG4gICAgICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0LnNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBzZWFyY2ggdGhlIHJpZ2h0IHNpZGVcbiAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQuc2VhcmNoQWZ0ZXIocG9pbnQsIHJlc3VsdHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2sgb24gdGhpcyBlbGVtZW50IGFuZCBib3RoIGl0J3MgYnJhbmNoZXNcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gIGNhbGxiYWNrXG4gICAgICovXG4gICAgdHJhdmVyc2UoY2FsbGJhY2spIHtcbiAgICAgICAgY2FsbGJhY2sodGhpcyk7XG4gICAgICAgIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubGVmdC50cmF2ZXJzZShjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQudHJhdmVyc2UoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgaGVpZ2h0IG9mIHRoZSBub2RlXG4gICAgICovXG4gICAgdXBkYXRlSGVpZ2h0KCkge1xuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsICYmIHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5sZWZ0LmhlaWdodCwgdGhpcy5yaWdodC5oZWlnaHQpICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMucmlnaHQuaGVpZ2h0ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gdGhpcy5sZWZ0LmhlaWdodCArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBoZWlnaHQgb2YgdGhlIG5vZGVcbiAgICAgKi9cbiAgICB1cGRhdGVNYXgoKSB7XG4gICAgICAgIHRoaXMubWF4ID0gdGhpcy5oaWdoO1xuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLm1heCA9IE1hdGgubWF4KHRoaXMubWF4LCB0aGlzLmxlZnQubWF4KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSBNYXRoLm1heCh0aGlzLm1heCwgdGhpcy5yaWdodC5tYXgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYWxhbmNlIGlzIGhvdyB0aGUgbGVhZnMgYXJlIGRpc3RyaWJ1dGVkIG9uIHRoZSBub2RlXG4gICAgICogQHJldHVybiAgTmVnYXRpdmUgbnVtYmVycyBhcmUgYmFsYW5jZWQgdG8gdGhlIHJpZ2h0XG4gICAgICovXG4gICAgZ2V0QmFsYW5jZSgpIHtcbiAgICAgICAgbGV0IGJhbGFuY2UgPSAwO1xuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsICYmIHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGJhbGFuY2UgPSB0aGlzLmxlZnQuaGVpZ2h0IC0gdGhpcy5yaWdodC5oZWlnaHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBiYWxhbmNlID0gdGhpcy5sZWZ0LmhlaWdodCArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgYmFsYW5jZSA9IC0odGhpcy5yaWdodC5oZWlnaHQgKyAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYmFsYW5jZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHJldHVybnMgdHJ1ZSBpZiB0aGlzIG5vZGUgaXMgdGhlIGxlZnQgY2hpbGQgb2YgaXRzIHBhcmVudFxuICAgICAqL1xuICAgIGlzTGVmdENoaWxkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQgIT09IG51bGwgJiYgdGhpcy5wYXJlbnQubGVmdCA9PT0gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogZ2V0L3NldCB0aGUgbGVmdCBub2RlXG4gICAgICovXG4gICAgZ2V0IGxlZnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZWZ0O1xuICAgIH1cbiAgICBzZXQgbGVmdChub2RlKSB7XG4gICAgICAgIHRoaXMuX2xlZnQgPSBub2RlO1xuICAgICAgICBpZiAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XG4gICAgICAgIHRoaXMudXBkYXRlTWF4KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGdldC9zZXQgdGhlIHJpZ2h0IG5vZGVcbiAgICAgKi9cbiAgICBnZXQgcmlnaHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yaWdodDtcbiAgICB9XG4gICAgc2V0IHJpZ2h0KG5vZGUpIHtcbiAgICAgICAgdGhpcy5fcmlnaHQgPSBub2RlO1xuICAgICAgICBpZiAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KCk7XG4gICAgICAgIHRoaXMudXBkYXRlTWF4KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIG51bGwgb3V0IHJlZmVyZW5jZXMuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fcmlnaHQgPSBudWxsO1xuICAgICAgICB0aGlzLmV2ZW50ID0gbnVsbDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1JbnRlcnZhbFRpbWVsaW5lLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL2Nsb2NrL0Nsb2NrXCI7XG4vLyBleHBvcnQgKiBmcm9tIFwiLi9jbG9jay9UcmFuc3BvcnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvQ29udGV4dFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9CYXNlQ29udGV4dFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9EZWxheVwiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9EZXN0aW5hdGlvblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9HYWluXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L09mZmxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvUGFyYW1cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9GcmVxdWVuY3lcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvTWlkaVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UaW1lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL1RpY2tzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCBcIi4vdXRpbC9EcmF3XCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL0VtaXR0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvSW50ZXJ2YWxUaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL1RpbWVsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL1R5cGVDaGVja1wiO1xuZXhwb3J0IHsgZGJUb0dhaW4sIGdhaW5Ub0RiLCBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8sIGZ0b20sIG10b2YgfSBmcm9tIFwiLi90eXBlL0NvbnZlcnNpb25zXCI7XG5leHBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cywgZGVmYXVsdEFyZyB9IGZyb20gXCIuL3V0aWwvRGVmYXVsdHNcIjtcbi8vIGdldCB0aGUgdW5pdHMgYW5kIGV4cG9ydCB0aGVtIHVuZGVyIHRoZSBcIlVuaXRcIiBuYW1lc3BhY2VcbmltcG9ydCAqIGFzIFVuaXQgZnJvbSBcIi4vdHlwZS9Vbml0c1wiO1xuZXhwb3J0IHsgVW5pdCB9O1xuLy8gZXhwb3J0IHRoZSBkZWJ1ZyBzdHVmZiBhcyBEZWJ1Z1xuaW1wb3J0ICogYXMgZGVidWcgZnJvbSBcIi4vdXRpbC9EZWJ1Z1wiO1xuZXhwb3J0IHsgZGVidWcgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBWb2x1bWUgaXMgYSBzaW1wbGUgdm9sdW1lIG5vZGUsIHVzZWZ1bCBmb3IgY3JlYXRpbmcgYSB2b2x1bWUgZmFkZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHZvbCA9IG5ldyBUb25lLlZvbHVtZSgtMTIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHZvbCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFZvbHVtZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhWb2x1bWUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJWb2x1bWVcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFZvbHVtZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5vdXRwdXQuZ2FpbjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgICAgIHRoaXMuX3VubXV0ZWRWb2x1bWUgPSBvcHRpb25zLnZvbHVtZTtcbiAgICAgICAgLy8gc2V0IHRoZSBtdXRlIGluaXRpYWxseVxuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHZvbCA9IG5ldyBUb25lLlZvbHVtZSgtMTIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdCh2b2wpLnN0YXJ0KCk7XG4gICAgICogLy8gbXV0ZSB0aGUgb3V0cHV0XG4gICAgICogdm9sLm11dGUgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52b2x1bWUudmFsdWUgPT09IC1JbmZpbml0eTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICBpZiAoIXRoaXMubXV0ZSAmJiBtdXRlKSB7XG4gICAgICAgICAgICB0aGlzLl91bm11dGVkVm9sdW1lID0gdGhpcy52b2x1bWUudmFsdWU7XG4gICAgICAgICAgICAvLyBtYXliZSBpdCBzaG91bGQgcmFtcCBoZXJlP1xuICAgICAgICAgICAgdGhpcy52b2x1bWUudmFsdWUgPSAtSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5tdXRlICYmICFtdXRlKSB7XG4gICAgICAgICAgICB0aGlzLnZvbHVtZS52YWx1ZSA9IHRoaXMuX3VubXV0ZWRWb2x1bWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVZvbHVtZS5qcy5tYXAiLCJpbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuL0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuL0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIEEgc2luZ2xlIG1hc3RlciBvdXRwdXQgd2hpY2ggaXMgY29ubmVjdGVkIHRvIHRoZVxuICogQXVkaW9EZXN0aW5hdGlvbk5vZGUgKGFrYSB5b3VyIHNwZWFrZXJzKS5cbiAqIEl0IHByb3ZpZGVzIHVzZWZ1bCBjb252ZW5pZW5jZXMgc3VjaCBhcyB0aGUgYWJpbGl0eVxuICogdG8gc2V0IHRoZSB2b2x1bWUgYW5kIG11dGUgdGhlIGVudGlyZSBhcHBsaWNhdGlvbi5cbiAqIEl0IGFsc28gZ2l2ZXMgeW91IHRoZSBhYmlsaXR5IHRvIGFwcGx5IG1hc3RlciBlZmZlY3RzIHRvIHlvdXIgYXBwbGljYXRpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuc3RhcnQoKTtcbiAqIC8vIHRoZSBhdWRpbyB3aWxsIGdvIGZyb20gdGhlIG9zY2lsbGF0b3IgdG8gdGhlIHNwZWFrZXJzXG4gKiBvc2NpbGxhdG9yLmNvbm5lY3QoVG9uZS5nZXREZXN0aW5hdGlvbigpKTtcbiAqIC8vIGEgY29udmVuaWVuY2UgZm9yIGNvbm5lY3RpbmcgdG8gdGhlIG1hc3RlciBvdXRwdXQgaXMgYWxzbyBwcm92aWRlZDpcbiAqIG9zY2lsbGF0b3IudG9EZXN0aW5hdGlvbigpO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIERlc3RpbmF0aW9uIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKERlc3RpbmF0aW9uLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRlc3RpbmF0aW9uXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgVm9sdW1lKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZvbHVtZSBvZiB0aGUgbWFzdGVyIG91dHB1dCBpbiBkZWNpYmVscy4gLUluZmluaXR5IGlzIHNpbGVudCwgYW5kIDAgaXMgbm8gY2hhbmdlLlxuICAgICAgICAgKiBAZXhhbXBsZVxuICAgICAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAgICAgKiBvc2Muc3RhcnQoKTtcbiAgICAgICAgICogLy8gcmFtcCB0aGUgdm9sdW1lIGRvd24gdG8gc2lsZW50IG92ZXIgMTAgc2Vjb25kc1xuICAgICAgICAgKiBUb25lLmdldERlc3RpbmF0aW9uKCkudm9sdW1lLnJhbXBUbygtSW5maW5pdHksIDEwKTtcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5pbnB1dC52b2x1bWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEZXN0aW5hdGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIHRoaXMub3V0cHV0LCB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmlucHV0LCB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5kZXN0aW5hdGlvbiwgdGhpcy5vdXRwdXRdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAqIFx0Ly8gbXV0ZSB0aGUgb3V0cHV0XG4gICAgICogXHRUb25lLkRlc3RpbmF0aW9uLm11dGUgPSB0cnVlO1xuICAgICAqIH0sIDEwMDApO1xuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuaW5wdXQubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIG1hc3RlciBlZmZlY3RzIGNoYWluLiBOT1RFOiB0aGlzIHdpbGwgZGlzY29ubmVjdCBhbnkgbm9kZXMgd2hpY2ggd2VyZSBwcmV2aW91c2x5XG4gICAgICogY2hhaW5lZCBpbiB0aGUgbWFzdGVyIGVmZmVjdHMgY2hhaW4uXG4gICAgICogQHBhcmFtIGFyZ3MgQWxsIGFyZ3VtZW50cyB3aWxsIGJlIGNvbm5lY3RlZCBpbiBhIHJvdyBhbmQgdGhlIE1hc3RlciB3aWxsIGJlIHJvdXRlZCB0aHJvdWdoIGl0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gcm91dGUgYWxsIGF1ZGlvIHRocm91Z2ggYSBmaWx0ZXIgYW5kIGNvbXByZXNzb3JcbiAgICAgKiBjb25zdCBsb3dwYXNzID0gbmV3IFRvbmUuRmlsdGVyKDgwMCwgXCJsb3dwYXNzXCIpO1xuICAgICAqIGNvbnN0IGNvbXByZXNzb3IgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0xOCk7XG4gICAgICogVG9uZS5EZXN0aW5hdGlvbi5jaGFpbihsb3dwYXNzLCBjb21wcmVzc29yKTtcbiAgICAgKi9cbiAgICBjaGFpbiguLi5hcmdzKSB7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICBhcmdzLnVuc2hpZnQodGhpcy5pbnB1dCk7XG4gICAgICAgIGFyZ3MucHVzaCh0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXMoLi4uYXJncyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2hhbm5lbHMgdGhlIHN5c3RlbSBjYW4gb3V0cHV0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zb2xlLmxvZyhUb25lLkRlc3RpbmF0aW9uLm1heENoYW5uZWxDb3VudCk7XG4gICAgICovXG4gICAgZ2V0IG1heENoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5yYXdDb250ZXh0LmRlc3RpbmF0aW9uLm1heENoYW5uZWxDb3VudDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kZXN0aW5hdGlvbiA9IG5ldyBEZXN0aW5hdGlvbih7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZGVzdGluYXRpb24uZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZXN0aW5hdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbi8qKlxuICogUmVwcmVzZW50cyBhIHNpbmdsZSB2YWx1ZSB3aGljaCBpcyBnZXR0YWJsZSBhbmQgc2V0dGFibGUgaW4gYSB0aW1lZCB3YXlcbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVsaW5lVmFsdWUgZXh0ZW5kcyBUb25lIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gaW5pdGlhbFZhbHVlIFRoZSB2YWx1ZSB0byByZXR1cm4gaWYgdGhlcmUgaXMgbm8gc2NoZWR1bGVkIHZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGluaXRpYWxWYWx1ZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVsaW5lVmFsdWVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lbGluZSB3aGljaCBzdG9yZXMgdGhlIHZhbHVlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBuZXcgVGltZWxpbmUoeyBtZW1vcnk6IDEwIH0pO1xuICAgICAgICB0aGlzLl9pbml0aWFsVmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKi9cbiAgICBzZXQodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuYWRkKHtcbiAgICAgICAgICAgIHZhbHVlLCB0aW1lXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqL1xuICAgIGdldCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmUuZ2V0KHRpbWUpO1xuICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudC52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lbGluZVZhbHVlLmpzLm1hcCIsImltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogVHJhbnNwb3J0RXZlbnQgaXMgYW4gaW50ZXJuYWwgY2xhc3MgdXNlZCBieSBbW1RyYW5zcG9ydF1dXG4gKiB0byBzY2hlZHVsZSBldmVudHMuIERvIG5vIGludm9rZSB0aGlzIGNsYXNzIGRpcmVjdGx5LCBpdCBpc1xuICogaGFuZGxlZCBmcm9tIHdpdGhpbiBUb25lLlRyYW5zcG9ydC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zcG9ydEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gdHJhbnNwb3J0IFRoZSB0cmFuc3BvcnQgb2JqZWN0IHdoaWNoIHRoZSBldmVudCBiZWxvbmdzIHRvXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHJhbnNwb3J0LCBvcHRzKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdW5pcXVlIGlkIG9mIHRoZSBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pZCA9IFRyYW5zcG9ydEV2ZW50Ll9ldmVudElkKys7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBPYmplY3QuYXNzaWduKFRyYW5zcG9ydEV2ZW50LmdldERlZmF1bHRzKCksIG9wdHMpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX29uY2UgPSBvcHRpb25zLm9uY2U7XG4gICAgICAgIHRoaXMudGltZSA9IG9wdGlvbnMudGltZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgICAgIHRpbWU6IDAsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgZXZlbnQgY2FsbGJhY2suXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgQXVkaW9Db250ZXh0IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBpbnZva2UodGltZSkge1xuICAgICAgICBpZiAodGhpcy5jYWxsYmFjaykge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vbmNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQuY2xlYXIodGhpcy5pZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEN1cnJlbnQgSUQgY291bnRlclxuICovXG5UcmFuc3BvcnRFdmVudC5fZXZlbnRJZCA9IDA7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmFuc3BvcnRFdmVudC5qcy5tYXAiLCJpbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IFRyYW5zcG9ydEV2ZW50IH0gZnJvbSBcIi4vVHJhbnNwb3J0RXZlbnRcIjtcbi8qKlxuICogVHJhbnNwb3J0UmVwZWF0RXZlbnQgaXMgYW4gaW50ZXJuYWwgY2xhc3MgdXNlZCBieSBUb25lLlRyYW5zcG9ydFxuICogdG8gc2NoZWR1bGUgcmVwZWF0IGV2ZW50cy4gVGhpcyBjbGFzcyBzaG91bGQgbm90IGJlIGluc3RhbnRpYXRlZCBkaXJlY3RseS5cbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zcG9ydFJlcGVhdEV2ZW50IGV4dGVuZHMgVHJhbnNwb3J0RXZlbnQge1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB0cmFuc3BvcnQgVGhlIHRyYW5zcG9ydCBvYmplY3Qgd2hpY2ggdGhlIGV2ZW50IGJlbG9uZ3MgdG9cbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0cmFuc3BvcnQsIG9wdHMpIHtcbiAgICAgICAgc3VwZXIodHJhbnNwb3J0LCBvcHRzKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBJRCBvZiB0aGUgY3VycmVudCB0aW1lbGluZSBldmVudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY3VycmVudElkID0gLTE7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSUQgb2YgdGhlIG5leHQgdGltZWxpbmUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX25leHRJZCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWUgb2YgdGhlIG5leHQgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX25leHRUaWNrID0gdGhpcy50aW1lO1xuICAgICAgICAvKipcbiAgICAgICAgICogYSByZWZlcmVuY2UgdG8gdGhlIGJvdW5kIHN0YXJ0IG1ldGhvZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYm91bmRSZXN0YXJ0ID0gdGhpcy5fcmVzdGFydC5iaW5kKHRoaXMpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gT2JqZWN0LmFzc2lnbihUcmFuc3BvcnRSZXBlYXRFdmVudC5nZXREZWZhdWx0cygpLCBvcHRzKTtcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IG5ldyBUaWNrc0NsYXNzKHRyYW5zcG9ydC5jb250ZXh0LCBvcHRpb25zLmR1cmF0aW9uKS52YWx1ZU9mKCk7XG4gICAgICAgIHRoaXMuX2ludGVydmFsID0gbmV3IFRpY2tzQ2xhc3ModHJhbnNwb3J0LmNvbnRleHQsIG9wdGlvbnMuaW50ZXJ2YWwpLnZhbHVlT2YoKTtcbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgPSBvcHRpb25zLnRpbWU7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9uKFwic3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQub24oXCJsb29wU3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgdGhpcy5jb250ZXh0ID0gdGhpcy50cmFuc3BvcnQuY29udGV4dDtcbiAgICAgICAgdGhpcy5fcmVzdGFydCgpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBUcmFuc3BvcnRFdmVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkdXJhdGlvbjogSW5maW5pdHksXG4gICAgICAgICAgICBpbnRlcnZhbDogMSxcbiAgICAgICAgICAgIG9uY2U6IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlIHRoZSBjYWxsYmFjay4gUmV0dXJucyB0aGUgdGljayB0aW1lIHdoaWNoXG4gICAgICogdGhlIG5leHQgZXZlbnQgc2hvdWxkIGJlIHNjaGVkdWxlZCBhdC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSBBdWRpb0NvbnRleHQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBldmVudFxuICAgICAqL1xuICAgIGludm9rZSh0aW1lKSB7XG4gICAgICAgIC8vIGNyZWF0ZSBtb3JlIGV2ZW50cyBpZiBuZWNlc3NhcnlcbiAgICAgICAgdGhpcy5fY3JlYXRlRXZlbnRzKHRpbWUpO1xuICAgICAgICAvLyBjYWxsIHRoZSBzdXBlciBjbGFzc1xuICAgICAgICBzdXBlci5pbnZva2UodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1c2ggbW9yZSBldmVudHMgb250byB0aGUgdGltZWxpbmUgdG8ga2VlcCB1cCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgdGltZWxpbmVcbiAgICAgKi9cbiAgICBfY3JlYXRlRXZlbnRzKHRpbWUpIHtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIG5leHQgZXZlbnRcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKHRpY2tzID49IHRoaXMudGltZSAmJiB0aWNrcyA+PSB0aGlzLl9uZXh0VGljayAmJiB0aGlzLl9uZXh0VGljayArIHRoaXMuX2ludGVydmFsIDwgdGhpcy50aW1lICsgdGhpcy5kdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5fbmV4dFRpY2sgKz0gdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50SWQgPSB0aGlzLl9uZXh0SWQ7XG4gICAgICAgICAgICB0aGlzLl9uZXh0SWQgPSB0aGlzLnRyYW5zcG9ydC5zY2hlZHVsZU9uY2UodGhpcy5pbnZva2UuYmluZCh0aGlzKSwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9uZXh0VGljaykudG9TZWNvbmRzKCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1c2ggbW9yZSBldmVudHMgb250byB0aGUgdGltZWxpbmUgdG8ga2VlcCB1cCB3aXRoIHRoZSBwb3NpdGlvbiBvZiB0aGUgdGltZWxpbmVcbiAgICAgKi9cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuX2N1cnJlbnRJZCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuX25leHRJZCk7XG4gICAgICAgIHRoaXMuX25leHRUaWNrID0gdGhpcy50aW1lO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudHJhbnNwb3J0LmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAodGlja3MgPiB0aGlzLnRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25leHRUaWNrID0gdGhpcy50aW1lICsgTWF0aC5jZWlsKCh0aWNrcyAtIHRoaXMudGltZSkgLyB0aGlzLl9pbnRlcnZhbCkgKiB0aGlzLl9pbnRlcnZhbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9jdXJyZW50SWQgPSB0aGlzLnRyYW5zcG9ydC5zY2hlZHVsZU9uY2UodGhpcy5pbnZva2UuYmluZCh0aGlzKSwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9uZXh0VGljaykudG9TZWNvbmRzKCkpO1xuICAgICAgICB0aGlzLl9uZXh0VGljayArPSB0aGlzLl9pbnRlcnZhbDtcbiAgICAgICAgdGhpcy5fbmV4dElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuX2N1cnJlbnRJZCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuX25leHRJZCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9mZihcInN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9mZihcImxvb3BTdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmFuc3BvcnRSZXBlYXRFdmVudC5qcy5tYXAiLCJpbXBvcnQgeyBUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL1RpbWVcIjtcbmltcG9ydCB7IFRpbWVsaW5lVmFsdWUgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1RpbWVsaW5lVmFsdWVcIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVtaXR0ZXIgfSBmcm9tIFwiLi4vdXRpbC9FbWl0dGVyXCI7XG5pbXBvcnQgeyByZWFkT25seSwgd3JpdGFibGUgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEludGVydmFsVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcnZhbFRpbWVsaW5lXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IENsb2NrIH0gZnJvbSBcIi4vQ2xvY2tcIjtcbmltcG9ydCB7IFRyYW5zcG9ydEV2ZW50IH0gZnJvbSBcIi4vVHJhbnNwb3J0RXZlbnRcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFJlcGVhdEV2ZW50IH0gZnJvbSBcIi4vVHJhbnNwb3J0UmVwZWF0RXZlbnRcIjtcbi8qKlxuICogVHJhbnNwb3J0IGZvciB0aW1pbmcgbXVzaWNhbCBldmVudHMuXG4gKiBTdXBwb3J0cyB0ZW1wbyBjdXJ2ZXMgYW5kIHRpbWUgY2hhbmdlcy4gVW5saWtlIGJyb3dzZXItYmFzZWQgdGltaW5nIChzZXRJbnRlcnZhbCwgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKVxuICogVHJhbnNwb3J0IHRpbWluZyBldmVudHMgcGFzcyBpbiB0aGUgZXhhY3QgdGltZSBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50XG4gKiBpbiB0aGUgYXJndW1lbnQgb2YgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uLiBQYXNzIHRoYXQgdGltZSB2YWx1ZSB0byB0aGUgb2JqZWN0XG4gKiB5b3UncmUgc2NoZWR1bGluZy4gPGJyPjxicj5cbiAqIEEgc2luZ2xlIHRyYW5zcG9ydCBpcyBjcmVhdGVkIGZvciB5b3Ugd2hlbiB0aGUgbGlicmFyeSBpcyBpbml0aWFsaXplZC5cbiAqIDxicj48YnI+XG4gKiBUaGUgdHJhbnNwb3J0IGVtaXRzIHRoZSBldmVudHM6IFwic3RhcnRcIiwgXCJzdG9wXCIsIFwicGF1c2VcIiwgYW5kIFwibG9vcFwiIHdoaWNoIGFyZVxuICogY2FsbGVkIHdpdGggdGhlIHRpbWUgb2YgdGhhdCBldmVudCBhcyB0aGUgYXJndW1lbnQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyByZXBlYXRlZCBldmVudCBldmVyeSA4dGggbm90ZVxuICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQoKHRpbWUpID0+IHtcbiAqIFx0Ly8gdXNlIHRoZSBjYWxsYmFjayB0aW1lIHRvIHNjaGVkdWxlIGV2ZW50c1xuICogXHRvc2Muc3RhcnQodGltZSkuc3RvcCh0aW1lICsgMC4xKTtcbiAqIH0sIFwiOG5cIik7XG4gKiAvLyB0cmFuc3BvcnQgbXVzdCBiZSBzdGFydGVkIGJlZm9yZSBpdCBzdGFydHMgaW52b2tpbmcgZXZlbnRzXG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zcG9ydCBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRyYW5zcG9ydC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUcmFuc3BvcnRcIjtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFx0TE9PUElOR1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoZSB0cmFuc3BvcnQgbG9vcHMgb3Igbm90LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcCA9IG5ldyBUaW1lbGluZVZhbHVlKGZhbHNlKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb29wIHN0YXJ0IHBvc2l0aW9uIGluIHRpY2tzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvb3AgZW5kIHBvc2l0aW9uIGluIHRpY2tzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gMDtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFx0VElNRUxJTkUgRVZFTlRTXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIHRoZSBldmVudHMgaW4gYW4gb2JqZWN0IHRvIGtlZXAgdHJhY2sgYnkgSURcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IHt9O1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHNjaGVkdWxlZCBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lbGluZSA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVwZWF0ZWQgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cyA9IG5ldyBJbnRlcnZhbFRpbWVsaW5lKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIHN5bmNlZCBTaWduYWxzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zeW5jZWRTaWduYWxzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3dpbmcgYW1vdW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zd2luZ0Ftb3VudCA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUcmFuc3BvcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgLy8gQ0xPQ0svVEVNUE9cbiAgICAgICAgdGhpcy5fcHBxID0gb3B0aW9ucy5wcHE7XG4gICAgICAgIHRoaXMuX2Nsb2NrID0gbmV3IENsb2NrKHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl9wcm9jZXNzVGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgdW5pdHM6IFwiYnBtXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9iaW5kQ2xvY2tFdmVudHMoKTtcbiAgICAgICAgdGhpcy5icG0gPSB0aGlzLl9jbG9jay5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5tdWx0aXBsaWVyID0gb3B0aW9ucy5wcHE7XG4gICAgICAgIHRoaXMuYnBtLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMuYnBtLCAwKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJicG1cIik7XG4gICAgICAgIHRoaXMuX3RpbWVTaWduYXR1cmUgPSBvcHRpb25zLnRpbWVTaWduYXR1cmU7XG4gICAgICAgIC8vIFNXSU5HXG4gICAgICAgIHRoaXMuX3N3aW5nVGlja3MgPSBvcHRpb25zLnBwcSAvIDI7IC8vIDhuXG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJwbTogMTIwLFxuICAgICAgICAgICAgbG9vcEVuZDogXCI0bVwiLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgcHBxOiAxOTIsXG4gICAgICAgICAgICBzd2luZzogMCxcbiAgICAgICAgICAgIHN3aW5nU3ViZGl2aXNpb246IFwiOG5cIixcbiAgICAgICAgICAgIHRpbWVTaWduYXR1cmU6IDQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFRJQ0tTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogY2FsbGVkIG9uIGV2ZXJ5IHRpY2tcbiAgICAgKiBAcGFyYW0gIHRpY2tUaW1lIGNsb2NrIHJlbGF0aXZlIHRpY2sgdGltZVxuICAgICAqL1xuICAgIF9wcm9jZXNzVGljayh0aWNrVGltZSwgdGlja3MpIHtcbiAgICAgICAgLy8gZG8gdGhlIGxvb3AgdGVzdFxuICAgICAgICBpZiAodGhpcy5fbG9vcC5nZXQodGlja1RpbWUpKSB7XG4gICAgICAgICAgICBpZiAodGlja3MgPj0gdGhpcy5fbG9vcEVuZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcImxvb3BFbmRcIiwgdGlja1RpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Nsb2NrLnNldFRpY2tzQXRUaW1lKHRoaXMuX2xvb3BTdGFydCwgdGlja1RpbWUpO1xuICAgICAgICAgICAgICAgIHRpY2tzID0gdGhpcy5fbG9vcFN0YXJ0O1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcImxvb3BTdGFydFwiLCB0aWNrVGltZSwgdGhpcy5fY2xvY2suZ2V0U2Vjb25kc0F0VGltZSh0aWNrVGltZSkpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcImxvb3BcIiwgdGlja1RpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGhhbmRsZSBzd2luZ1xuICAgICAgICBpZiAodGhpcy5fc3dpbmdBbW91bnQgPiAwICYmXG4gICAgICAgICAgICB0aWNrcyAlIHRoaXMuX3BwcSAhPT0gMCAmJiAvLyBub3Qgb24gYSBkb3duYmVhdFxuICAgICAgICAgICAgdGlja3MgJSAodGhpcy5fc3dpbmdUaWNrcyAqIDIpICE9PSAwKSB7XG4gICAgICAgICAgICAvLyBhZGQgc29tZSBzd2luZ1xuICAgICAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSAodGlja3MgJSAodGhpcy5fc3dpbmdUaWNrcyAqIDIpKSAvICh0aGlzLl9zd2luZ1RpY2tzICogMik7XG4gICAgICAgICAgICBjb25zdCBhbW91bnQgPSBNYXRoLnNpbigocHJvZ3Jlc3MpICogTWF0aC5QSSkgKiB0aGlzLl9zd2luZ0Ftb3VudDtcbiAgICAgICAgICAgIHRpY2tUaW1lICs9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fc3dpbmdUaWNrcyAqIDIgLyAzKS50b1NlY29uZHMoKSAqIGFtb3VudDtcbiAgICAgICAgfVxuICAgICAgICAvLyBpbnZva2UgdGhlIHRpbWVsaW5lIGV2ZW50cyBzY2hlZHVsZWQgb24gdGhpcyB0aWNrXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmZvckVhY2hBdFRpbWUodGlja3MsIGV2ZW50ID0+IGV2ZW50Lmludm9rZSh0aWNrVGltZSkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNDSEVEVUxBQkxFIEVWRU5UU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGFuIGV2ZW50IGFsb25nIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGJlIGludm9rZWQgYXQgdGhlIHRpbWUuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdG8gaW52b2tlIHRoZSBjYWxsYmFjayBhdC5cbiAgICAgKiBAcmV0dXJuIFRoZSBpZCBvZiB0aGUgZXZlbnQgd2hpY2ggY2FuIGJlIHVzZWQgZm9yIGNhbmNlbGluZyB0aGUgZXZlbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBzY2hlZHVsZSBhbiBldmVudCBvbiB0aGUgMTZ0aCBtZWFzdXJlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGUoKHRpbWUpID0+IHtcbiAgICAgKiBcdC8vIGludm9rZWQgb24gbWVhc3VyZSAxNlxuICAgICAqIFx0Y29uc29sZS5sb2coXCJtZWFzdXJlIDE2IVwiKTtcbiAgICAgKiB9LCBcIjE2OjA6MFwiKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIHRpbWU6IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1RpY2tzKCksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkRXZlbnQoZXZlbnQsIHRoaXMuX3RpbWVsaW5lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYSByZXBlYXRlZCBldmVudCBhbG9uZyB0aGUgdGltZWxpbmUuIFRoZSBldmVudCB3aWxsIGZpcmVcbiAgICAgKiBhdCB0aGUgYGludGVydmFsYCBzdGFydGluZyBhdCB0aGUgYHN0YXJ0VGltZWAgYW5kIGZvciB0aGUgc3BlY2lmaWVkXG4gICAgICogYGR1cmF0aW9uYC5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZS5cbiAgICAgKiBAcGFyYW0gIGludGVydmFsICAgVGhlIGR1cmF0aW9uIGJldHdlZW4gc3VjY2Vzc2l2ZSBjYWxsYmFja3MuIE11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXIuXG4gICAgICogQHBhcmFtICBzdGFydFRpbWUgIFdoZW4gYWxvbmcgdGhlIHRpbWVsaW5lIHRoZSBldmVudHMgc2hvdWxkIHN0YXJ0IGJlaW5nIGludm9rZWQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgZXZlbnQgc2hvdWxkIHJlcGVhdC5cbiAgICAgKiBAcmV0dXJuICBUaGUgSUQgb2YgdGhlIHNjaGVkdWxlZCBldmVudC4gVXNlIHRoaXMgdG8gY2FuY2VsIHRoZSBldmVudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiAvLyBhIGNhbGxiYWNrIGludm9rZWQgZXZlcnkgZWlnaHRoIG5vdGUgYWZ0ZXIgdGhlIGZpcnN0IG1lYXN1cmVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCgodGltZSkgPT4ge1xuICAgICAqIFx0b3NjLnN0YXJ0KHRpbWUpLnN0b3AodGltZSArIDAuMSk7XG4gICAgICogfSwgXCI4blwiLCBcIjFtXCIpO1xuICAgICAqL1xuICAgIHNjaGVkdWxlUmVwZWF0KGNhbGxiYWNrLCBpbnRlcnZhbCwgc3RhcnRUaW1lLCBkdXJhdGlvbiA9IEluZmluaXR5KSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IFRyYW5zcG9ydFJlcGVhdEV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgZHVyYXRpb246IG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBkdXJhdGlvbikudG9UaWNrcygpLFxuICAgICAgICAgICAgaW50ZXJ2YWw6IG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBpbnRlcnZhbCkudG9UaWNrcygpLFxuICAgICAgICAgICAgdGltZTogbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8ga2ljayBpdCBvZmYgaWYgdGhlIFRyYW5zcG9ydCBpcyBzdGFydGVkXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl9yZXBlYXRlZEV2ZW50cyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGFuIGV2ZW50IHRoYXQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIGl0IGlzIGludm9rZWQuXG4gICAgICogQHBhcmFtIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugb25jZS5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0aGUgY2FsbGJhY2sgc2hvdWxkIGJlIGludm9rZWQuXG4gICAgICogQHJldHVybnMgVGhlIElEIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQuXG4gICAgICovXG4gICAgc2NoZWR1bGVPbmNlKGNhbGxiYWNrLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gbmV3IFRyYW5zcG9ydEV2ZW50KHRoaXMsIHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgb25jZTogdHJ1ZSxcbiAgICAgICAgICAgIHRpbWU6IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1RpY2tzKCksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy5fYWRkRXZlbnQoZXZlbnQsIHRoaXMuX3RpbWVsaW5lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXIgdGhlIHBhc3NlZCBpbiBldmVudCBpZCBmcm9tIHRoZSB0aW1lbGluZVxuICAgICAqIEBwYXJhbSBldmVudElkIFRoZSBpZCBvZiB0aGUgZXZlbnQuXG4gICAgICovXG4gICAgY2xlYXIoZXZlbnRJZCkge1xuICAgICAgICBpZiAodGhpcy5fc2NoZWR1bGVkRXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50SWQpKSB7XG4gICAgICAgICAgICBjb25zdCBpdGVtID0gdGhpcy5fc2NoZWR1bGVkRXZlbnRzW2V2ZW50SWQudG9TdHJpbmcoKV07XG4gICAgICAgICAgICBpdGVtLnRpbWVsaW5lLnJlbW92ZShpdGVtLmV2ZW50KTtcbiAgICAgICAgICAgIGl0ZW0uZXZlbnQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudElkLnRvU3RyaW5nKCldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYW4gZXZlbnQgdG8gdGhlIGNvcnJlY3QgdGltZWxpbmUuIEtlZXAgdHJhY2sgb2YgdGhlXG4gICAgICogdGltZWxpbmUgaXQgd2FzIGFkZGVkIHRvLlxuICAgICAqIEByZXR1cm5zIHRoZSBldmVudCBpZCB3aGljaCB3YXMganVzdCBhZGRlZFxuICAgICAqL1xuICAgIF9hZGRFdmVudChldmVudCwgdGltZWxpbmUpIHtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzW2V2ZW50LmlkLnRvU3RyaW5nKCldID0ge1xuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICB0aW1lbGluZSxcbiAgICAgICAgfTtcbiAgICAgICAgdGltZWxpbmUuYWRkKGV2ZW50KTtcbiAgICAgICAgcmV0dXJuIGV2ZW50LmlkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgc2NoZWR1bGVkIGV2ZW50cyBmcm9tIHRoZSB0aW1lbGluZSBhZnRlclxuICAgICAqIHRoZSBnaXZlbiB0aW1lLiBSZXBlYXRlZCBldmVudHMgd2lsbCBiZSByZW1vdmVkXG4gICAgICogaWYgdGhlaXIgc3RhcnRUaW1lIGlzIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtIGFmdGVyIENsZWFyIGFsbCBldmVudHMgYWZ0ZXIgdGhpcyB0aW1lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlciA9IDApIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRBZnRlciA9IHRoaXMudG9UaWNrcyhhZnRlcik7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmZvckVhY2hGcm9tKGNvbXB1dGVkQWZ0ZXIsIGV2ZW50ID0+IHRoaXMuY2xlYXIoZXZlbnQuaWQpKTtcbiAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMuZm9yRWFjaEZyb20oY29tcHV0ZWRBZnRlciwgZXZlbnQgPT4gdGhpcy5jbGVhcihldmVudC5pZCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTVEFSVC9TVE9QL1BBVVNFXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQmluZCBzdGFydC9zdG9wL3BhdXNlIGV2ZW50cyBmcm9tIHRoZSBjbG9jayBhbmQgZW1pdCB0aGVtLlxuICAgICAqL1xuICAgIF9iaW5kQ2xvY2tFdmVudHMoKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLm9uKFwic3RhcnRcIiwgKHRpbWUsIG9mZnNldCkgPT4ge1xuICAgICAgICAgICAgb2Zmc2V0ID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBvZmZzZXQpLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgdGltZSwgb2Zmc2V0KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLm9uKFwic3RvcFwiLCAodGltZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLm9uKFwicGF1c2VcIiwgKHRpbWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInBhdXNlXCIsIHRpbWUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiwgb3IgXCJwYXVzZWRcIlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmdldFN0YXRlQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgdHJhbnNwb3J0IHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgdGltZWxpbmUgb2Zmc2V0IHRvIHN0YXJ0IHRoZSB0cmFuc3BvcnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0IGluIG9uZSBzZWNvbmQgc3RhcnRpbmcgYXQgYmVnaW5uaW5nIG9mIHRoZSA1dGggbWVhc3VyZS5cbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdGFydChcIisxXCIsIFwiNDowOjBcIik7XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGxldCBvZmZzZXRUaWNrcztcbiAgICAgICAgaWYgKGlzRGVmaW5lZChvZmZzZXQpKSB7XG4gICAgICAgICAgICBvZmZzZXRUaWNrcyA9IHRoaXMudG9UaWNrcyhvZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBjbG9ja1xuICAgICAgICB0aGlzLl9jbG9jay5zdGFydCh0aW1lLCBvZmZzZXRUaWNrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIHRyYW5zcG9ydCBzaG91bGQgc3RvcC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0b3AoKTtcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fY2xvY2suc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhdXNlIHRoZSB0cmFuc3BvcnQgYW5kIGFsbCBzb3VyY2VzIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0LlxuICAgICAqL1xuICAgIHBhdXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fY2xvY2sucGF1c2UodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUb2dnbGUgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHRyYW5zcG9ydC4gSWYgaXQgaXNcbiAgICAgKiBzdGFydGVkLCBpdCB3aWxsIHN0b3AgaXQsIG90aGVyd2lzZSBpdCB3aWxsIHN0YXJ0IHRoZSBUcmFuc3BvcnQuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIG9mIHRoZSBldmVudFxuICAgICAqL1xuICAgIHRvZ2dsZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX2Nsb2NrLmdldFN0YXRlQXRUaW1lKHRpbWUpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5zdGFydCh0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCh0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTRVRURVJTL0dFVFRFUlNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaWduYXR1cmUgYXMganVzdCB0aGUgbnVtZXJhdG9yIG92ZXIgNC5cbiAgICAgKiBGb3IgZXhhbXBsZSA0LzQgd291bGQgYmUganVzdCA0IGFuZCA2Lzggd291bGQgYmUgMy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGNvbW1vbiB0aW1lXG4gICAgICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZSA9IDQ7XG4gICAgICogLy8gNy84XG4gICAgICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZSA9IFs3LCA4XTtcbiAgICAgKiAvLyB0aGlzIHdpbGwgYmUgcmVkdWNlZCB0byBhIHNpbmdsZSBudW1iZXJcbiAgICAgKiBUb25lLlRyYW5zcG9ydC50aW1lU2lnbmF0dXJlOyAvLyByZXR1cm5zIDMuNVxuICAgICAqL1xuICAgIGdldCB0aW1lU2lnbmF0dXJlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZVNpZ25hdHVyZTtcbiAgICB9XG4gICAgc2V0IHRpbWVTaWduYXR1cmUodGltZVNpZykge1xuICAgICAgICBpZiAoaXNBcnJheSh0aW1lU2lnKSkge1xuICAgICAgICAgICAgdGltZVNpZyA9ICh0aW1lU2lnWzBdIC8gdGltZVNpZ1sxXSkgKiA0O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RpbWVTaWduYXR1cmUgPSB0aW1lU2lnO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBUcmFuc3BvcnQubG9vcCA9IHRydWUsIHRoaXMgaXMgdGhlIHN0YXJ0aW5nIHBvc2l0aW9uIG9mIHRoZSBsb29wLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcFN0YXJ0LCBcImlcIikudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQoc3RhcnRQb3NpdGlvbikge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3Moc3RhcnRQb3NpdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIFRyYW5zcG9ydC5sb29wID0gdHJ1ZSwgdGhpcyBpcyB0aGUgZW5kaW5nIHBvc2l0aW9uIG9mIHRoZSBsb29wLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BFbmQsIFwiaVwiKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQoZW5kUG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhlbmRQb3NpdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSB0cmFuc3BvcnQgbG9vcHMgb3Igbm90LlxuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcC5nZXQodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fbG9vcC5zZXQobG9vcCwgdGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgbG9vcCBzdGFydCBhbmQgc3RvcCBhdCB0aGUgc2FtZSB0aW1lLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gbG9vcCBvdmVyIHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2V0TG9vcFBvaW50cygwLCBcIjFtXCIpO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3AgPSB0cnVlO1xuICAgICAqL1xuICAgIHNldExvb3BQb2ludHMoc3RhcnRQb3NpdGlvbiwgZW5kUG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBzdGFydFBvc2l0aW9uO1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBlbmRQb3NpdGlvbjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzd2luZyB2YWx1ZS4gQmV0d2VlbiAwLTEgd2hlcmUgMSBlcXVhbCB0byB0aGUgbm90ZSArIGhhbGYgdGhlIHN1YmRpdmlzaW9uLlxuICAgICAqL1xuICAgIGdldCBzd2luZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N3aW5nQW1vdW50O1xuICAgIH1cbiAgICBzZXQgc3dpbmcoYW1vdW50KSB7XG4gICAgICAgIC8vIHNjYWxlIHRoZSB2YWx1ZXMgdG8gYSBub3JtYWwgcmFuZ2VcbiAgICAgICAgdGhpcy5fc3dpbmdBbW91bnQgPSBhbW91bnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgc3ViZGl2aXNpb24gd2hpY2ggdGhlIHN3aW5nIHdpbGwgYmUgYXBwbGllZCB0by5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBhbiA4dGggbm90ZS4gVmFsdWUgbXVzdCBiZSBsZXNzXG4gICAgICogdGhhbiBhIHF1YXJ0ZXIgbm90ZS5cbiAgICAgKi9cbiAgICBnZXQgc3dpbmdTdWJkaXZpc2lvbigpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fc3dpbmdUaWNrcykudG9Ob3RhdGlvbigpO1xuICAgIH1cbiAgICBzZXQgc3dpbmdTdWJkaXZpc2lvbihzdWJkaXZpc2lvbikge1xuICAgICAgICB0aGlzLl9zd2luZ1RpY2tzID0gdGhpcy50b1RpY2tzKHN1YmRpdmlzaW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIFRyYW5zcG9ydCdzIHBvc2l0aW9uIGluIEJhcnM6QmVhdHM6U2l4dGVlbnRocy5cbiAgICAgKiBTZXR0aW5nIHRoZSB2YWx1ZSB3aWxsIGp1bXAgdG8gdGhhdCBwb3NpdGlvbiByaWdodCBhd2F5LlxuICAgICAqL1xuICAgIGdldCBwb3NpdGlvbigpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykudG9CYXJzQmVhdHNTaXh0ZWVudGhzKCk7XG4gICAgfVxuICAgIHNldCBwb3NpdGlvbihwcm9ncmVzcykge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyhwcm9ncmVzcyk7XG4gICAgICAgIHRoaXMudGlja3MgPSB0aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIFRyYW5zcG9ydCdzIHBvc2l0aW9uIGluIHNlY29uZHNcbiAgICAgKiBTZXR0aW5nIHRoZSB2YWx1ZSB3aWxsIGp1bXAgdG8gdGhhdCBwb3NpdGlvbiByaWdodCBhd2F5LlxuICAgICAqL1xuICAgIGdldCBzZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suc2Vjb25kcztcbiAgICB9XG4gICAgc2V0IHNlY29uZHMocykge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS50aW1lVG9UaWNrcyhzLCBub3cpO1xuICAgICAgICB0aGlzLnRpY2tzID0gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBsb29wIHBvc2l0aW9uIGFzIGEgbm9ybWFsaXplZCB2YWx1ZS4gQWx3YXlzXG4gICAgICogcmV0dXJucyAwIGlmIHRoZSB0cmFuc3BvcnQgaWYgbG9vcCBpcyBub3QgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKG5vdyk7XG4gICAgICAgICAgICByZXR1cm4gKHRpY2tzIC0gdGhpcy5fbG9vcFN0YXJ0KSAvICh0aGlzLl9sb29wRW5kIC0gdGhpcy5fbG9vcFN0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0cmFuc3BvcnRzIGN1cnJlbnQgdGljayBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay50aWNrcztcbiAgICB9XG4gICAgc2V0IHRpY2tzKHQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Nsb2NrLnRpY2tzICE9PSB0KSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgLy8gc3RvcCBldmVyeXRoaW5nIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKG5vdyk7XG4gICAgICAgICAgICAgICAgLy8gc2NoZWR1bGUgdG8gc3RhcnQgb24gdGhlIG5leHQgdGljaywgIzU3M1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbWFpbmluZ1RpY2sgPSB0aGlzLl9jbG9jay5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKE1hdGguY2VpbCh0aWNrcykgLSB0aWNrcywgbm93KTtcbiAgICAgICAgICAgICAgICBjb25zdCB0aW1lID0gbm93ICsgcmVtYWluaW5nVGljaztcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIHRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2Nsb2NrLnNldFRpY2tzQXRUaW1lKHQsIHRpbWUpO1xuICAgICAgICAgICAgICAgIC8vIHJlc3RhcnQgaXQgd2l0aCB0aGUgbmV3IHRpbWVcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCB0aW1lLCB0aGlzLl9jbG9jay5nZXRTZWNvbmRzQXRUaW1lKHRpbWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2Nsb2NrLnNldFRpY2tzQXRUaW1lKHQsIG5vdyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjbG9jaydzIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBnZXQgdGhlIHRpY2sgdmFsdWVcbiAgICAgKiBAcmV0dXJuIFRoZSB0aWNrIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQodGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUodGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suZ2V0U2Vjb25kc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHVsc2VzIFBlciBRdWFydGVyIG5vdGUuIFRoaXMgaXMgdGhlIHNtYWxsZXN0IHJlc29sdXRpb25cbiAgICAgKiB0aGUgVHJhbnNwb3J0IHRpbWluZyBzdXBwb3J0cy4gVGhpcyBzaG91bGQgYmUgc2V0IG9uY2VcbiAgICAgKiBvbiBpbml0aWFsaXphdGlvbiBhbmQgbm90IHNldCBhZ2Fpbi4gQ2hhbmdpbmcgdGhpcyB2YWx1ZVxuICAgICAqIGFmdGVyIG90aGVyIG9iamVjdHMgaGF2ZSBiZWVuIGNyZWF0ZWQgY2FuIGNhdXNlIHByb2JsZW1zLlxuICAgICAqL1xuICAgIGdldCBQUFEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5mcmVxdWVuY3kubXVsdGlwbGllcjtcbiAgICB9XG4gICAgc2V0IFBQUShwcHEpIHtcbiAgICAgICAgdGhpcy5fY2xvY2suZnJlcXVlbmN5Lm11bHRpcGxpZXIgPSBwcHE7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U1lOQ0lOR1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHRpbWUgYWxpZ25lZCB0byB0aGUgbmV4dCBzdWJkaXZpc2lvblxuICAgICAqIG9mIHRoZSBUcmFuc3BvcnQuIElmIHRoZSBUcmFuc3BvcnQgaXMgbm90IHN0YXJ0ZWQsXG4gICAgICogaXQgd2lsbCByZXR1cm4gMC5cbiAgICAgKiBOb3RlOiB0aGlzIHdpbGwgbm90IHdvcmsgcHJlY2lzZWx5IGR1cmluZyB0ZW1wbyByYW1wcy5cbiAgICAgKiBAcGFyYW0gIHN1YmRpdmlzaW9uICBUaGUgc3ViZGl2aXNpb24gdG8gcXVhbnRpemUgdG9cbiAgICAgKiBAcmV0dXJuICBUaGUgY29udGV4dCB0aW1lIG9mIHRoZSBuZXh0IHN1YmRpdmlzaW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gdGhlIHRyYW5zcG9ydCBtdXN0IGJlIHN0YXJ0ZWQsIG90aGVyd2lzZSByZXR1cm5zIDBcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0Lm5leHRTdWJkaXZpc2lvbihcIjRuXCIpO1xuICAgICAqL1xuICAgIG5leHRTdWJkaXZpc2lvbihzdWJkaXZpc2lvbikge1xuICAgICAgICBzdWJkaXZpc2lvbiA9IHRoaXMudG9UaWNrcyhzdWJkaXZpc2lvbik7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gaWYgdGhlIHRyYW5zcG9ydCdzIG5vdCBzdGFydGVkLCByZXR1cm4gMFxuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgLy8gdGhlIHJlbWFpbmRlciBvZiB0aGUgY3VycmVudCB0aWNrcyBhbmQgdGhlIHN1YmRpdmlzaW9uXG4gICAgICAgICAgICBjb25zdCB0cmFuc3BvcnRQb3MgPSB0aGlzLmdldFRpY2tzQXRUaW1lKG5vdyk7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdUaWNrcyA9IHN1YmRpdmlzaW9uIC0gdHJhbnNwb3J0UG9zICUgc3ViZGl2aXNpb247XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2submV4dFRpY2tUaW1lKHJlbWFpbmluZ1RpY2tzLCBub3cpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEF0dGFjaGVzIHRoZSBzaWduYWwgdG8gdGhlIHRlbXBvIGNvbnRyb2wgc2lnbmFsIHNvIHRoYXRcbiAgICAgKiBhbnkgY2hhbmdlcyBpbiB0aGUgdGVtcG8gd2lsbCBjaGFuZ2UgdGhlIHNpZ25hbCBpbiB0aGUgc2FtZVxuICAgICAqIHJhdGlvLlxuICAgICAqXG4gICAgICogQHBhcmFtIHNpZ25hbFxuICAgICAqIEBwYXJhbSByYXRpbyBPcHRpb25hbGx5IHBhc3MgaW4gdGhlIHJhdGlvIGJldHdlZW4gdGhlIHR3byBzaWduYWxzLlxuICAgICAqIFx0XHRcdE90aGVyd2lzZSBpdCB3aWxsIGJlIGNvbXB1dGVkIGJhc2VkIG9uIHRoZWlyIGN1cnJlbnQgdmFsdWVzLlxuICAgICAqL1xuICAgIHN5bmNTaWduYWwoc2lnbmFsLCByYXRpbykge1xuICAgICAgICBpZiAoIXJhdGlvKSB7XG4gICAgICAgICAgICAvLyBnZXQgdGhlIHN5bmMgcmF0aW9cbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICBpZiAoc2lnbmFsLmdldFZhbHVlQXRUaW1lKG5vdykgIT09IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBicG0gPSB0aGlzLmJwbS5nZXRWYWx1ZUF0VGltZShub3cpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkRnJlcSA9IDEgLyAoNjAgLyBicG0gLyB0aGlzLlBQUSk7XG4gICAgICAgICAgICAgICAgcmF0aW8gPSBzaWduYWwuZ2V0VmFsdWVBdFRpbWUobm93KSAvIGNvbXB1dGVkRnJlcTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJhdGlvID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCByYXRpb1NpZ25hbCA9IG5ldyBHYWluKHJhdGlvKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLmJwbS5jb25uZWN0KHJhdGlvU2lnbmFsKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICByYXRpb1NpZ25hbC5jb25uZWN0KHNpZ25hbC5fcGFyYW0pO1xuICAgICAgICB0aGlzLl9zeW5jZWRTaWduYWxzLnB1c2goe1xuICAgICAgICAgICAgaW5pdGlhbDogc2lnbmFsLnZhbHVlLFxuICAgICAgICAgICAgcmF0aW86IHJhdGlvU2lnbmFsLFxuICAgICAgICAgICAgc2lnbmFsLFxuICAgICAgICB9KTtcbiAgICAgICAgc2lnbmFsLnZhbHVlID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luY3MgYSBwcmV2aW91c2x5IHN5bmNlZCBzaWduYWwgZnJvbSB0aGUgdHJhbnNwb3J0J3MgY29udHJvbC5cbiAgICAgKiBTZWUgVHJhbnNwb3J0LnN5bmNTaWduYWwuXG4gICAgICovXG4gICAgdW5zeW5jU2lnbmFsKHNpZ25hbCkge1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5fc3luY2VkU2lnbmFscy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgY29uc3Qgc3luY2VkU2lnbmFsID0gdGhpcy5fc3luY2VkU2lnbmFsc1tpXTtcbiAgICAgICAgICAgIGlmIChzeW5jZWRTaWduYWwuc2lnbmFsID09PSBzaWduYWwpIHtcbiAgICAgICAgICAgICAgICBzeW5jZWRTaWduYWwucmF0aW8uZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIHN5bmNlZFNpZ25hbC5zaWduYWwudmFsdWUgPSBzeW5jZWRTaWduYWwuaW5pdGlhbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9zeW5jZWRTaWduYWxzLnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jbG9jay5kaXNwb3NlKCk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFwiYnBtXCIpO1xuICAgICAgICB0aGlzLl90aW1lbGluZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuRW1pdHRlci5taXhpbihUcmFuc3BvcnQpO1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC50cmFuc3BvcnQgPSBuZXcgVHJhbnNwb3J0KHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC50cmFuc3BvcnQuZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmFuc3BvcnQuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IFwiLi4vY29yZS9jb250ZXh0L0Rlc3RpbmF0aW9uXCI7XG5pbXBvcnQgXCIuLi9jb3JlL2Nsb2NrL1RyYW5zcG9ydFwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AsIHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vY29yZS91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNVbmRlZiB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQsIGFzc2VydENvbnRleHRSdW5uaW5nIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgR1QgfSBmcm9tIFwiLi4vY29yZS91dGlsL01hdGhcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3Igc291cmNlcy5cbiAqIHN0YXJ0L3N0b3Agb2YgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5cbiAqXG4gKiBgYGBcbiAqIC8vIE11bHRpcGxlIHN0YXRlIGNoYW5nZSBldmVudHMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIsXG4gKiAvLyBidXQgbXVzdCBiZSBzZXQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIgYW5kIHdpdGggYXNjZW5kaW5nIHRpbWVzXG4gKiAvLyBPS1xuICogc3RhdGUuc3RhcnQoKS5zdG9wKFwiKzAuMlwiKTtcbiAqIC8vIE9LXG4gKiBzdGF0ZS5zdGFydCgpLnN0b3AoXCIrMC4yXCIpLnN0YXJ0KFwiKzAuNFwiKS5zdG9wKFwiKzAuN1wiKVxuICogLy8gQkFEXG4gKiBzdGF0ZS5zdG9wKFwiKzAuMlwiKS5zdGFydCgpO1xuICogLy8gQkFEXG4gKiBzdGF0ZS5zdGFydChcIiswLjNcIikuc3RvcChcIiswLjJcIik7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFNvdXJjZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTb3VyY2VzIGhhdmUgbm8gaW5wdXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgc2NoZWR1bGVkIHN0YXRlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3luY2VkIGBzdGFydGAgY2FsbGJhY2sgZnVuY3Rpb24gZnJvbSB0aGUgdHJhbnNwb3J0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgYWxsIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQgaWRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWQgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBsYWNlaG9sZGVyIGZ1bmN0aW9ucyBmb3Igc3luY2luZy91bnN5bmNpbmcgdG8gdHJhbnNwb3J0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zeW5jZWRTdGFydCA9IG5vT3A7XG4gICAgICAgIHRoaXMuX3N5bmNlZFN0b3AgPSBub09wO1xuICAgICAgICB0aGlzLl9zdGF0ZS5tZW1vcnkgPSAxMDA7XG4gICAgICAgIHRoaXMuX3N0YXRlLmluY3JlYXNpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbXV0ZTogb3B0aW9ucy5tdXRlLFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ2b2x1bWVcIik7XG4gICAgICAgIHRoaXMub25zdG9wID0gb3B0aW9ucy5vbnN0b3A7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIG9uc3RvcDogbm9PcCxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2FobnRvbmVfYzMubXAzXCIsICgpID0+IHtcbiAgICAgKiBcdHBsYXllci5zdGFydCgpO1xuICAgICAqIFx0Y29uc29sZS5sb2cocGxheWVyLnN0YXRlKTtcbiAgICAgKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBcInN0b3BwZWRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gbXV0ZSB0aGUgb3V0cHV0XG4gICAgICogb3NjLm11dGUgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBFbnN1cmUgdGhhdCB0aGUgc2NoZWR1bGVkIHRpbWUgaXMgbm90IGJlZm9yZSB0aGUgY3VycmVudCB0aW1lLlxuICAgICAqIFNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiBzY2hlZHVsZWQgdW5zeW5jZWQuXG4gICAgICovXG4gICAgX2NsYW1wVG9DdXJyZW50VGltZSh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aW1lO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIE1hdGgubWF4KHRpbWUsIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sXG4gICAgICogc3RhcnQgdGhlIHNvdXJjZSBub3cuXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHNvdXJjZSBzaG91bGQgYmUgc3RhcnRlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc291cmNlLnN0YXJ0KFwiKzAuNVwiKTsgLy8gc3RhcnRzIHRoZSBzb3VyY2UgMC41IHNlY29uZHMgZnJvbSBub3dcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIGxldCBjb21wdXRlZFRpbWUgPSBpc1VuZGVmKHRpbWUpICYmIHRoaXMuX3N5bmNlZCA/IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyA6IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb21wdXRlZFRpbWUgPSB0aGlzLl9jbGFtcFRvQ3VycmVudFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgLy8gaWYgaXQncyBzdGFydGVkLCBzdG9wIGl0IGFuZCByZXN0YXJ0IGl0XG4gICAgICAgIGlmICghdGhpcy5fc3luY2VkICYmIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAvLyB0aW1lIHNob3VsZCBiZSBzdHJpY3RseSBncmVhdGVyIHRoYW4gdGhlIHByZXZpb3VzIHN0YXJ0IHRpbWVcbiAgICAgICAgICAgIGFzc2VydChHVChjb21wdXRlZFRpbWUsIHRoaXMuX3N0YXRlLmdldChjb21wdXRlZFRpbWUpLnRpbWUpLCBcIlN0YXJ0IHRpbWUgbXVzdCBiZSBzdHJpY3RseSBncmVhdGVyIHRoYW4gcHJldmlvdXMgc3RhcnQgdGltZVwiKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLmxvZyhcInJlc3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMucmVzdGFydChjb21wdXRlZFRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICAgICAgLy8gYWRkIHRoZSBvZmZzZXQgdGltZSB0byB0aGUgZXZlbnRcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXRlLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5vZmZzZXQgPSB0aGlzLnRvU2Vjb25kcyhkZWZhdWx0QXJnKG9mZnNldCwgMCkpO1xuICAgICAgICAgICAgICAgICAgICBldmVudC5kdXJhdGlvbiA9IGR1cmF0aW9uID8gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUodCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHQsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgIH0sIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkLnB1c2goc2NoZWQpO1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB0cmFuc3BvcnQgaXMgYWxyZWFkeSBzdGFydGVkXG4gICAgICAgICAgICAgICAgLy8gYW5kIHRoZSB0aW1lIGlzIGdyZWF0ZXIgdGhhbiB3aGVyZSB0aGUgdHJhbnNwb3J0IGlzXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuZ2V0U2Vjb25kc0F0VGltZSh0aGlzLmltbWVkaWF0ZSgpKSA+IGNvbXB1dGVkVGltZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zeW5jZWRTdGFydCh0aGlzLm5vdygpLCB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzc2VydENvbnRleHRSdW5uaW5nKHRoaXMuY29udGV4dCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnQoY29tcHV0ZWRUaW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgc291cmNlIGF0IHRoZSBzcGVjaWZpZWQgdGltZS4gSWYgbm8gdGltZSBpcyBnaXZlbixcbiAgICAgKiBzdG9wIHRoZSBzb3VyY2Ugbm93LlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBzb3VyY2Ugc2hvdWxkIGJlIHN0b3BwZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHNvdXJjZS5zdGFydCgpO1xuICAgICAqIHNvdXJjZS5zdG9wKFwiKzAuNVwiKTsgLy8gc3RvcHMgdGhlIHNvdXJjZSAwLjUgc2Vjb25kcyBmcm9tIG5vd1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICBsZXQgY29tcHV0ZWRUaW1lID0gaXNVbmRlZih0aW1lKSAmJiB0aGlzLl9zeW5jZWQgPyB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMgOiB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29tcHV0ZWRUaW1lID0gdGhpcy5fY2xhbXBUb0N1cnJlbnRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIiB8fCBpc0RlZmluZWQodGhpcy5fc3RhdGUuZ2V0TmV4dFN0YXRlKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpKSkge1xuICAgICAgICAgICAgdGhpcy5sb2coXCJzdG9wXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSh0aGlzLl9zdG9wLmJpbmQodGhpcyksIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkLnB1c2goc2NoZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzdGFydCB0aGUgc291cmNlLlxuICAgICAqL1xuICAgIHJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3Jlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHNvdXJjZSB0byB0aGUgVHJhbnNwb3J0IHNvIHRoYXQgYWxsIHN1YnNlcXVlbnRcbiAgICAgKiBjYWxscyB0byBgc3RhcnRgIGFuZCBgc3RvcGAgYXJlIHN5bmNlZCB0byB0aGUgVHJhbnNwb3J0VGltZVxuICAgICAqIGluc3RlYWQgb2YgdGhlIEF1ZGlvQ29udGV4dCB0aW1lLlxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHN5bmMgdGhlIHNvdXJjZSBzbyB0aGF0IGl0IHBsYXlzIGJldHdlZW4gMCBhbmQgMC4zIG9uIHRoZSBUcmFuc3BvcnQncyB0aW1lbGluZVxuICAgICAqIG9zYy5zeW5jKCkuc3RhcnQoMCkuc3RvcCgwLjMpO1xuICAgICAqIC8vIHN0YXJ0IHRoZSB0cmFuc3BvcnQuXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKiAvLyBzZXQgaXQgdG8gbG9vcCBvbmNlIGEgc2Vjb25kXG4gICAgICogVG9uZS5UcmFuc3BvcnQubG9vcCA9IHRydWU7XG4gICAgICogVG9uZS5UcmFuc3BvcnQubG9vcEVuZCA9IDE7XG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWRTdGFydCA9ICh0aW1lLCBvZmZzZXQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIHBsYXliYWNrIHN0YXRlIGF0IHRoYXQgdGltZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGF0ZUV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KG9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxpc3RlbiBmb3Igc3RhcnQgZXZlbnRzIHdoaWNoIG1heSBvY2N1ciBpbiB0aGUgbWlkZGxlIG9mIHRoZSBzeW5jJ2VkIHRpbWVcbiAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlRXZlbnQgJiYgc3RhdGVFdmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIgJiYgc3RhdGVFdmVudC50aW1lICE9PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGdldCB0aGUgb2Zmc2V0XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGFydE9mZnNldCA9IG9mZnNldCAtIHRoaXMudG9TZWNvbmRzKHN0YXRlRXZlbnQudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZHVyYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGVFdmVudC5kdXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoc3RhdGVFdmVudC5kdXJhdGlvbikgLSBzdGFydE9mZnNldDtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIHRoaXMudG9TZWNvbmRzKHN0YXRlRXZlbnQub2Zmc2V0KSArIHN0YXJ0T2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RvcCA9IHRpbWUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFNlY29uZHNBdFRpbWUoTWF0aC5tYXgodGltZSAtIHRoaXMuc2FtcGxlVGltZSwgMCkpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShzZWNvbmRzKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJsb29wU3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0b3BcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwibG9vcEVuZFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBzb3VyY2UgdG8gdGhlIFRyYW5zcG9ydC4gU2VlIFNvdXJjZS5zeW5jXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0b3BcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJsb29wRW5kXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcImxvb3BTdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgIC8vIGNsZWFyIGFsbCBvZiB0aGUgc2NoZWR1bGVkIGlkc1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWQuZm9yRWFjaChpZCA9PiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGlkKSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZCA9IFtdO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoMCk7XG4gICAgICAgIC8vIHN0b3AgaXQgYWxzb1xuICAgICAgICB0aGlzLl9zdG9wKDApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9uc3RvcCA9IG5vT3A7XG4gICAgICAgIHRoaXMudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U291cmNlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgT25lU2hvdFNvdXJjZSB9IGZyb20gXCIuLi9PbmVTaG90U291cmNlXCI7XG5pbXBvcnQgeyBFUSwgR1RFLCBMVCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvTWF0aFwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIEJ1ZmZlclNvdXJjZU5vZGUuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQnVmZmVyU291cmNlIGV4dGVuZHMgT25lU2hvdFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVCdWZmZXJTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQnVmZmVyU291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3NjaWxsYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuX3NvdXJjZV07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBpbmRpY2F0b3JzIGlmIHRoZSBzb3VyY2UgaGFzIHN0YXJ0ZWQvc3RvcHBlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9zb3VyY2VTdG9wcGVkID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQnVmZmVyU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9zb3VyY2UsIHRoaXMuX2dhaW5Ob2RlKTtcbiAgICAgICAgdGhpcy5fc291cmNlLm9uZW5kZWQgPSAoKSA9PiB0aGlzLl9zdG9wU291cmNlKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcGxheWJhY2tSYXRlIG9mIHRoZSBidWZmZXJcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9zb3VyY2UucGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNldCBzb21lIHZhbHVlcyBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIob3B0aW9ucy51cmwsIG9wdGlvbnMub25sb2FkLCBvcHRpb25zLm9uZXJyb3IpO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzLnB1c2godGhpcy5fc291cmNlKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPbmVTaG90U291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHVybDogbmV3IFRvbmVBdWRpb0J1ZmZlcigpLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlSW4gdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlSW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlSW47XG4gICAgfVxuICAgIHNldCBmYWRlSW4odCkge1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVPdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlT3V0O1xuICAgIH1cbiAgICBzZXQgZmFkZU91dCh0KSB7XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VydmUgYXBwbGllZCB0byB0aGUgZmFkZXMsIGVpdGhlciBcImxpbmVhclwiIG9yIFwiZXhwb25lbnRpYWxcIlxuICAgICAqL1xuICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnZlO1xuICAgIH1cbiAgICBzZXQgY3VydmUodCkge1xuICAgICAgICB0aGlzLl9jdXJ2ZSA9IHQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBidWZmZXJcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcGxheWVyIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc2FtcGxlIHRvIHN0YXJ0IGF0LlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb24gaXMgZ2l2ZW4sIGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcbiAgICAgKiBAcGFyYW0gIGdhaW4gIFRoZSBnYWluIHRvIHBsYXkgdGhlIGJ1ZmZlciBiYWNrIGF0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24sIGdhaW4gPSAxKSB7XG4gICAgICAgIGFzc2VydCh0aGlzLmJ1ZmZlci5sb2FkZWQsIFwiYnVmZmVyIGlzIGVpdGhlciBub3Qgc2V0IG9yIG5vdCBsb2FkZWRcIik7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyBhcHBseSB0aGUgZ2FpbiBlbnZlbG9wZVxuICAgICAgICB0aGlzLl9zdGFydEdhaW4oY29tcHV0ZWRUaW1lLCBnYWluKTtcbiAgICAgICAgLy8gaWYgaXQncyBhIGxvb3AgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIHRoZSBsb29wc3RhcnQgcG9pbnRcbiAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMubG9vcFN0YXJ0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB0aGUgZGVmYXVsdCBvZmZzZXQgaXMgMFxuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuICAgICAgICB9XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgb2Zmc2V0IGlzIG5vdCBsZXNzIHRoYW4gMFxuICAgICAgICBsZXQgY29tcHV0ZWRPZmZzZXQgPSBNYXRoLm1heCh0aGlzLnRvU2Vjb25kcyhvZmZzZXQpLCAwKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIGJ1ZmZlciBzb3VyY2VcbiAgICAgICAgaWYgKHRoaXMubG9vcCkge1xuICAgICAgICAgICAgLy8gbW9kaWZ5IHRoZSBvZmZzZXQgaWYgaXQncyBncmVhdGVyIHRoYW4gdGhlIGxvb3AgdGltZVxuICAgICAgICAgICAgY29uc3QgbG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKHRoaXMubG9vcEVuZCkgfHwgdGhpcy5idWZmZXIuZHVyYXRpb247XG4gICAgICAgICAgICBjb25zdCBsb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BTdGFydCk7XG4gICAgICAgICAgICBjb25zdCBsb29wRHVyYXRpb24gPSBsb29wRW5kIC0gbG9vcFN0YXJ0O1xuICAgICAgICAgICAgLy8gbW92ZSB0aGUgb2Zmc2V0IGJhY2tcbiAgICAgICAgICAgIGlmIChHVEUoY29tcHV0ZWRPZmZzZXQsIGxvb3BFbmQpKSB7XG4gICAgICAgICAgICAgICAgY29tcHV0ZWRPZmZzZXQgPSAoKGNvbXB1dGVkT2Zmc2V0IC0gbG9vcFN0YXJ0KSAlIGxvb3BEdXJhdGlvbikgKyBsb29wU3RhcnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB3aGVuIHRoZSBvZmZzZXQgaXMgdmVyeSBjbG9zZSB0byB0aGUgZHVyYXRpb24sIHNldCBpdCB0byAwXG4gICAgICAgICAgICBpZiAoRVEoY29tcHV0ZWRPZmZzZXQsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKSkge1xuICAgICAgICAgICAgICAgIGNvbXB1dGVkT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyB0aGlzLmJ1ZmZlci5sb2FkZWQgd291bGQgaGF2ZSByZXR1cm4gZmFsc2UgaWYgdGhlIEF1ZGlvQnVmZmVyIHdhcyB1bmRlZmluZWRcbiAgICAgICAgdGhpcy5fc291cmNlLmJ1ZmZlciA9IHRoaXMuYnVmZmVyLmdldCgpO1xuICAgICAgICB0aGlzLl9zb3VyY2UubG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKHRoaXMubG9vcEVuZCkgfHwgdGhpcy5idWZmZXIuZHVyYXRpb247XG4gICAgICAgIGlmIChMVChjb21wdXRlZE9mZnNldCwgdGhpcy5idWZmZXIuZHVyYXRpb24pKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdGFydChjb21wdXRlZFRpbWUsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiBhIGR1cmF0aW9uIGlzIGdpdmVuLCBzY2hlZHVsZSBhIHN0b3BcbiAgICAgICAgaWYgKGlzRGVmaW5lZChkdXJhdGlvbikpIHtcbiAgICAgICAgICAgIGxldCBjb21wdXRlZER1ciA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSBpdCdzIG5ldmVyIG5lZ2F0aXZlXG4gICAgICAgICAgICBjb21wdXRlZER1ciA9IE1hdGgubWF4KGNvbXB1dGVkRHVyLCAwKTtcbiAgICAgICAgICAgIHRoaXMuc3RvcChjb21wdXRlZFRpbWUgKyBjb21wdXRlZER1cik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9zdG9wU291cmNlKHRpbWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9zb3VyY2VTdG9wcGVkICYmIHRoaXMuX3NvdXJjZVN0YXJ0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZVN0b3BwZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnN0b3AodGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBzdGFydCBhdCB0aGlzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2UubG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9zb3VyY2UubG9vcFN0YXJ0ID0gdGhpcy50b1NlY29uZHMobG9vcFN0YXJ0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIGVuZCBhdCB0aGlzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyhsb29wRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGF1ZGlvIGJ1ZmZlciBiZWxvbmdpbmcgdG8gdGhlIHBsYXllci5cbiAgICAgKi9cbiAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyO1xuICAgIH1cbiAgICBzZXQgYnVmZmVyKGJ1ZmZlcikge1xuICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgc2hvdWxkIGxvb3Agb25jZSBpdCdzIG92ZXIuXG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zb3VyY2UubG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9zb3VyY2UubG9vcCA9IGxvb3A7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2VTdGFydGVkKSB7XG4gICAgICAgICAgICB0aGlzLmNhbmNlbFN0b3AoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5vbmVuZGVkID0gbnVsbDtcbiAgICAgICAgdGhpcy5fc291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQnVmZmVyU291cmNlLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbi8qKlxuICogTm9pc2UgaXMgYSBub2lzZSBnZW5lcmF0b3IuIEl0IHVzZXMgbG9vcGVkIG5vaXNlIGJ1ZmZlcnMgdG8gc2F2ZSBvbiBwZXJmb3JtYW5jZS5cbiAqIE5vaXNlIHN1cHBvcnRzIHRoZSBub2lzZSB0eXBlczogXCJwaW5rXCIsIFwid2hpdGVcIiwgYW5kIFwiYnJvd25cIi4gUmVhZCBtb3JlIGFib3V0XG4gKiBjb2xvcnMgb2Ygbm9pc2Ugb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29sb3JzX29mX25vaXNlKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6ZSB0aGUgbm9pc2UgYW5kIHN0YXJ0XG4gKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKFwicGlua1wiKS5zdGFydCgpO1xuICogLy8gbWFrZSBhbiBhdXRvZmlsdGVyIHRvIHNoYXBlIHRoZSBub2lzZVxuICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoe1xuICogXHRmcmVxdWVuY3k6IFwiOG5cIixcbiAqIFx0YmFzZUZyZXF1ZW5jeTogMjAwLFxuICogXHRvY3RhdmVzOiA4XG4gKiB9KS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIGNvbm5lY3QgdGhlIG5vaXNlXG4gKiBub2lzZS5jb25uZWN0KGF1dG9GaWx0ZXIpO1xuICogLy8gc3RhcnQgdGhlIGF1dG9maWx0ZXIgTEZPXG4gKiBhdXRvRmlsdGVyLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBOb2lzZSBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk5vaXNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIHJlZmVyZW5jZSB0byB0aGUgc291cmNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zb3VyY2UgPSBudWxsO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTm9pc2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgICAgICB0eXBlOiBcIndoaXRlXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbm9pc2UuIENhbiBiZSBcIndoaXRlXCIsIFwiYnJvd25cIiwgb3IgXCJwaW5rXCIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogbm9pc2UudHlwZSA9IFwiYnJvd25cIjtcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgYXNzZXJ0KHR5cGUgaW4gX25vaXNlQnVmZmVycywgXCJOb2lzZTogaW52YWxpZCB0eXBlOiBcIiArIHR5cGUpO1xuICAgICAgICBpZiAodGhpcy5fdHlwZSAhPT0gdHlwZSkge1xuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIHBsYXlpbmcsIHN0b3AgYW5kIHJlc3RhcnQgaXRcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RvcChub3cpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KG5vdyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIG5vaXNlLiBBZmZlY3RzXG4gICAgICogdGhlIFwiZnJlcXVlbmN5XCIgb2YgdGhlIG5vaXNlLlxuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UucGxheWJhY2tSYXRlLnZhbHVlID0gcmF0ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBpbnRlcm5hbCBzdGFydCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBidWZmZXIgPSBfbm9pc2VCdWZmZXJzW3RoaXMuX3R5cGVdO1xuICAgICAgICB0aGlzLl9zb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICB1cmw6IGJ1ZmZlcixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZhZGVJbjogdGhpcy5fZmFkZUluLFxuICAgICAgICAgICAgZmFkZU91dDogdGhpcy5fZmFkZU91dCxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBvbmVuZGVkOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5fcGxheWJhY2tSYXRlLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fc291cmNlLnN0YXJ0KHRoaXMudG9TZWNvbmRzKHRpbWUpLCBNYXRoLnJhbmRvbSgpICogKGJ1ZmZlci5kdXJhdGlvbiAtIDAuMDAxKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGludGVybmFsIHN0b3AgbWV0aG9kXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RvcCh0aGlzLnRvU2Vjb25kcyh0aW1lKSk7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlSW4gdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlSW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlSW47XG4gICAgfVxuICAgIHNldCBmYWRlSW4odGltZSkge1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSB0aW1lO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZmFkZUluID0gdGhpcy5fZmFkZUluO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlT3V0IHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZU91dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG4gICAgfVxuICAgIHNldCBmYWRlT3V0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IHRpbWU7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5mYWRlT3V0ID0gdGhpcy5fZmFkZU91dDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIC8vIFRPRE8gY291bGQgYmUgb3B0aW1pemVkIGJ5IGNhbmNlbGxpbmcgdGhlIGJ1ZmZlciBzb3VyY2UgJ3N0b3AnXG4gICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVEhFIE5PSVNFIEJVRkZFUlNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIE5vaXNlIGJ1ZmZlciBzdGF0c1xuY29uc3QgQlVGRkVSX0xFTkdUSCA9IDQ0MTAwICogNTtcbmNvbnN0IE5VTV9DSEFOTkVMUyA9IDI7XG4vKipcbiAqIENhY2hlIHRoZSBub2lzZSBidWZmZXJzXG4gKi9cbmNvbnN0IF9ub2lzZUNhY2hlID0ge1xuICAgIGJyb3duOiBudWxsLFxuICAgIHBpbms6IG51bGwsXG4gICAgd2hpdGU6IG51bGwsXG59O1xuLyoqXG4gKiBUaGUgbm9pc2UgYXJyYXlzLiBHZW5lcmF0ZWQgb24gaW5pdGlhbGl6YXRpb24uXG4gKiBib3Jyb3dlZCBoZWF2aWx5IGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3phY2hhcnlkZW50b24vbm9pc2UuanNcbiAqIChjKSAyMDEzIFphY2ggRGVudG9uIChNSVQpXG4gKi9cbmNvbnN0IF9ub2lzZUJ1ZmZlcnMgPSB7XG4gICAgZ2V0IGJyb3duKCkge1xuICAgICAgICBpZiAoIV9ub2lzZUNhY2hlLmJyb3duKSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGNoYW5uZWxOdW0gPSAwOyBjaGFubmVsTnVtIDwgTlVNX0NIQU5ORUxTOyBjaGFubmVsTnVtKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IEZsb2F0MzJBcnJheShCVUZGRVJfTEVOR1RIKTtcbiAgICAgICAgICAgICAgICBidWZmZXJbY2hhbm5lbE51bV0gPSBjaGFubmVsO1xuICAgICAgICAgICAgICAgIGxldCBsYXN0T3V0ID0gMC4wO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQlVGRkVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoaXRlID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gKGxhc3RPdXQgKyAoMC4wMiAqIHdoaXRlKSkgLyAxLjAyO1xuICAgICAgICAgICAgICAgICAgICBsYXN0T3V0ID0gY2hhbm5lbFtpXTtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSAqPSAzLjU7IC8vIChyb3VnaGx5KSBjb21wZW5zYXRlIGZvciBnYWluXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX25vaXNlQ2FjaGUuYnJvd24gPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKCkuZnJvbUFycmF5KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9ub2lzZUNhY2hlLmJyb3duO1xuICAgIH0sXG4gICAgZ2V0IHBpbmsoKSB7XG4gICAgICAgIGlmICghX25vaXNlQ2FjaGUucGluaykge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBsZXQgYjAsIGIxLCBiMiwgYjMsIGI0LCBiNSwgYjY7XG4gICAgICAgICAgICAgICAgYjAgPSBiMSA9IGIyID0gYjMgPSBiNCA9IGI1ID0gYjYgPSAwLjA7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBCVUZGRVJfTEVOR1RIOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgd2hpdGUgPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG4gICAgICAgICAgICAgICAgICAgIGIwID0gMC45OTg4NiAqIGIwICsgd2hpdGUgKiAwLjA1NTUxNzk7XG4gICAgICAgICAgICAgICAgICAgIGIxID0gMC45OTMzMiAqIGIxICsgd2hpdGUgKiAwLjA3NTA3NTk7XG4gICAgICAgICAgICAgICAgICAgIGIyID0gMC45NjkwMCAqIGIyICsgd2hpdGUgKiAwLjE1Mzg1MjA7XG4gICAgICAgICAgICAgICAgICAgIGIzID0gMC44NjY1MCAqIGIzICsgd2hpdGUgKiAwLjMxMDQ4NTY7XG4gICAgICAgICAgICAgICAgICAgIGI0ID0gMC41NTAwMCAqIGI0ICsgd2hpdGUgKiAwLjUzMjk1MjI7XG4gICAgICAgICAgICAgICAgICAgIGI1ID0gLTAuNzYxNiAqIGI1IC0gd2hpdGUgKiAwLjAxNjg5ODA7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gPSBiMCArIGIxICsgYjIgKyBiMyArIGI0ICsgYjUgKyBiNiArIHdoaXRlICogMC41MzYyO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldICo9IDAuMTE7IC8vIChyb3VnaGx5KSBjb21wZW5zYXRlIGZvciBnYWluXG4gICAgICAgICAgICAgICAgICAgIGI2ID0gd2hpdGUgKiAwLjExNTkyNjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfbm9pc2VDYWNoZS5waW5rID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS5waW5rO1xuICAgIH0sXG4gICAgZ2V0IHdoaXRlKCkge1xuICAgICAgICBpZiAoIV9ub2lzZUNhY2hlLndoaXRlKSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGNoYW5uZWxOdW0gPSAwOyBjaGFubmVsTnVtIDwgTlVNX0NIQU5ORUxTOyBjaGFubmVsTnVtKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gbmV3IEZsb2F0MzJBcnJheShCVUZGRVJfTEVOR1RIKTtcbiAgICAgICAgICAgICAgICBidWZmZXJbY2hhbm5lbE51bV0gPSBjaGFubmVsO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQlVGRkVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gPSBNYXRoLnJhbmRvbSgpICogMiAtIDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX25vaXNlQ2FjaGUud2hpdGUgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKCkuZnJvbUFycmF5KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIF9ub2lzZUNhY2hlLndoaXRlO1xuICAgIH0sXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Tm9pc2UuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNOdW1iZXIgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBVc2VyTWVkaWEgdXNlcyBNZWRpYURldmljZXMuZ2V0VXNlck1lZGlhIHRvIG9wZW4gdXAgYW5kIGV4dGVybmFsIG1pY3JvcGhvbmUgb3IgYXVkaW8gaW5wdXQuXG4gKiBDaGVjayBbTWVkaWFEZXZpY2VzIEFQSSBTdXBwb3J0XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTWVkaWFEZXZpY2VzL2dldFVzZXJNZWRpYSlcbiAqIHRvIHNlZSB3aGljaCBicm93c2VycyBhcmUgc3VwcG9ydGVkLiBBY2Nlc3MgdG8gYW4gZXh0ZXJuYWwgaW5wdXRcbiAqIGlzIGxpbWl0ZWQgdG8gc2VjdXJlIChIVFRQUykgY29ubmVjdGlvbnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWV0ZXIgPSBuZXcgVG9uZS5NZXRlcigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCkuY29ubmVjdChtZXRlcik7XG4gKiBtaWMub3BlbigpLnRoZW4oKCkgPT4ge1xuICogXHQvLyBwcm9taXNlIHJlc29sdmVzIHdoZW4gaW5wdXQgaXMgYXZhaWxhYmxlXG4gKiBcdGNvbnNvbGUubG9nKFwibWljIG9wZW5cIik7XG4gKiBcdC8vIHByaW50IHRoZSBpbmNvbWluZyBtaWMgbGV2ZWxzIGluIGRlY2liZWxzXG4gKiBcdHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKG1ldGVyLmdldFZhbHVlKCkpLCAxMDApO1xuICogfSkuY2F0Y2goZSA9PiB7XG4gKiBcdC8vIHByb21pc2UgaXMgcmVqZWN0ZWQgd2hlbiB0aGUgdXNlciBkb2Vzbid0IGhhdmUgb3IgYWxsb3cgbWljIGFjY2Vzc1xuICogXHRjb25zb2xlLmxvZyhcIm1pYyBub3Qgb3BlblwiKTtcbiAqIH0pO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVXNlck1lZGlhIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFVzZXJNZWRpYS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlVzZXJNZWRpYVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVXNlck1lZGlhLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHZvbHVtZTogMFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogT3BlbiB0aGUgbWVkaWEgc3RyZWFtLiBJZiBhIHN0cmluZyBpcyBwYXNzZWQgaW4sIGl0IGlzIGFzc3VtZWRcbiAgICAgKiB0byBiZSB0aGUgbGFiZWwgb3IgaWQgb2YgdGhlIHN0cmVhbSwgaWYgYSBudW1iZXIgaXMgcGFzc2VkIGluLFxuICAgICAqIGl0IGlzIHRoZSBpbnB1dCBudW1iZXIgb2YgdGhlIHN0cmVhbS5cbiAgICAgKiBAcGFyYW0gIGxhYmVsT3JJZCBUaGUgbGFiZWwgb3IgaWQgb2YgdGhlIGF1ZGlvIGlucHV0IG1lZGlhIGRldmljZS5cbiAgICAgKiAgICAgICAgICAgICAgICAgICBXaXRoIG5vIGFyZ3VtZW50LCB0aGUgZGVmYXVsdCBzdHJlYW0gaXMgb3BlbmVkLlxuICAgICAqIEByZXR1cm4gVGhlIHByb21pc2UgaXMgcmVzb2x2ZWQgd2hlbiB0aGUgc3RyZWFtIGlzIG9wZW4uXG4gICAgICovXG4gICAgb3BlbihsYWJlbE9ySWQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydChVc2VyTWVkaWEuc3VwcG9ydGVkLCBcIlVzZXJNZWRpYSBpcyBub3Qgc3VwcG9ydGVkXCIpO1xuICAgICAgICAgICAgLy8gY2xvc2UgdGhlIHByZXZpb3VzIHN0cmVhbVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgZGV2aWNlcyA9IHlpZWxkIFVzZXJNZWRpYS5lbnVtZXJhdGVEZXZpY2VzKCk7XG4gICAgICAgICAgICBpZiAoaXNOdW1iZXIobGFiZWxPcklkKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2RldmljZSA9IGRldmljZXNbbGFiZWxPcklkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2RldmljZSA9IGRldmljZXMuZmluZCgoZGV2aWNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXZpY2UubGFiZWwgPT09IGxhYmVsT3JJZCB8fCBkZXZpY2UuZGV2aWNlSWQgPT09IGxhYmVsT3JJZDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvLyBkaWRuJ3QgZmluZCBhIG1hdGNoaW5nIGRldmljZVxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5fZGV2aWNlICYmIGRldmljZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzWzBdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKHRoaXMuX2RldmljZSksIGBObyBtYXRjaGluZyBkZXZpY2UgJHtsYWJlbE9ySWR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBkbyBnZXRVc2VyTWVkaWFcbiAgICAgICAgICAgIGNvbnN0IGNvbnN0cmFpbnRzID0ge1xuICAgICAgICAgICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgICAgICAgICAgIGVjaG9DYW5jZWxsYXRpb246IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSxcbiAgICAgICAgICAgICAgICAgICAgbm9pc2VTdXBwcmVzc2lvbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1vek5vaXNlU3VwcHJlc3Npb246IGZhbHNlLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgICAgIGNvbnN0cmFpbnRzLmF1ZGlvLmRldmljZUlkID0gdGhpcy5fZGV2aWNlLmRldmljZUlkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3Qgc3RyZWFtID0geWllbGQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoY29uc3RyYWludHMpO1xuICAgICAgICAgICAgLy8gc3RhcnQgYSBuZXcgc291cmNlIG9ubHkgaWYgdGhlIHByZXZpb3VzIG9uZSBpcyBjbG9zZWRcbiAgICAgICAgICAgIGlmICghdGhpcy5fc3RyZWFtKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RyZWFtID0gc3RyZWFtO1xuICAgICAgICAgICAgICAgIC8vIFdyYXAgYSBNZWRpYVN0cmVhbVNvdXJjZU5vZGUgYXJvdW5kIHRoZSBsaXZlIGlucHV0IHN0cmVhbS5cbiAgICAgICAgICAgICAgICBjb25zdCBtZWRpYVN0cmVhbU5vZGUgPSB0aGlzLmNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICAgICAgICAgICAgICAvLyBDb25uZWN0IHRoZSBNZWRpYVN0cmVhbVNvdXJjZU5vZGUgdG8gYSBnYXRlIGdhaW4gbm9kZVxuICAgICAgICAgICAgICAgIGNvbm5lY3QobWVkaWFTdHJlYW1Ob2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbWVkaWFTdHJlYW0gPSBtZWRpYVN0cmVhbU5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBtZWRpYSBzdHJlYW1cbiAgICAgKi9cbiAgICBjbG9zZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N0cmVhbSAmJiB0aGlzLl9tZWRpYVN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy5fc3RyZWFtLmdldEF1ZGlvVHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHtcbiAgICAgICAgICAgICAgICB0cmFjay5zdG9wKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3N0cmVhbSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgb2xkIG1lZGlhIHN0cmVhbVxuICAgICAgICAgICAgdGhpcy5fbWVkaWFTdHJlYW0uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgdGhpcy5fbWVkaWFTdHJlYW0gPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZGV2aWNlID0gdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2l0aCB0aGUgbGlzdCBvZiBhdWRpbyBpbnB1dCBkZXZpY2VzIGF2YWlsYWJsZS5cbiAgICAgKiBAcmV0dXJuIFRoZSBwcm9taXNlIHRoYXQgaXMgcmVzb2x2ZWQgd2l0aCB0aGUgZGV2aWNlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5Vc2VyTWVkaWEuZW51bWVyYXRlRGV2aWNlcygpLnRoZW4oKGRldmljZXMpID0+IHtcbiAgICAgKiBcdC8vIHByaW50IHRoZSBkZXZpY2UgbGFiZWxzXG4gICAgICogXHRjb25zb2xlLmxvZyhkZXZpY2VzLm1hcChkZXZpY2UgPT4gZGV2aWNlLmxhYmVsKSk7XG4gICAgICogfSk7XG4gICAgICovXG4gICAgc3RhdGljIGVudW1lcmF0ZURldmljZXMoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBhbGxEZXZpY2VzID0geWllbGQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5lbnVtZXJhdGVEZXZpY2VzKCk7XG4gICAgICAgICAgICByZXR1cm4gYWxsRGV2aWNlcy5maWx0ZXIoZGV2aWNlID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlLmtpbmQgPT09IFwiYXVkaW9pbnB1dFwiO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBcInN0YXJ0ZWRcIiB3aGVuIHRoZSBtaWNyb3Bob25lIGlzIG9wZW5cbiAgICAgKiBhbmQgXCJzdG9wcGVkXCIgd2hlbiB0aGUgbWljIGlzIGNsb3NlZC5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdHJlYW0gJiYgdGhpcy5fc3RyZWFtLmFjdGl2ZSA/IFwic3RhcnRlZFwiIDogXCJzdG9wcGVkXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYW4gaWRlbnRpZmllciBmb3IgdGhlIHJlcHJlc2VudGVkIGRldmljZSB0aGF0IGlzXG4gICAgICogcGVyc2lzdGVkIGFjcm9zcyBzZXNzaW9ucy4gSXQgaXMgdW4tZ3Vlc3NhYmxlIGJ5IG90aGVyIGFwcGxpY2F0aW9ucyBhbmRcbiAgICAgKiB1bmlxdWUgdG8gdGhlIG9yaWdpbiBvZiB0aGUgY2FsbGluZyBhcHBsaWNhdGlvbi4gSXQgaXMgcmVzZXQgd2hlbiB0aGVcbiAgICAgKiB1c2VyIGNsZWFycyBjb29raWVzIChmb3IgUHJpdmF0ZSBCcm93c2luZywgYSBkaWZmZXJlbnQgaWRlbnRpZmllciBpc1xuICAgICAqIHVzZWQgdGhhdCBpcyBub3QgcGVyc2lzdGVkIGFjcm9zcyBzZXNzaW9ucykuIFJldHVybnMgdW5kZWZpbmVkIHdoZW4gdGhlXG4gICAgICogZGV2aWNlIGlzIG5vdCBvcGVuLlxuICAgICAqL1xuICAgIGdldCBkZXZpY2VJZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldmljZS5kZXZpY2VJZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGdyb3VwIGlkZW50aWZpZXIuIFR3byBkZXZpY2VzIGhhdmUgdGhlXG4gICAgICogc2FtZSBncm91cCBpZGVudGlmaWVyIGlmIHRoZXkgYmVsb25nIHRvIHRoZSBzYW1lIHBoeXNpY2FsIGRldmljZS5cbiAgICAgKiBSZXR1cm5zIG51bGwgIHdoZW4gdGhlIGRldmljZSBpcyBub3Qgb3Blbi5cbiAgICAgKi9cbiAgICBnZXQgZ3JvdXBJZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2RldmljZS5ncm91cElkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgbGFiZWwgZGVzY3JpYmluZyB0aGlzIGRldmljZSAoZm9yIGV4YW1wbGUgXCJCdWlsdC1pbiBNaWNyb3Bob25lXCIpLlxuICAgICAqIFJldHVybnMgdW5kZWZpbmVkIHdoZW4gdGhlIGRldmljZSBpcyBub3Qgb3BlbiBvciBsYWJlbCBpcyBub3QgYXZhaWxhYmxlXG4gICAgICogYmVjYXVzZSBvZiBwZXJtaXNzaW9ucy5cbiAgICAgKi9cbiAgICBnZXQgbGFiZWwoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UubGFiZWw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpO1xuICAgICAqIG1pYy5vcGVuKCkudGhlbigoKSA9PiB7XG4gICAgICogXHQvLyBwcm9taXNlIHJlc29sdmVzIHdoZW4gaW5wdXQgaXMgYXZhaWxhYmxlXG4gICAgICogfSk7XG4gICAgICogLy8gbXV0ZSB0aGUgb3V0cHV0XG4gICAgICogbWljLm11dGUgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgZ2V0VXNlck1lZGlhIGlzIHN1cHBvcnRlZCBieSB0aGUgYnJvd3Nlci5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHN1cHBvcnRlZCgpIHtcbiAgICAgICAgcmV0dXJuIGlzRGVmaW5lZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzKSAmJlxuICAgICAgICAgICAgaXNEZWZpbmVkKG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Vc2VyTWVkaWEuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbi8qKlxuICogUmVuZGVyIGEgc2VnbWVudCBvZiB0aGUgb3NjaWxsYXRvciB0byBhbiBvZmZsaW5lIGNvbnRleHQgYW5kIHJldHVybiB0aGUgcmVzdWx0cyBhcyBhbiBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVXYXZlZm9ybShpbnN0YW5jZSwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgY29uc3QgZHVyYXRpb24gPSBsZW5ndGggLyBpbnN0YW5jZS5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMSwgZHVyYXRpb24sIGluc3RhbmNlLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IGNsb25lID0gbmV3IGluc3RhbmNlLmNvbnN0cnVjdG9yKE9iamVjdC5hc3NpZ24oaW5zdGFuY2UuZ2V0KCksIHtcbiAgICAgICAgICAgIC8vIHNob3VsZCBkbyAyIGl0ZXJhdGlvbnNcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMiAvIGR1cmF0aW9uLFxuICAgICAgICAgICAgLy8gemVybyBvdXQgdGhlIGRldHVuZVxuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgY29udGV4dFxuICAgICAgICB9KSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAgICBjbG9uZS5zdGFydCgwKTtcbiAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgY29udGV4dC5yZW5kZXIoKTtcbiAgICAgICAgcmV0dXJuIGJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICB9KTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9zY2lsbGF0b3JJbnRlcmZhY2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE9uZVNob3RTb3VyY2UgfSBmcm9tIFwiLi4vT25lU2hvdFNvdXJjZVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIGZpcmUtYW5kLWZvcmdldCBPc2NpbGxhdG9yTm9kZS5cbiAqIEFkZHMgdGhlIGFiaWxpdHkgdG8gcmVzY2hlZHVsZSB0aGUgc3RvcCBtZXRob2QuXG4gKiAqKipbW09zY2lsbGF0b3JdXSBpcyBiZXR0ZXIgZm9yIG1vc3QgdXNlLWNhc2VzKioqXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lT3NjaWxsYXRvck5vZGUgZXh0ZW5kcyBPbmVTaG90U291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZU9zY2lsbGF0b3JOb2RlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVPc2NpbGxhdG9yTm9kZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLmNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuX29zY2lsbGF0b3JdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZU9zY2lsbGF0b3JOb2RlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fb3NjaWxsYXRvciwgdGhpcy5fZ2Fpbk5vZGUpO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX29zY2lsbGF0b3IuZGV0dW5lLFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIG9zY2lsbGF0b3Igbm9kZSBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRvIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydEdhaW4oY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3N0b3BTb3VyY2UodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgYW4gYXJiaXRyYXJ5IGN1c3RvbSBwZXJpb2RpYyB3YXZlZm9ybSBnaXZlbiBhIFBlcmlvZGljV2F2ZS5cbiAgICAgKiBAcGFyYW0gIHBlcmlvZGljV2F2ZSBQZXJpb2RpY1dhdmUgc2hvdWxkIGJlIGNyZWF0ZWQgd2l0aCBjb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZVxuICAgICAqL1xuICAgIHNldFBlcmlvZGljV2F2ZShwZXJpb2RpY1dhdmUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUocGVyaW9kaWNXYXZlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yIHR5cGUuIEVpdGhlciAnc2luZScsICdzYXd0b290aCcsICdzcXVhcmUnLCBvciAndHJpYW5nbGUnXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZU9zY2lsbGF0b3JOb2RlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgZGVlcEVxdWFscywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lT3NjaWxsYXRvck5vZGUgfSBmcm9tIFwiLi9Ub25lT3NjaWxsYXRvck5vZGVcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL01hdGhcIjtcbi8qKlxuICogT3NjaWxsYXRvciBzdXBwb3J0cyBhIG51bWJlciBvZiBmZWF0dXJlcyBpbmNsdWRpbmdcbiAqIHBoYXNlIHJvdGF0aW9uLCBtdWx0aXBsZSBvc2NpbGxhdG9yIHR5cGVzIChzZWUgT3NjaWxsYXRvci50eXBlKSxcbiAqIGFuZCBUcmFuc3BvcnQgc3luY2luZyAoc2VlIE9zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIG1ha2UgYW5kIHN0YXJ0IGEgNDQwaHogc2luZSB0b25lXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDQ0MCwgXCJzaW5lXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIG1haW4gb3NjaWxsYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG51bGw7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZnJlcXVlbmN5XCIpO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZGV0dW5lXCIpO1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IG9wdGlvbnMucGFydGlhbENvdW50O1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICBpZiAob3B0aW9ucy5wYXJ0aWFsQ291bnQgJiYgb3B0aW9ucy50eXBlICE9PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICB0aGlzLl90eXBlID0gdGhpcy5iYXNlVHlwZSArIG9wdGlvbnMucGFydGlhbENvdW50LnRvU3RyaW5nKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5waGFzZSA9IG9wdGlvbnMucGhhc2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgcGFydGlhbENvdW50OiAwLFxuICAgICAgICAgICAgcGFydGlhbHM6IFtdLFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIG5ldyBvc2NpbGxhdG9yIHdpdGggcHJldmlvdXMgdmFsdWVzXG4gICAgICAgIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZU9zY2lsbGF0b3JOb2RlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9uZW5kZWQ6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IG9zY2lsbGF0b3I7XG4gICAgICAgIGlmICh0aGlzLl93YXZlKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZSh0aGlzLl93YXZlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29ubmVjdCB0aGUgY29udHJvbCBzaWduYWwgdG8gdGhlIG9zY2lsbGF0b3IgZnJlcXVlbmN5ICYgZGV0dW5lXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZGV0dW5lKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydChjb21wdXRlZFRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc3RhcnQgdGhlIG9zY2lsbGF0b3IuIERvZXMgbm90IHN0b3AgdGhlIG9zY2lsbGF0b3IsIGJ1dCBpbnN0ZWFkXG4gICAgICoganVzdCBjYW5jZWxzIGFueSBzY2hlZHVsZWQgJ3N0b3AnIGZyb20gYmVpbmcgaW52b2tlZC5cbiAgICAgKi9cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInJlc3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY2FuY2VsU3RvcCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgc2lnbmFsIHRvIHRoZSBUcmFuc3BvcnQncyBicG0uIEFueSBjaGFuZ2VzIHRvIHRoZSB0cmFuc3BvcnRzIGJwbSxcbiAgICAgKiB3aWxsIGFsc28gYWZmZWN0IHRoZSBvc2NpbGxhdG9ycyBmcmVxdWVuY3kuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogb3NjLmZyZXF1ZW5jeS52YWx1ZSA9IDQ0MDtcbiAgICAgKiAvLyB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgYnBtIGFuZCB0aGUgZnJlcXVlbmN5IHdpbGwgYmUgbWFpbnRhaW5lZFxuICAgICAqIG9zYy5zeW5jRnJlcXVlbmN5KCk7XG4gICAgICogLy8gZG91YmxlIHRoZSB0ZW1wb1xuICAgICAqIFRvbmUuVHJhbnNwb3J0LmJwbS52YWx1ZSAqPSAyO1xuICAgICAqIC8vIHRoZSBmcmVxdWVuY3kgb2YgdGhlIG9zY2lsbGF0b3IgaXMgZG91YmxlZCB0byA4ODBcbiAgICAgKi9cbiAgICBzeW5jRnJlcXVlbmN5KCkge1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBvc2NpbGxhdG9yJ3MgZnJlcXVlbmN5IGZyb20gdGhlIFRyYW5zcG9ydC5cbiAgICAgKiBTZWUgT3NjaWxsYXRvci5zeW5jRnJlcXVlbmN5XG4gICAgICovXG4gICAgdW5zeW5jRnJlcXVlbmN5KCkge1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnVuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYSBjYWNoZWQgcGVyaW9kaWMgd2F2ZS4gQXZvaWRzIGhhdmluZyB0byByZWNvbXB1dGVcbiAgICAgKiB0aGUgb3NjaWxsYXRvciB2YWx1ZXMgd2hlbiB0aGV5IGhhdmUgYWxyZWFkeSBiZWVuIGNvbXB1dGVkXG4gICAgICogd2l0aCB0aGUgc2FtZSB2YWx1ZXMuXG4gICAgICovXG4gICAgX2dldENhY2hlZFBlcmlvZGljV2F2ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IG9zY1Byb3BzID0gT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUuZmluZChkZXNjcmlwdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uLnBoYXNlID09PSB0aGlzLl9waGFzZSAmJlxuICAgICAgICAgICAgICAgICAgICBkZWVwRXF1YWxzKGRlc2NyaXB0aW9uLnBhcnRpYWxzLCB0aGlzLl9wYXJ0aWFscyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBvc2NQcm9wcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG9zY1Byb3BzID0gT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUuZmluZChkZXNjcmlwdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0aW9uLnR5cGUgPT09IHRoaXMuX3R5cGUgJiZcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24ucGhhc2UgPT09IHRoaXMuX3BoYXNlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBvc2NQcm9wcyA/IG9zY1Byb3BzLnBhcnRpYWxDb3VudCA6IHRoaXMuX3BhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIHJldHVybiBvc2NQcm9wcztcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIGNvbnN0IGlzQmFzaWNUeXBlID0gW1wic2luZVwiLCBcInNxdWFyZVwiLCBcInNhd3Rvb3RoXCIsIFwidHJpYW5nbGVcIl0uaW5kZXhPZih0eXBlKSAhPT0gLTE7XG4gICAgICAgIGlmICh0aGlzLl9waGFzZSA9PT0gMCAmJiBpc0Jhc2ljVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5fd2F2ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IDA7XG4gICAgICAgICAgICAvLyBqdXN0IGdvIHdpdGggdGhlIGJhc2ljIGFwcHJvYWNoXG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgdGVzdGVkIHRoYXQgaXQncyBhIGJhc2ljIHR5cGVcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gZmlyc3QgY2hlY2sgaWYgdGhlIHZhbHVlIGlzIGNhY2hlZFxuICAgICAgICAgICAgY29uc3QgY2FjaGUgPSB0aGlzLl9nZXRDYWNoZWRQZXJpb2RpY1dhdmUoKTtcbiAgICAgICAgICAgIGlmIChpc0RlZmluZWQoY2FjaGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBwYXJ0aWFscywgd2F2ZSB9ID0gY2FjaGU7XG4gICAgICAgICAgICAgICAgdGhpcy5fd2F2ZSA9IHdhdmU7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNldFBlcmlvZGljV2F2ZSh0aGlzLl93YXZlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBbcmVhbCwgaW1hZ10gPSB0aGlzLl9nZXRSZWFsSW1hZ2luYXJ5KHR5cGUsIHRoaXMuX3BoYXNlKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwZXJpb2RpY1dhdmUgPSB0aGlzLmNvbnRleHQuY3JlYXRlUGVyaW9kaWNXYXZlKHJlYWwsIGltYWcpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dhdmUgPSBwZXJpb2RpY1dhdmU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIHNldCB0aGUgY2FjaGVcbiAgICAgICAgICAgICAgICBPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaW1hZyxcbiAgICAgICAgICAgICAgICAgICAgcGFydGlhbENvdW50OiB0aGlzLl9wYXJ0aWFsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxzOiB0aGlzLl9wYXJ0aWFscyxcbiAgICAgICAgICAgICAgICAgICAgcGhhc2U6IHRoaXMuX3BoYXNlLFxuICAgICAgICAgICAgICAgICAgICByZWFsLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLl90eXBlLFxuICAgICAgICAgICAgICAgICAgICB3YXZlOiB0aGlzLl93YXZlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChPc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZS5sZW5ndGggPiAxMDApIHtcbiAgICAgICAgICAgICAgICAgICAgT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IGJhc2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZS5yZXBsYWNlKHRoaXMucGFydGlhbENvdW50LnRvU3RyaW5nKCksIFwiXCIpO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgaWYgKHRoaXMucGFydGlhbENvdW50ICYmIHRoaXMuX3R5cGUgIT09IFwiY3VzdG9tXCIgJiYgYmFzZVR5cGUgIT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IGJhc2VUeXBlICsgdGhpcy5wYXJ0aWFsQ291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHApIHtcbiAgICAgICAgYXNzZXJ0UmFuZ2UocCwgMCk7XG4gICAgICAgIGxldCB0eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgY29uc3QgcGFydGlhbCA9IC9eKHNpbmV8dHJpYW5nbGV8c3F1YXJlfHNhd3Rvb3RoKShcXGQrKSQvLmV4ZWModGhpcy5fdHlwZSk7XG4gICAgICAgIGlmIChwYXJ0aWFsKSB7XG4gICAgICAgICAgICB0eXBlID0gcGFydGlhbFsxXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fdHlwZSAhPT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgaWYgKHAgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZSArIHAudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGV4dGVuZCBvciBzaG9ydGVuIHRoZSBwYXJ0aWFscyBhcnJheVxuICAgICAgICAgICAgY29uc3QgZnVsbFBhcnRpYWxzID0gbmV3IEZsb2F0MzJBcnJheShwKTtcbiAgICAgICAgICAgIC8vIGNvcHkgb3ZlciB0aGUgcGFydGlhbHMgYXJyYXlcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzLmZvckVhY2goKHYsIGkpID0+IGZ1bGxQYXJ0aWFsc1tpXSA9IHYpO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBBcnJheS5mcm9tKGZ1bGxQYXJ0aWFscyk7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHJlYWwgYW5kIGltYWdpbmFyeSBjb21wb25lbnRzIGJhc2VkXG4gICAgICogb24gdGhlIG9zY2lsbGF0b3IgdHlwZS5cbiAgICAgKiBAcmV0dXJucyBbcmVhbDogRmxvYXQzMkFycmF5LCBpbWFnaW5hcnk6IEZsb2F0MzJBcnJheV1cbiAgICAgKi9cbiAgICBfZ2V0UmVhbEltYWdpbmFyeSh0eXBlLCBwaGFzZSkge1xuICAgICAgICBjb25zdCBmZnRTaXplID0gNDA5NjtcbiAgICAgICAgbGV0IHBlcmlvZGljV2F2ZVNpemUgPSBmZnRTaXplIC8gMjtcbiAgICAgICAgY29uc3QgcmVhbCA9IG5ldyBGbG9hdDMyQXJyYXkocGVyaW9kaWNXYXZlU2l6ZSk7XG4gICAgICAgIGNvbnN0IGltYWcgPSBuZXcgRmxvYXQzMkFycmF5KHBlcmlvZGljV2F2ZVNpemUpO1xuICAgICAgICBsZXQgcGFydGlhbENvdW50ID0gMTtcbiAgICAgICAgaWYgKHR5cGUgPT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aCArIDE7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGg7XG4gICAgICAgICAgICBwZXJpb2RpY1dhdmVTaXplID0gcGFydGlhbENvdW50O1xuICAgICAgICAgICAgLy8gaWYgdGhlIHBhcnRpYWwgY291bnQgaXMgMCwgZG9uJ3QgYm90aGVyIGRvaW5nIGFueSBjb21wdXRhdGlvblxuICAgICAgICAgICAgaWYgKHRoaXMuX3BhcnRpYWxzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbcmVhbCwgaW1hZ107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsID0gL14oc2luZXx0cmlhbmdsZXxzcXVhcmV8c2F3dG9vdGgpKFxcZCspJC8uZXhlYyh0eXBlKTtcbiAgICAgICAgICAgIGlmIChwYXJ0aWFsKSB7XG4gICAgICAgICAgICAgICAgcGFydGlhbENvdW50ID0gcGFyc2VJbnQocGFydGlhbFsyXSwgMTApICsgMTtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBwYXJzZUludChwYXJ0aWFsWzJdLCAxMCk7XG4gICAgICAgICAgICAgICAgdHlwZSA9IHBhcnRpYWxbMV07XG4gICAgICAgICAgICAgICAgcGFydGlhbENvdW50ID0gTWF0aC5tYXgocGFydGlhbENvdW50LCAyKTtcbiAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmVTaXplID0gcGFydGlhbENvdW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gW107XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbiA9IDE7IG4gPCBwZXJpb2RpY1dhdmVTaXplOyArK24pIHtcbiAgICAgICAgICAgIGNvbnN0IHBpRmFjdG9yID0gMiAvIChuICogTWF0aC5QSSk7XG4gICAgICAgICAgICBsZXQgYjtcbiAgICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzaW5lXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSAobiA8PSBwYXJ0aWFsQ291bnQpID8gMSA6IDA7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzW24gLSAxXSA9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzcXVhcmVcIjpcbiAgICAgICAgICAgICAgICAgICAgYiA9IChuICYgMSkgPyAyICogcGlGYWN0b3IgOiAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsc1tuIC0gMV0gPSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwic2F3dG9vdGhcIjpcbiAgICAgICAgICAgICAgICAgICAgYiA9IHBpRmFjdG9yICogKChuICYgMSkgPyAxIDogLTEpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsc1tuIC0gMV0gPSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwidHJpYW5nbGVcIjpcbiAgICAgICAgICAgICAgICAgICAgaWYgKG4gJiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiID0gMiAqIChwaUZhY3RvciAqIHBpRmFjdG9yKSAqICgoKChuIC0gMSkgPj4gMSkgJiAxKSA/IC0xIDogMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiID0gMDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsc1tuIC0gMV0gPSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwiY3VzdG9tXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSB0aGlzLl9wYXJ0aWFsc1tuIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPc2NpbGxhdG9yOiBpbnZhbGlkIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYiAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJlYWxbbl0gPSAtYiAqIE1hdGguc2luKHBoYXNlICogbik7XG4gICAgICAgICAgICAgICAgaW1hZ1tuXSA9IGIgKiBNYXRoLmNvcyhwaGFzZSAqIG4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVhbFtuXSA9IDA7XG4gICAgICAgICAgICAgICAgaW1hZ1tuXSA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtyZWFsLCBpbWFnXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29tcHV0ZSB0aGUgaW52ZXJzZSBGRlQgZm9yIGEgZ2l2ZW4gcGhhc2UuXG4gICAgICovXG4gICAgX2ludmVyc2VGRlQocmVhbCwgaW1hZywgcGhhc2UpIHtcbiAgICAgICAgbGV0IHN1bSA9IDA7XG4gICAgICAgIGNvbnN0IGxlbiA9IHJlYWwubGVuZ3RoO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBzdW0gKz0gcmVhbFtpXSAqIE1hdGguY29zKGkgKiBwaGFzZSkgKyBpbWFnW2ldICogTWF0aC5zaW4oaSAqIHBoYXNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3VtO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBvc2NpbGxhdG9yIHdoZW4gc3RvcHBlZC5cbiAgICAgKiBFLmcuIGEgXCJzaW5lXCIgb3NjaWxsYXRvciB3aXRoIHBoYXNlID0gOTAgd291bGQgcmV0dXJuIGFuIGluaXRpYWwgdmFsdWUgb2YgLTEuXG4gICAgICovXG4gICAgZ2V0SW5pdGlhbFZhbHVlKCkge1xuICAgICAgICBjb25zdCBbcmVhbCwgaW1hZ10gPSB0aGlzLl9nZXRSZWFsSW1hZ2luYXJ5KHRoaXMuX3R5cGUsIDApO1xuICAgICAgICBsZXQgbWF4VmFsdWUgPSAwO1xuICAgICAgICBjb25zdCB0d29QaSA9IE1hdGguUEkgKiAyO1xuICAgICAgICBjb25zdCB0ZXN0UG9zaXRpb25zID0gMzI7XG4gICAgICAgIC8vIGNoZWNrIGZvciBwZWFrcyBpbiAxNiBwbGFjZXNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0ZXN0UG9zaXRpb25zOyBpKyspIHtcbiAgICAgICAgICAgIG1heFZhbHVlID0gTWF0aC5tYXgodGhpcy5faW52ZXJzZUZGVChyZWFsLCBpbWFnLCAoaSAvIHRlc3RQb3NpdGlvbnMpICogdHdvUGkpLCBtYXhWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNsYW1wKC10aGlzLl9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIHRoaXMuX3BoYXNlKSAvIG1heFZhbHVlLCAtMSwgMSk7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnRpYWxzLnNsaWNlKDAsIHRoaXMucGFydGlhbENvdW50KTtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHRoaXMuX3BhcnRpYWxzLmxlbmd0aDtcbiAgICAgICAgaWYgKHBhcnRpYWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJjdXN0b21cIjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9waGFzZSAqICgxODAgLyBNYXRoLlBJKTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX3BoYXNlID0gcGhhc2UgKiBNYXRoLlBJIC8gMTgwO1xuICAgICAgICAvLyByZXNldCB0aGUgdHlwZVxuICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl93YXZlID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBDYWNoZSB0aGUgcGVyaW9kaWMgd2F2ZXMgdG8gYXZvaWQgaGF2aW5nIHRvIHJlZG8gY29tcHV0YXRpb25zXG4gKi9cbk9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlID0gW107XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Pc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgY29ubmVjdFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuLyoqXG4gKiBBIHNpZ25hbCBvcGVyYXRvciBoYXMgYW4gaW5wdXQgYW5kIG91dHB1dCBhbmQgbW9kaWZpZXMgdGhlIHNpZ25hbC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25hbE9wZXJhdG9yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjb250ZXh0XCJdKSkpO1xuICAgIH1cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNpZ25hbE9wZXJhdG9yLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNGdW5jdGlvbiB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogV3JhcHMgdGhlIG5hdGl2ZSBXZWIgQXVkaW8gQVBJXG4gKiBbV2F2ZVNoYXBlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLXdhdmVzaGFwZXJub2RlLWludGVyZmFjZSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIG11bHRpcGx5IHRoZSBvdXRwdXQgb2YgdGhlIHNpZ25hbCBieSAyIHVzaW5nIHRoZSB3YXZlc2hhcGVyJ3MgZnVuY3Rpb25cbiAqIGNvbnN0IHRpbWVzVHdvID0gbmV3IFRvbmUuV2F2ZVNoYXBlcigodmFsKSA9PiB2YWwgKiAyLCAyMDQ4KS5jb25uZWN0KG9zYy5mcmVxdWVuY3kpO1xuICogY29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDQ0MCkuY29ubmVjdCh0aW1lc1R3byk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBXYXZlU2hhcGVyIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFdhdmVTaGFwZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtYXBwaW5nXCIsIFwibGVuZ3RoXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIldhdmVTaGFwZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSB3YXZlc2hhcGVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NoYXBlciA9IHRoaXMuY29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgdG8gdGhlIHdhdmVzaGFwZXIgbm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9zaGFwZXI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IGZyb20gdGhlIHdhdmVzaGFwZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9zaGFwZXI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlU2hhcGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWFwcGluZ1wiLCBcImxlbmd0aFwiXSk7XG4gICAgICAgIGlmIChpc0FycmF5KG9wdGlvbnMubWFwcGluZykgfHwgb3B0aW9ucy5tYXBwaW5nIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLmN1cnZlID0gRmxvYXQzMkFycmF5LmZyb20ob3B0aW9ucy5tYXBwaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0Z1bmN0aW9uKG9wdGlvbnMubWFwcGluZykpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0TWFwKG9wdGlvbnMubWFwcGluZywgb3B0aW9ucy5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGxlbmd0aDogMTAyNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVzZXMgYSBtYXBwaW5nIGZ1bmN0aW9uIHRvIHNldCB0aGUgdmFsdWUgb2YgdGhlIGN1cnZlLlxuICAgICAqIEBwYXJhbSBtYXBwaW5nIFRoZSBmdW5jdGlvbiB1c2VkIHRvIGRlZmluZSB0aGUgdmFsdWVzLlxuICAgICAqICAgICAgICAgICAgICAgIFRoZSBtYXBwaW5nIGZ1bmN0aW9uIHRha2UgdHdvIGFyZ3VtZW50czpcbiAgICAgKiAgICAgICAgICAgICAgICB0aGUgZmlyc3QgaXMgdGhlIHZhbHVlIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uXG4gICAgICogICAgICAgICAgICAgICAgd2hpY2ggZ29lcyBmcm9tIC0xIHRvIDEgb3ZlciB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzXG4gICAgICogICAgICAgICAgICAgICAgaW4gdGhlIGN1cnZlIGFycmF5LiBUaGUgc2Vjb25kIGFyZ3VtZW50IGlzIHRoZSBhcnJheSBwb3NpdGlvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHNoYXBlciA9IG5ldyBUb25lLldhdmVTaGFwZXIoKTtcbiAgICAgKiAvLyBtYXAgdGhlIGlucHV0IHNpZ25hbCBmcm9tIFstMSwgMV0gdG8gWzAsIDEwXVxuICAgICAqIHNoYXBlci5zZXRNYXAoKHZhbCwgaW5kZXgpID0+ICh2YWwgKyAxKSAqIDUpO1xuICAgICAqL1xuICAgIHNldE1hcChtYXBwaW5nLCBsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIGNvbnN0IGFycmF5ID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gbGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSAoaSAvIChsZW4gLSAxKSkgKiAyIC0gMTtcbiAgICAgICAgICAgIGFycmF5W2ldID0gbWFwcGluZyhub3JtYWxpemVkLCBpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmN1cnZlID0gYXJyYXk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXJyYXkgdG8gc2V0IGFzIHRoZSB3YXZlc2hhcGVyIGN1cnZlLiBGb3IgbGluZWFyIGN1cnZlc1xuICAgICAqIGFycmF5IGxlbmd0aCBkb2VzIG5vdCBtYWtlIG11Y2ggZGlmZmVyZW5jZSwgYnV0IGZvciBjb21wbGV4IGN1cnZlc1xuICAgICAqIGxvbmdlciBhcnJheXMgd2lsbCBwcm92aWRlIHNtb290aGVyIGludGVycG9sYXRpb24uXG4gICAgICovXG4gICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLmN1cnZlO1xuICAgIH1cbiAgICBzZXQgY3VydmUobWFwcGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIuY3VydmUgPSBtYXBwaW5nO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTcGVjaWZpZXMgd2hhdCB0eXBlIG9mIG92ZXJzYW1wbGluZyAoaWYgYW55KSBzaG91bGQgYmUgdXNlZCB3aGVuXG4gICAgICogYXBwbHlpbmcgdGhlIHNoYXBpbmcgY3VydmUuIENhbiBlaXRoZXIgYmUgXCJub25lXCIsIFwiMnhcIiBvciBcIjR4XCIuXG4gICAgICovXG4gICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZTtcbiAgICB9XG4gICAgc2V0IG92ZXJzYW1wbGUob3ZlcnNhbXBsaW5nKSB7XG4gICAgICAgIGNvbnN0IGlzT3ZlclNhbXBsZVR5cGUgPSBbXCJub25lXCIsIFwiMnhcIiwgXCI0eFwiXS5zb21lKHN0ciA9PiBzdHIuaW5jbHVkZXMob3ZlcnNhbXBsaW5nKSk7XG4gICAgICAgIGFzc2VydChpc092ZXJTYW1wbGVUeXBlLCBcIm92ZXJzYW1wbGluZyBtdXN0IGJlIGVpdGhlciAnbm9uZScsICcyeCcsIG9yICc0eCdcIik7XG4gICAgICAgIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlID0gb3ZlcnNhbXBsaW5nO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NoYXBlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVdhdmVTaGFwZXIuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbi8qKlxuICogQXVkaW9Ub0dhaW4gY29udmVydHMgYW4gaW5wdXQgaW4gQXVkaW9SYW5nZSBbLTEsMV0gdG8gTm9ybWFsUmFuZ2UgWzAsMV0uXG4gKiBTZWUgW1tHYWluVG9BdWRpb11dLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgQXVkaW9Ub0dhaW4gZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXVkaW9Ub0dhaW5cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBub2RlIHdoaWNoIGNvbnZlcnRzIHRoZSBhdWRpbyByYW5nZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX25vcm0gPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB4ID0+ICh4ICsgMSkgLyAyLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBBdWRpb1JhbmdlIGlucHV0IFstMSwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9ub3JtO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEdhaW5SYW5nZSBvdXRwdXQgWzAsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX25vcm07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ub3JtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXVkaW9Ub0dhaW4uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbi8qKlxuICogTXVsdGlwbHkgdHdvIGluY29taW5nIHNpZ25hbHMuIE9yLCBpZiBhIG51bWJlciBpcyBnaXZlbiBpbiB0aGUgY29uc3RydWN0b3IsXG4gKiBtdWx0aXBsaWVzIHRoZSBpbmNvbWluZyBzaWduYWwgYnkgdGhhdCB2YWx1ZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gbXVsdGlwbHkgdHdvIHNpZ25hbHNcbiAqIGNvbnN0IG11bHQgPSBuZXcgVG9uZS5NdWx0aXBseSgpO1xuICogY29uc3Qgc2lnQSA9IG5ldyBUb25lLlNpZ25hbCgzKTtcbiAqIGNvbnN0IHNpZ0IgPSBuZXcgVG9uZS5TaWduYWwoNCk7XG4gKiBzaWdBLmNvbm5lY3QobXVsdCk7XG4gKiBzaWdCLmNvbm5lY3QobXVsdC5mYWN0b3IpO1xuICogLy8gb3V0cHV0IG9mIG11bHQgaXMgMTIuXG4gKiBAZXhhbXBsZVxuICogLy8gbXVsdGlwbHkgYSBzaWduYWwgYW5kIGEgbnVtYmVyXG4gKiBjb25zdCBtdWx0ID0gbmV3IFRvbmUuTXVsdGlwbHkoMTApO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDIpLmNvbm5lY3QobXVsdCk7XG4gKiAvLyB0aGUgb3V0cHV0IG9mIG11bHQgaXMgMjAuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBNdWx0aXBseSBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGlwbHkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aXBseVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSB2YWx1ZSBzaG91bGQgYmUgb3ZlcnJpZGRlbiBvbiBjb25uZWN0aW9uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aXBseS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5fbXVsdCA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZhY3RvciA9IHRoaXMuX3BhcmFtID0gdGhpcy5fbXVsdC5nYWluO1xuICAgICAgICB0aGlzLmZhY3Rvci5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX211bHQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NdWx0aXBseS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgQXVkaW9Ub0dhaW4gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0F1ZGlvVG9HYWluXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuLyoqXG4gKiBBbiBhbXBsaXR1ZGUgbW9kdWxhdGVkIG9zY2lsbGF0b3Igbm9kZS4gSXQgaXMgaW1wbGVtZW50ZWQgd2l0aFxuICogdHdvIG9zY2lsbGF0b3JzLCBvbmUgd2hpY2ggbW9kdWxhdG9ycyB0aGUgb3RoZXIncyBhbXBsaXR1ZGVcbiAqIHRocm91Z2ggYSBnYWluIG5vZGUuXG4gKiBgYGBcbiAqICAgICstLS0tLS0tLS0tLS0tKyAgICAgICArLS0tLS0tLS0tLStcbiAqICAgIHwgQ2FycmllciBPc2MgKz4tLS0tLS0+IEdhaW5Ob2RlIHxcbiAqICAgICstLS0tLS0tLS0tLS0tKyAgICAgICB8ICAgICAgICAgICstLS0+T3V0cHV0XG4gKiAgICAgICAgICAgICAgICAgICAgICArLS0tPiBnYWluICAgICB8XG4gKiArLS0tLS0tLS0tLS0tLS0tKyAgICB8ICAgKy0tLS0tLS0tLS0rXG4gKiB8IE1vZHVsYXRvciBPc2MgKz4tLS0rXG4gKiArLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFtT3NjID0gbmV3IFRvbmUuQU1Pc2NpbGxhdG9yKDMwLCBcInNpbmVcIiwgXCJzcXVhcmVcIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjIsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgQU1Pc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQU1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQU1Pc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBjb252ZXJ0IHRoZSAtMSwxIG91dHB1dCB0byAwLDFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZSA9IG5ldyBBdWRpb1RvR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBub2RlIHdoZXJlIHRoZSBtb2R1bGF0aW9uIGhhcHBlbnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEFNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fY2Fycmllci5mcmVxdWVuY3ksXG4gICAgICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX2NhcnJpZXIuZGV0dW5lO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMubW9kdWxhdGlvblR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMuX21vZHVsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY2hhaW4odGhpcy5fbW9kdWxhdGlvblNjYWxlLCB0aGlzLl9tb2R1bGF0aW9uTm9kZS5nYWluKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uTm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJoYXJtb25pY2l0eVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBoYXJtb25pY2l0eTogMSxcbiAgICAgICAgICAgIG1vZHVsYXRpb25UeXBlOiBcInNxdWFyZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0b3AodGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucmVzdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIGNhcnJpZXIgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIuYmFzZVR5cGU7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlID0gYmFzZVR5cGU7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvclxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vZHVsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgbW9kdWxhdGlvblR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBoYXNlID0gcGhhc2U7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QU1Pc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi8uLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbi8qKlxuICogRk1Pc2NpbGxhdG9yIGltcGxlbWVudHMgYSBmcmVxdWVuY3kgbW9kdWxhdGlvbiBzeW50aGVzaXNcbiAqIGBgYFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0rXG4gKiArLS0tLS0tLS0tLS0tLS0tKyAgICAgICAgKy0tLS0tLS0tLS0tLS0rICAgICB8IENhcnJpZXIgT3NjIHxcbiAqIHwgTW9kdWxhdG9yIE9zYyArPi0tLS0tLS0+IEdhaW5Ob2RlICAgIHwgICAgIHwgICAgICAgICAgICAgKy0tLT5PdXRwdXRcbiAqICstLS0tLS0tLS0tLS0tLS0rICAgICAgICB8ICAgICAgICAgICAgICs+LS0tLT4gZnJlcXVlbmN5ICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICstLT4gZ2FpbiAgICAgICAgfCAgICAgKy0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgICAgICAgICAgfCAgKy0tLS0tLS0tLS0tLS0rXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0rICAgfFxuICogfCBtb2R1bGF0aW9uSW5kZXggKz4tLStcbiAqICstLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZm1Pc2MgPSBuZXcgVG9uZS5GTU9zY2lsbGF0b3Ioe1xuICogXHRcdGZyZXF1ZW5jeTogMjAwLFxuICogXHRcdHR5cGU6IFwic3F1YXJlXCIsXG4gKiBcdFx0bW9kdWxhdGlvblR5cGU6IFwidHJpYW5nbGVcIixcbiAqIFx0XHRoYXJtb25pY2l0eTogMC4yLFxuICogXHRcdG1vZHVsYXRpb25JbmRleDogM1xuICogXHR9KS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBGTU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGTU9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBub2RlIHdoZXJlIHRoZSBtb2R1bGF0aW9uIGhhcHBlbnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fY2Fycmllci5kZXR1bmU7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy5tb2R1bGF0aW9uVHlwZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXggPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5tb2R1bGF0aW9uSW5kZXgsIHRoaXMuX21vZHVsYXRpb25Ob2RlKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNvbm5lY3QodGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KHRoaXMuX21vZHVsYXRvci5kZXR1bmUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJtb2R1bGF0aW9uSW5kZXhcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJoYXJtb25pY2l0eVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBoYXJtb25pY2l0eTogMSxcbiAgICAgICAgICAgIG1vZHVsYXRpb25JbmRleDogMixcbiAgICAgICAgICAgIG1vZHVsYXRpb25UeXBlOiBcInNxdWFyZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0b3AodGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucmVzdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIuYmFzZVR5cGU7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlID0gYmFzZVR5cGU7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvclxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21vZHVsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgbW9kdWxhdGlvblR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnBoYXNlID0gcGhhc2U7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Rk1Pc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuLi8uLi9zaWduYWwvV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG4vKipcbiAqIFB1bHNlT3NjaWxsYXRvciBpcyBhbiBvc2NpbGxhdG9yIHdpdGggY29udHJvbCBvdmVyIHB1bHNlIHdpZHRoLFxuICogYWxzbyBrbm93biBhcyB0aGUgZHV0eSBjeWNsZS4gQXQgNTAlIGR1dHkgY3ljbGUgKHdpZHRoID0gMCkgdGhlIHdhdmUgaXNcbiAqIGEgc3F1YXJlIHdhdmUuXG4gKiBbUmVhZCBtb3JlXShodHRwczovL3dpZ2dsZXdhdmUud29yZHByZXNzLmNvbS8yMDE0LzA4LzE2L3B1bHNlLXdhdmVmb3Jtcy1hbmQtaGFybW9uaWNzLykuXG4gKiBgYGBcbiAqICAgIHdpZHRoID0gLTAuMjUgICAgICAgIHdpZHRoID0gMC4wICAgICAgICAgIHdpZHRoID0gMC4yNVxuICpcbiAqICAgKy0tLS0tKyAgICAgICAgICAgICstLS0tLS0tKyAgICAgICArICAgICstLS0tLS0tKyAgICAgKy0rXG4gKiAgIHwgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgfCAgICAgICAgICAgIHwgICAgIHxcbiAqICAgfCAgICAgfCAgICAgICAgICAgIHwgICAgICAgfCAgICAgICB8ICAgICAgICAgICAgfCAgICAgfFxuICogKy0rICAgICArLS0tLS0tLSsgICAgKyAgICAgICArLS0tLS0tLSsgICAgICAgICAgICArLS0tLS0rXG4gKlxuICpcbiAqICAgIHdpZHRoID0gLTAuNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC41XG4gKlxuICogICAgICstLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0rICAgKy0tLStcbiAqICAgICB8ICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHxcbiAqICAgICB8ICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHxcbiAqICstLS0rICAgKy0tLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLStcbiAqXG4gKlxuICogICAgd2lkdGggPSAtMC43NSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAwLjc1XG4gKlxuICogICAgICAgKy0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0rICstLS0tLStcbiAqICAgICAgIHwgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB8XG4gKiAgICAgICB8IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgfFxuICogKy0tLS0tKyArLS0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBwdWxzZSA9IG5ldyBUb25lLlB1bHNlT3NjaWxsYXRvcig1MCwgMC40KS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBQdWxzZU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQdWxzZU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ3aWR0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlB1bHNlT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogZ2F0ZSB0aGUgd2lkdGggYW1vdW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRocmVzaG9sZCB0aGUgc2lnbmFsIHRvIHR1cm4gaXQgaW50byBhIHNxdWFyZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGhyZXNoID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogdmFsID0+IHZhbCA8PSAwID8gLTEgOiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFB1bHNlT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIndpZHRoXCJdKTtcbiAgICAgICAgdGhpcy53aWR0aCA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiYXVkaW9SYW5nZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMud2lkdGgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl90cmlhbmdsZSA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICAgICAgdHlwZTogXCJ0cmlhbmdsZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl90cmlhbmdsZS5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fdHJpYW5nbGUuZGV0dW5lO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5jaGFpbih0aGlzLl90aHJlc2gsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy53aWR0aC5jaGFpbih0aGlzLl93aWR0aEdhdGUsIHRoaXMuX3RocmVzaCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIndpZHRoXCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICBwaGFzZTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwicHVsc2VcIixcbiAgICAgICAgICAgIHdpZHRoOiAwLjIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLnNldFZhbHVlQXRUaW1lKDEsIHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnN0b3AodGltZSk7XG4gICAgICAgIC8vIHRoZSB3aWR0aCBpcyBzdGlsbCBjb25uZWN0ZWQgdG8gdGhlIG91dHB1dC5cbiAgICAgICAgLy8gdGhhdCBuZWVkcyB0byBiZSBzdG9wcGVkIGFsc29cbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLnNldFZhbHVlQXRUaW1lKDEsIHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3IgaW4gZGVncmVlcy5cbiAgICAgKi9cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90cmlhbmdsZS5waGFzZTtcbiAgICB9XG4gICAgc2V0IHBoYXNlKHBoYXNlKSB7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBBbHdheXMgcmV0dXJucyBcInB1bHNlXCIuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB1bHNlXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlVHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwdWxzZVwiLlxuICAgICAqL1xuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHVsc2VcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhcnRpYWxzIG9mIHRoZSB3YXZlZm9ybS4gQ2Fubm90IHNldCBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5vIHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqICpJbnRlcm5hbCB1c2UqIFRoZSBjYXJyaWVyIG9zY2lsbGF0b3IgdHlwZSBpcyBmZWQgdGhyb3VnaCB0aGVcbiAgICAgKiB3YXZlc2hhcGVyIG5vZGUgdG8gY3JlYXRlIHRoZSBwdWxzZS4gVXNpbmcgZGlmZmVyZW50IGNhcnJpZXIgb3NjaWxsYXRvcnNcbiAgICAgKiBjaGFuZ2VzIG9zY2lsbGF0b3IncyBiZWhhdmlvci5cbiAgICAgKi9cbiAgICBzZXQgY2FycmllclR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl90cmlhbmdsZS50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAgbWV0aG9kLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLndpZHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGhyZXNoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UHVsc2VPc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogRmF0T3NjaWxsYXRvciBpcyBhbiBhcnJheSBvZiBvc2NpbGxhdG9ycyB3aXRoIGRldHVuZSBzcHJlYWQgYmV0d2VlbiB0aGUgb3NjaWxsYXRvcnNcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKFwiQWIzXCIsIFwic2F3dG9vdGhcIiwgNDApLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgRmF0T3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwic3ByZWFkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmF0T3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFycmF5IG9mIG9zY2lsbGF0b3JzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmF0T3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJzcHJlYWRcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NwcmVhZCA9IG9wdGlvbnMuc3ByZWFkO1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLl9waGFzZSA9IG9wdGlvbnMucGhhc2U7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxzID0gb3B0aW9ucy5wYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gb3B0aW9ucy5wYXJ0aWFsQ291bnQ7XG4gICAgICAgIC8vIHNldCB0aGUgY291bnQgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMuY291bnQgPSBvcHRpb25zLmNvdW50O1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY291bnQ6IDMsXG4gICAgICAgICAgICBzcHJlYWQ6IDIwLFxuICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5zdGFydCh0aW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnN0b3AodGltZSkpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5yZXN0YXJ0KHRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGFsbCBvZiB0aGUgb3NjaWxsYXRvcnNcbiAgICAgKi9cbiAgICBfZm9yRWFjaChpdGVyYXRvcikge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpdGVyYXRvcih0aGlzLl9vc2NpbGxhdG9yc1tpXSwgaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy50eXBlID0gdHlwZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZXR1bmUgc3ByZWFkIGJldHdlZW4gdGhlIG9zY2lsbGF0b3JzLiBJZiBcImNvdW50XCIgaXNcbiAgICAgKiBzZXQgdG8gMyBvc2NpbGxhdG9ycyBhbmQgdGhlIFwic3ByZWFkXCIgaXMgc2V0IHRvIDQwLFxuICAgICAqIHRoZSB0aHJlZSBvc2NpbGxhdG9ycyB3b3VsZCBiZSBkZXR1bmVkIGxpa2UgdGhpczogWy0yMCwgMCwgMjBdXG4gICAgICogZm9yIGEgdG90YWwgZGV0dW5lIHNwcmVhZCBvZiA0MCBjZW50cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZhdE9zYyA9IG5ldyBUb25lLkZhdE9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiBmYXRPc2Muc3ByZWFkID0gNzA7XG4gICAgICovXG4gICAgZ2V0IHNwcmVhZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NwcmVhZDtcbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgdGhpcy5fc3ByZWFkID0gc3ByZWFkO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSAtc3ByZWFkIC8gMjtcbiAgICAgICAgICAgIGNvbnN0IHN0ZXAgPSBzcHJlYWQgLyAodGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKChvc2MsIGkpID0+IG9zYy5kZXR1bmUudmFsdWUgPSBzdGFydCArIHN0ZXAgKiBpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGRldHVuZWQgb3NjaWxsYXRvcnMuIE11c3QgYmUgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gMS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZhdE9zYyA9IG5ldyBUb25lLkZhdE9zY2lsbGF0b3IoXCJDIzNcIiwgXCJzYXd0b290aFwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAgICAgKiAvLyB1c2UgNCBzYXd0b290aCBvc2NpbGxhdG9yc1xuICAgICAqIGZhdE9zYy5jb3VudCA9IDQ7XG4gICAgICovXG4gICAgZ2V0IGNvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoO1xuICAgIH1cbiAgICBzZXQgY291bnQoY291bnQpIHtcbiAgICAgICAgYXNzZXJ0UmFuZ2UoY291bnQsIDEpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvcnMubGVuZ3RoICE9PSBjb3VudCkge1xuICAgICAgICAgICAgLy8gZGlzcG9zZSB0aGUgcHJldmlvdXMgb3NjaWxsYXRvcnNcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5kaXNwb3NlKCkpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9zYyA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgICAgICB2b2x1bWU6IC02IC0gY291bnQgKiAxLjEsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IHRoaXMuX3R5cGUsXG4gICAgICAgICAgICAgICAgICAgIHBoYXNlOiB0aGlzLl9waGFzZSArIChpIC8gY291bnQpICogMzYwLFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsQ291bnQ6IHRoaXMuX3BhcnRpYWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgb25zdG9wOiBpID09PSAwID8gKCkgPT4gdGhpcy5vbnN0b3AodGhpcykgOiBub09wLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgb3NjLnBhcnRpYWxzID0gdGhpcy5fcGFydGlhbHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3Qob3NjLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdChvc2MuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBvc2MuZGV0dW5lLm92ZXJyaWRkZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBvc2MuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0gPSBvc2M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBzZXQgdGhlIHNwcmVhZFxuICAgICAgICAgICAgdGhpcy5zcHJlYWQgPSB0aGlzLl9zcHJlYWQ7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2Muc3RhcnQoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKChvc2MsIGkpID0+IG9zYy5waGFzZSA9IHRoaXMuX3BoYXNlICsgKGkgLyB0aGlzLmNvdW50KSAqIDM2MCk7XG4gICAgfVxuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLmJhc2VUeXBlID0gYmFzZVR5cGUpO1xuICAgICAgICB0aGlzLl90eXBlID0gdGhpcy5fb3NjaWxsYXRvcnNbMF0udHlwZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0ucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGg7XG4gICAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSBcImN1c3RvbVwiO1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnBhcnRpYWxzID0gcGFydGlhbHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnBhcnRpYWxDb3VudCA9IHBhcnRpYWxDb3VudCk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0aGlzLl9vc2NpbGxhdG9yc1swXS50eXBlO1xuICAgIH1cbiAgICBhc0FycmF5KGxlbmd0aCA9IDEwMjQpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHJldHVybiBnZW5lcmF0ZVdhdmVmb3JtKHRoaXMsIGxlbmd0aCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MuZGlzcG9zZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmF0T3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IFB1bHNlT3NjaWxsYXRvciB9IGZyb20gXCIuL1B1bHNlT3NjaWxsYXRvclwiO1xuLyoqXG4gKiBQV01Pc2NpbGxhdG9yIG1vZHVsYXRlcyB0aGUgd2lkdGggb2YgYSBUb25lLlB1bHNlT3NjaWxsYXRvclxuICogYXQgdGhlIG1vZHVsYXRpb25GcmVxdWVuY3kuIFRoaXMgaGFzIHRoZSBlZmZlY3Qgb2YgY29udGludW91c2x5XG4gKiBjaGFuZ2luZyB0aGUgdGltYnJlIG9mIHRoZSBvc2NpbGxhdG9yIGJ5IGFsdGVyaW5nIHRoZSBoYXJtb25pY3NcbiAqIGdlbmVyYXRlZC5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgcHdtID0gbmV3IFRvbmUuUFdNT3NjaWxsYXRvcig2MCwgMC4zKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBQV01Pc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUFdNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm1vZHVsYXRpb25GcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQV01Pc2NpbGxhdG9yXCI7XG4gICAgICAgIHRoaXMuc291cmNlVHlwZSA9IFwicHdtXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTY2FsZSB0aGUgb3NjaWxsYXRvciBzbyBpdCBkb2Vzbid0IGdvIHNpbGVudFxuICAgICAgICAgKiBhdCB0aGUgZXh0cmVtZSB2YWx1ZXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2FsZSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMixcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQV01Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwibW9kdWxhdGlvbkZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX3B1bHNlID0gbmV3IFB1bHNlT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMubW9kdWxhdGlvbkZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNoYW5nZSB0aGUgcHVsc2Ugb3NjaWxsYXRvciB0eXBlXG4gICAgICAgIHRoaXMuX3B1bHNlLmNhcnJpZXJUeXBlID0gXCJzaW5lXCI7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkZyZXF1ZW5jeSA9IHRoaXMuX3B1bHNlLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX21vZHVsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gdGhpcy5fbW9kdWxhdG9yLmRldHVuZTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX3NjYWxlLCB0aGlzLl9wdWxzZS53aWR0aCk7XG4gICAgICAgIHRoaXMuX3B1bHNlLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJtb2R1bGF0aW9uRnJlcXVlbmN5XCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICBtb2R1bGF0aW9uRnJlcXVlbmN5OiAwLjQsXG4gICAgICAgICAgICBwaGFzZTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwicHdtXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9wdWxzZS5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fcHVsc2Uuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogcmVzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX3B1bHNlLnJlc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBBbHdheXMgcmV0dXJucyBcInB3bVwiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwd21cIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2VUeXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBBbHdheXMgcmV0dXJucyBcInB3bVwiLlxuICAgICAqL1xuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHdtXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYXJ0aWFscyBvZiB0aGUgd2F2ZWZvcm0uIENhbm5vdCBzZXQgcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBObyBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlLlxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGhhc2Ugb2YgdGhlIG9zY2lsbGF0b3IgaW4gZGVncmVlcy5cbiAgICAgKi9cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wdWxzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UFdNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNOdW1iZXIsIGlzU3RyaW5nIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBBTU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9BTU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IEZhdE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9GYXRPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBGTU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9GTU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgUHVsc2VPc2NpbGxhdG9yIH0gZnJvbSBcIi4vUHVsc2VPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBQV01Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vUFdNT3NjaWxsYXRvclwiO1xuY29uc3QgT21uaU9zY2lsbGF0b3JTb3VyY2VNYXAgPSB7XG4gICAgYW06IEFNT3NjaWxsYXRvcixcbiAgICBmYXQ6IEZhdE9zY2lsbGF0b3IsXG4gICAgZm06IEZNT3NjaWxsYXRvcixcbiAgICBvc2NpbGxhdG9yOiBPc2NpbGxhdG9yLFxuICAgIHB1bHNlOiBQdWxzZU9zY2lsbGF0b3IsXG4gICAgcHdtOiBQV01Pc2NpbGxhdG9yLFxufTtcbi8qKlxuICogT21uaU9zY2lsbGF0b3IgYWdncmVnYXRlcyBhbGwgb2YgdGhlIG9zY2lsbGF0b3IgdHlwZXMgaW50byBvbmUuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcihcIkMjNFwiLCBcInB3bVwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIH0sIDAuMSwgMSk7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBPbW5pT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9tbmlPc2NpbGxhdG9yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgICAgIC8vIHNldCB0aGUgb3B0aW9uc1xuICAgICAgICB0aGlzLnNldChvcHRpb25zKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIEZNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBBTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgRmF0T3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBQdWxzZU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgUFdNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IucmVzdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBDYW4gYmUgYW55IG9mIHRoZSBiYXNpYyB0eXBlczogc2luZSwgc3F1YXJlLCB0cmlhbmdsZSwgc2F3dG9vdGguIE9yXG4gICAgICogcHJlZml4IHRoZSBiYXNpYyB0eXBlcyB3aXRoIFwiZm1cIiwgXCJhbVwiLCBvciBcImZhdFwiIHRvIHVzZSB0aGUgRk1Pc2NpbGxhdG9yLCBBTU9zY2lsbGF0b3Igb3IgRmF0T3NjaWxsYXRvclxuICAgICAqIHR5cGVzLiBUaGUgb3NjaWxsYXRvciBjb3VsZCBhbHNvIGJlIHNldCB0byBcInB3bVwiIG9yIFwicHVsc2VcIi4gQWxsIG9mIHRoZSBwYXJhbWV0ZXJzIG9mIHRoZVxuICAgICAqIG9zY2lsbGF0b3IncyBjbGFzcyBhcmUgYWNjZXNzaWJsZSB3aGVuIHRoZSBvc2NpbGxhdG9yIGlzIHNldCB0byB0aGF0IHR5cGUsIGJ1dCB0aHJvd3MgYW4gZXJyb3JcbiAgICAgKiB3aGVuIGl0J3Mgbm90LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb21uaU9zYyA9IG5ldyBUb25lLk9tbmlPc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogb21uaU9zYy50eXBlID0gXCJwd21cIjtcbiAgICAgKiAvLyBtb2R1bGF0aW9uRnJlcXVlbmN5IGlzIHBhcmFtZXRlciB3aGljaCBpcyBhdmFpbGFibGVcbiAgICAgKiAvLyBvbmx5IHdoZW4gdGhlIHR5cGUgaXMgXCJwd21cIi5cbiAgICAgKiBvbW5pT3NjLm1vZHVsYXRpb25GcmVxdWVuY3kudmFsdWUgPSAwLjU7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIGxldCBwcmVmaXggPSBcIlwiO1xuICAgICAgICBpZiAoW1wiYW1cIiwgXCJmbVwiLCBcImZhdFwiXS5zb21lKHAgPT4gdGhpcy5fc291cmNlVHlwZSA9PT0gcCkpIHtcbiAgICAgICAgICAgIHByZWZpeCA9IHRoaXMuX3NvdXJjZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByZWZpeCArIHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBpZiAodHlwZS5zdWJzdHIoMCwgMikgPT09IFwiZm1cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImZtXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlLnN1YnN0cigwLCAyKSA9PT0gXCJhbVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwiYW1cIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGUuc3Vic3RyKDIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUuc3Vic3RyKDAsIDMpID09PSBcImZhdFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwiZmF0XCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlID09PSBcInB3bVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwicHdtXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwicHVsc2VcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9jcmVhdGVOZXdPc2NpbGxhdG9yKFwib3NjaWxsYXRvclwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgaXMgYW4gZW1wdHkgYXJyYXkgd2hlbiB0aGUgdHlwZSBpcyBub3QgXCJjdXN0b21cIi5cbiAgICAgKiBUaGlzIGlzIG5vdCBhdmFpbGFibGUgb24gXCJwd21cIiBhbmQgXCJwdWxzZVwiIG9zY2lsbGF0b3IgdHlwZXMuXG4gICAgICogU2VlIFtbT3NjaWxsYXRvci5wYXJ0aWFsc11dXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIGlmICghdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB1bHNlXCIpICYmICF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICBpZiAoIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSAmJiAhdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0KHByb3BzKSB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgdHlwZSBpcyBzZXQgZmlyc3RcbiAgICAgICAgaWYgKFJlZmxlY3QuaGFzKHByb3BzLCBcInR5cGVcIikgJiYgcHJvcHMudHlwZSkge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gcHJvcHMudHlwZTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGVuIHNldCB0aGUgcmVzdFxuICAgICAgICBzdXBlci5zZXQocHJvcHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY29ubmVjdCB0aGUgb3NjaWxsYXRvciB0byB0aGUgZnJlcXVlbmN5IGFuZCBkZXR1bmUgc2lnbmFsc1xuICAgICAqL1xuICAgIF9jcmVhdGVOZXdPc2NpbGxhdG9yKG9zY1R5cGUpIHtcbiAgICAgICAgaWYgKG9zY1R5cGUgIT09IHRoaXMuX3NvdXJjZVR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZVR5cGUgPSBvc2NUeXBlO1xuICAgICAgICAgICAgY29uc3QgT3NjQ29uc3RydWN0b3IgPSBPbW5pT3NjaWxsYXRvclNvdXJjZU1hcFtvc2NUeXBlXTtcbiAgICAgICAgICAgIC8vIHNob3J0IGRlbGF5IHRvIGF2b2lkIGNsaWNrcyBvbiB0aGUgY2hhbmdlXG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvbGRPc2MgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgICAgIG9sZE9zYy5zdG9wKG5vdyk7XG4gICAgICAgICAgICAgICAgLy8gZGlzcG9zZSB0aGUgb2xkIG9uZVxuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IG9sZE9zYy5kaXNwb3NlKCksIHRoaXMuYmxvY2tUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBuZXcgT3NjQ29uc3RydWN0b3Ioe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZGV0dW5lKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLm9uc3RvcCA9ICgpID0+IHRoaXMub25zdG9wKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydChub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzb3VyY2UgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcig0NDAsIFwiZm1zcXVhcmVcIik7XG4gICAgICogY29uc29sZS5sb2cob21uaU9zYy5zb3VyY2VUeXBlKTsgLy8gJ2ZtJ1xuICAgICAqL1xuICAgIGdldCBzb3VyY2VUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlVHlwZTtcbiAgICB9XG4gICAgc2V0IHNvdXJjZVR5cGUoc1R5cGUpIHtcbiAgICAgICAgLy8gdGhlIGJhc2V0eXBlIGRlZmF1bHRzIHRvIHNpbmVcbiAgICAgICAgbGV0IGJhc2VUeXBlID0gXCJzaW5lXCI7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yLnR5cGUgIT09IFwicHdtXCIgJiYgdGhpcy5fb3NjaWxsYXRvci50eXBlICE9PSBcInB1bHNlXCIpIHtcbiAgICAgICAgICAgIGJhc2VUeXBlID0gdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNldCB0aGUgdHlwZVxuICAgICAgICBpZiAoc1R5cGUgPT09IFwiZm1cIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJmbVwiICsgYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwiYW1cIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJhbVwiICsgYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwiZmF0XCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiZmF0XCIgKyBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJvc2NpbGxhdG9yXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcInB1bHNlXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwicHVsc2VcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJwd21cIikge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gXCJwd21cIjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBfZ2V0T3NjVHlwZShvc2MsIHNvdXJjZVR5cGUpIHtcbiAgICAgICAgcmV0dXJuIG9zYyBpbnN0YW5jZW9mIE9tbmlPc2NpbGxhdG9yU291cmNlTWFwW3NvdXJjZVR5cGVdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yLiBTZWUgW1tPc2NpbGxhdG9yLmJhc2VUeXBlXV1cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcig0NDAsIFwiZm1zcXVhcmU0XCIpO1xuICAgICAqIGNvbnNvbGUubG9nKG9tbmlPc2Muc291cmNlVHlwZSwgb21uaU9zYy5iYXNlVHlwZSwgb21uaU9zYy5wYXJ0aWFsQ291bnQpO1xuICAgICAqL1xuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IuYmFzZVR5cGU7XG4gICAgfVxuICAgIHNldCBiYXNlVHlwZShiYXNlVHlwZSkge1xuICAgICAgICBpZiAoIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSAmJlxuICAgICAgICAgICAgIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikgJiZcbiAgICAgICAgICAgIGJhc2VUeXBlICE9PSBcInB1bHNlXCIgJiYgYmFzZVR5cGUgIT09IFwicHdtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuYmFzZVR5cGUgPSBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgd2lkdGggb2YgdGhlIG9zY2lsbGF0b3Igd2hlbiBzb3VyY2VUeXBlID09PSBcInB1bHNlXCIuXG4gICAgICogU2VlIFtbUFdNT3NjaWxsYXRvci53aWR0aF1dXG4gICAgICovXG4gICAgZ2V0IHdpZHRoKCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB1bHNlXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci53aWR0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkZXR1bmVkIG9zY2lsbGF0b3JzIHdoZW4gc291cmNlVHlwZSA9PT0gXCJmYXRcIi5cbiAgICAgKiBTZWUgW1tGYXRPc2NpbGxhdG9yLmNvdW50XV1cbiAgICAgKi9cbiAgICBnZXQgY291bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZmF0XCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5jb3VudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGNvdW50KGNvdW50KSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZmF0XCIpICYmIGlzTnVtYmVyKGNvdW50KSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jb3VudCA9IGNvdW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZXR1bmUgc3ByZWFkIGJldHdlZW4gdGhlIG9zY2lsbGF0b3JzIHdoZW4gc291cmNlVHlwZSA9PT0gXCJmYXRcIi5cbiAgICAgKiBTZWUgW1tGYXRPc2NpbGxhdG9yLmNvdW50XV1cbiAgICAgKi9cbiAgICBnZXQgc3ByZWFkKCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iuc3ByZWFkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgc3ByZWFkKHNwcmVhZCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSAmJiBpc051bWJlcihzcHJlYWQpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnNwcmVhZCA9IHNwcmVhZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3IuIE9ubHkgaWYgdGhlIG9zY2lsbGF0b3IgaXMgc2V0IHRvIFwiYW1cIiBvciBcImZtXCIgdHlwZXMuXG4gICAgICogU2VlIFtbQU1Pc2NpbGxhdG9yXV0gb3IgW1tGTU9zY2lsbGF0b3JdXVxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uVHlwZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSB8fCB0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiYW1cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25UeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgbW9kdWxhdGlvblR5cGUobVR5cGUpIHtcbiAgICAgICAgaWYgKCh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikgfHwgdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImFtXCIpKSAmJiBpc1N0cmluZyhtVHlwZSkpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvblR5cGUgPSBtVHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbW9kdWxhdGlvbiBpbmRleCB3aGVuIHRoZSBzb3VyY2VUeXBlID09PSBcImZtXCJcbiAgICAgKiBTZWUgW1tGTU9zY2lsbGF0b3JdXS5cbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvbkluZGV4KCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uSW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhhcm1vbmljaXR5IGlzIHRoZSBmcmVxdWVuY3kgcmF0aW8gYmV0d2VlbiB0aGUgY2FycmllciBhbmQgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9ycy5cbiAgICAgKiBTZWUgW1tBTU9zY2lsbGF0b3JdXSBvciBbW0ZNT3NjaWxsYXRvcl1dXG4gICAgICovXG4gICAgZ2V0IGhhcm1vbmljaXR5KCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpIHx8IHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJhbVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IuaGFybW9uaWNpdHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtb2R1bGF0aW9uRnJlcXVlbmN5IFNpZ25hbCBvZiB0aGUgb3NjaWxsYXRvciB3aGVuIHNvdXJjZVR5cGUgPT09IFwicHdtXCJcbiAgICAgKiBzZWUgW1tQV01Pc2NpbGxhdG9yXV1cbiAgICAgKiBAbWluIDAuMVxuICAgICAqIEBtYXggNVxuICAgICAqL1xuICAgIGdldCBtb2R1bGF0aW9uRnJlcXVlbmN5KCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvbkZyZXF1ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9tbmlPc2NpbGxhdG9yLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3RTZXJpZXMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG4vKipcbiAqIEFkZCBhIHNpZ25hbCBhbmQgYSBudW1iZXIgb3IgdHdvIHNpZ25hbHMuIFdoZW4gbm8gdmFsdWUgaXNcbiAqIHBhc3NlZCBpbnRvIHRoZSBjb25zdHJ1Y3RvciwgVG9uZS5BZGQgd2lsbCBzdW0gaW5wdXQgYW5kIGBhZGRlbmRgXG4gKiBJZiBhIHZhbHVlIGlzIHBhc3NlZCBpbnRvIHRoZSBjb25zdHJ1Y3RvciwgdGhlIGl0IHdpbGwgYmUgYWRkZWQgdG8gdGhlIGlucHV0LlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYWRkID0gbmV3IFRvbmUuQWRkKDIpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0YWRkLmFkZGVuZC5zZXRWYWx1ZUF0VGltZSgxLCAwLjIpO1xuICogXHRjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMik7XG4gKiBcdC8vIGFkZCBhIHNpZ25hbCBhbmQgYSBzY2FsYXJcbiAqIFx0c2lnbmFsLmNvbm5lY3QoYWRkKTtcbiAqIFx0c2lnbmFsLnNldFZhbHVlQXRUaW1lKDEsIDAuMSk7XG4gKiB9LCAwLjUsIDEpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgQWRkIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhBZGQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSkpKTtcbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFkZFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHN1bW1pbmcgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3VtID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9zdW07XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIHdoaWNoIGlzIGFkZGVkIHRvIHRoZSBpbnB1dCBzaWduYWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYWRkZW5kID0gdGhpcy5fcGFyYW07XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5fY29uc3RhbnRTb3VyY2UsIHRoaXMuX3N1bSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdW0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BZGQuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBBZGQgfSBmcm9tIFwiLi9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4vTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogUGVyZm9ybXMgYSBsaW5lYXIgc2NhbGluZyBvbiBhbiBpbnB1dCBzaWduYWwuXG4gKiBTY2FsZXMgYSBOb3JtYWxSYW5nZSBpbnB1dCB0byBiZXR3ZWVuXG4gKiBvdXRwdXRNaW4gYW5kIG91dHB1dE1heC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc2NhbGUgPSBuZXcgVG9uZS5TY2FsZSg1MCwgMTAwKTtcbiAqIGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3Qoc2NhbGUpO1xuICogLy8gdGhlIG91dHB1dCBvZiBzY2FsZSBlcXVhbHMgNzVcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNjYWxlIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNjYWxlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiXSk7XG4gICAgICAgIHRoaXMuX211bHQgPSB0aGlzLmlucHV0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm1heCAtIG9wdGlvbnMubWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYWRkID0gdGhpcy5vdXRwdXQgPSBuZXcgQWRkKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm1pbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21pbiA9IG9wdGlvbnMubWluO1xuICAgICAgICB0aGlzLl9tYXggPSBvcHRpb25zLm1heDtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWxPcGVyYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgbnVtYmVyIGlzIG91dHB1dCB3aGVuIHRoZSB2YWx1ZSBpbnB1dCB2YWx1ZSBpcyAwLlxuICAgICAqL1xuICAgIGdldCBtaW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW47XG4gICAgfVxuICAgIHNldCBtaW4obWluKSB7XG4gICAgICAgIHRoaXMuX21pbiA9IG1pbjtcbiAgICAgICAgdGhpcy5fc2V0UmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlbiB0aGUgdmFsdWUgaW5wdXQgdmFsdWUgaXMgMS5cbiAgICAgKi9cbiAgICBnZXQgbWF4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWF4O1xuICAgIH1cbiAgICBzZXQgbWF4KG1heCkge1xuICAgICAgICB0aGlzLl9tYXggPSBtYXg7XG4gICAgICAgIHRoaXMuX3NldFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHNldCB0aGUgdmFsdWVzXG4gICAgICovXG4gICAgX3NldFJhbmdlKCkge1xuICAgICAgICB0aGlzLl9hZGQudmFsdWUgPSB0aGlzLl9taW47XG4gICAgICAgIHRoaXMuX211bHQudmFsdWUgPSB0aGlzLl9tYXggLSB0aGlzLl9taW47XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWRkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNjYWxlLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3QsIGRpc2Nvbm5lY3QgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuLyoqXG4gKiBUb25lLlplcm8gb3V0cHV0cyAwJ3MgYXQgYXVkaW8tcmF0ZS4gVGhlIHJlYXNvbiB0aGlzIGhhcyB0byBiZVxuICogaXQncyBvd24gY2xhc3MgaXMgdGhhdCBtYW55IGJyb3dzZXJzIG9wdGltaXplIG91dCBUb25lLlNpZ25hbFxuICogd2l0aCBhIHZhbHVlIG9mIDAgYW5kIHdpbGwgbm90IHByb2Nlc3Mgbm9kZXMgZnVydGhlciBkb3duIHRoZSBncmFwaC5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFplcm8gZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoWmVyby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiWmVyb1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGdhaW4gbm9kZSB3aGljaCBjb25uZWN0cyB0aGUgY29uc3RhbnQgc291cmNlIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2dhaW4gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9ubHkgb3V0cHV0cyAwXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW47XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBubyBpbnB1dCBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25uZWN0KHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgwKSwgdGhpcy5fZ2Fpbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBkaXNjb25uZWN0KHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgwKSwgdGhpcy5fZ2Fpbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVplcm8uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEF1ZGlvVG9HYWluIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BdWRpb1RvR2FpblwiO1xuaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NjYWxlXCI7XG5pbXBvcnQgeyBjb25uZWN0U2lnbmFsLCBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgWmVybyB9IGZyb20gXCIuLi8uLi9zaWduYWwvWmVyb1wiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbi8qKlxuICogTEZPIHN0YW5kcyBmb3IgbG93IGZyZXF1ZW5jeSBvc2NpbGxhdG9yLiBMRk8gcHJvZHVjZXMgYW4gb3V0cHV0IHNpZ25hbFxuICogd2hpY2ggY2FuIGJlIGF0dGFjaGVkIHRvIGFuIEF1ZGlvUGFyYW0gb3IgVG9uZS5TaWduYWxcbiAqIGluIG9yZGVyIHRvIG1vZHVsYXRlIHRoYXQgcGFyYW1ldGVyIHdpdGggYW4gb3NjaWxsYXRvci4gVGhlIExGTyBjYW5cbiAqIGFsc28gYmUgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQgdG8gc3RhcnQvc3RvcCBhbmQgY2hhbmdlIHdoZW4gdGhlIHRlbXBvIGNoYW5nZXMuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGxmbyA9IG5ldyBUb25lLkxGTyhcIjRuXCIsIDQwMCwgNDAwMCkuc3RhcnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiB9LCAwLjUsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgTEZPIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKExGTy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm1pblwiLCBcIm1heFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxGT1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIHRoYXQgdGhlIExGTyBvdXRwdXRzIHdoZW4gaXQncyBzdG9wcGVkXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdG9wcGVkVmFsdWUgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBwcml2YXRlIHBsYWNlaG9sZGVyIGZvciB0aGUgdW5pdHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3VuaXRzID0gXCJudW1iZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoZSBpbnB1dCB2YWx1ZSBpcyBjb252ZXJ0ZWQgdXNpbmcgdGhlIFtbdW5pdHNdXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jb252ZXJ0ID0gdHJ1ZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByaXZhdGUgbWV0aG9kcyBib3Jyb3dlZCBmcm9tIFBhcmFtXG4gICAgICAgICAqL1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2Zyb21UeXBlID0gUGFyYW0ucHJvdG90eXBlLl9mcm9tVHlwZTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl90b1R5cGUgPSBQYXJhbS5wcm90b3R5cGUuX3RvVHlwZTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9pcyA9IFBhcmFtLnByb3RvdHlwZS5faXM7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fY2xhbXBWYWx1ZSA9IFBhcmFtLnByb3RvdHlwZS5fY2xhbXBWYWx1ZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKExGTy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm1pblwiLCBcIm1heFwiXSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBuZXcgT3NjaWxsYXRvcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMuYW1wbGl0dWRlLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYW1wbGl0dWRlID0gdGhpcy5fYW1wbGl0dWRlR2Fpbi5nYWluO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJhdWRpb1JhbmdlXCIsXG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3plcm9zID0gbmV3IFplcm8oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2EyZyA9IG5ldyBBdWRpb1RvR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fc2NhbGVyID0gdGhpcy5vdXRwdXQgPSBuZXcgU2NhbGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4OiBvcHRpb25zLm1heCxcbiAgICAgICAgICAgIG1pbjogb3B0aW9ucy5taW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVuaXRzID0gb3B0aW9ucy51bml0cztcbiAgICAgICAgdGhpcy5taW4gPSBvcHRpb25zLm1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBvcHRpb25zLm1heDtcbiAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNoYWluKHRoaXMuX2FtcGxpdHVkZUdhaW4sIHRoaXMuX2EyZywgdGhpcy5fc2NhbGVyKTtcbiAgICAgICAgdGhpcy5femVyb3MuY29ubmVjdCh0aGlzLl9hMmcpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLmNvbm5lY3QodGhpcy5fYTJnKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiYW1wbGl0dWRlXCIsIFwiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5waGFzZSA9IG9wdGlvbnMucGhhc2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhbXBsaXR1ZGU6IDEsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IFwiNG5cIixcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgTEZPLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRoZSBMRk8gd2lsbCBzdGFydFxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgTEZPLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0aGUgTEZPIHdpbGwgc3RvcFxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3N0b3BwZWRTaWduYWwuc2V0VmFsdWVBdFRpbWUodGhpcy5fc3RvcHBlZFZhbHVlLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgc3RhcnQvc3RvcC9wYXVzZSB0byB0aGUgdHJhbnNwb3J0XG4gICAgICogYW5kIHRoZSBmcmVxdWVuY3kgdG8gdGhlIGJwbSBvZiB0aGUgdHJhbnNwb3J0XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsZm8gPSBuZXcgVG9uZS5MRk8oXCI4blwiKTtcbiAgICAgKiBsZm8uc3luYygpLnN0YXJ0KDApO1xuICAgICAqIC8vIHRoZSByYXRlIG9mIHRoZSBMRk8gd2lsbCBhbHdheXMgYmUgYW4gZWlnaHRoIG5vdGUsIGV2ZW4gYXMgdGhlIHRlbXBvIGNoYW5nZXNcbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN5bmMoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zeW5jRnJlcXVlbmN5KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB1bnN5bmMgdGhlIExGTyBmcm9tIHRyYW5zcG9ydCBjb250cm9sXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnVuc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWZ0ZXIgdGhlIG9zY2lsbGF0b3Igd2F2ZWZvcm0gaXMgdXBkYXRlZCwgcmVzZXQgdGhlIGBfc3RvcHBlZFNpZ25hbGAgdmFsdWUgdG8gbWF0Y2ggdGhlIHVwZGF0ZWQgd2F2ZWZvcm1cbiAgICAgKi9cbiAgICBfc2V0U3RvcHBlZFZhbHVlKCkge1xuICAgICAgICB0aGlzLl9zdG9wcGVkVmFsdWUgPSB0aGlzLl9vc2NpbGxhdG9yLmdldEluaXRpYWxWYWx1ZSgpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnZhbHVlID0gdGhpcy5fc3RvcHBlZFZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSBvdXRwdXQgb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgbWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdG9UeXBlKHRoaXMuX3NjYWxlci5taW4pO1xuICAgIH1cbiAgICBzZXQgbWluKG1pbikge1xuICAgICAgICBtaW4gPSB0aGlzLl9mcm9tVHlwZShtaW4pO1xuICAgICAgICB0aGlzLl9zY2FsZXIubWluID0gbWluO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBvdXRwdXQgb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgbWF4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdG9UeXBlKHRoaXMuX3NjYWxlci5tYXgpO1xuICAgIH1cbiAgICBzZXQgbWF4KG1heCkge1xuICAgICAgICBtYXggPSB0aGlzLl9mcm9tVHlwZShtYXgpO1xuICAgICAgICB0aGlzLl9zY2FsZXIubWF4ID0gbWF4O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvcjogU2VlIFtbT3NjaWxsYXRvci50eXBlXV1cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9zZXRTdG9wcGVkVmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IncyBwYXJ0aWFscyBhcnJheTogU2VlIFtbT3NjaWxsYXRvci5wYXJ0aWFsc11dXG4gICAgICovXG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgdGhpcy5fc2V0U3RvcHBlZFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwaGFzZSBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgICAgIHRoaXMuX3NldFN0b3BwZWRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3V0cHV0IHVuaXRzIG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IHVuaXRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdW5pdHM7XG4gICAgfVxuICAgIHNldCB1bml0cyh2YWwpIHtcbiAgICAgICAgY29uc3QgY3VycmVudE1pbiA9IHRoaXMubWluO1xuICAgICAgICBjb25zdCBjdXJyZW50TWF4ID0gdGhpcy5tYXg7XG4gICAgICAgIC8vIGNvbnZlcnQgdGhlIG1pbiBhbmQgdGhlIG1heFxuICAgICAgICB0aGlzLl91bml0cyA9IHZhbDtcbiAgICAgICAgdGhpcy5taW4gPSBjdXJyZW50TWluO1xuICAgICAgICB0aGlzLm1heCA9IGN1cnJlbnRNYXg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnN0YXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gbm9kZSB0aGUgZGVzdGluYXRpb24gdG8gY29ubmVjdCB0b1xuICAgICAqIEBwYXJhbSBvdXRwdXROdW0gdGhlIG9wdGlvbmFsIG91dHB1dCBudW1iZXJcbiAgICAgKiBAcGFyYW0gaW5wdXROdW0gdGhlIGlucHV0IG51bWJlclxuICAgICAqL1xuICAgIGNvbm5lY3Qobm9kZSwgb3V0cHV0TnVtLCBpbnB1dE51bSkge1xuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFBhcmFtIHx8IG5vZGUgaW5zdGFuY2VvZiBTaWduYWwpIHtcbiAgICAgICAgICAgIHRoaXMuY29udmVydCA9IG5vZGUuY29udmVydDtcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPSBub2RlLnVuaXRzO1xuICAgICAgICB9XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgbm9kZSwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5femVyb3MuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hMmcuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVHYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5hbXBsaXR1ZGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1MRk8uanMubWFwIiwiaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi9EZWJ1Z1wiO1xuLyoqXG4gKiBBc3NlcnQgdGhhdCB0aGUgbnVtYmVyIGlzIGluIHRoZSBnaXZlbiByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmdlKG1pbiwgbWF4ID0gSW5maW5pdHkpIHtcbiAgICBjb25zdCB2YWx1ZU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZU1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRSYW5nZShuZXdWYWx1ZSwgbWluLCBtYXgpO1xuICAgICAgICAgICAgICAgIHZhbHVlTWFwLnNldCh0aGlzLCBuZXdWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59XG4vKipcbiAqIENvbnZlcnQgdGhlIHRpbWUgdG8gc2Vjb25kcyBhbmQgYXNzZXJ0IHRoYXQgdGhlIHRpbWUgaXMgaW4gYmV0d2VlbiB0aGUgdHdvXG4gKiB2YWx1ZXMgd2hlbiBiZWluZyBzZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aW1lUmFuZ2UobWluLCBtYXggPSBJbmZpbml0eSkge1xuICAgIGNvbnN0IHZhbHVlTWFwID0gbmV3IFdlYWtNYXAoKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwgcHJvcGVydHlLZXkpIHtcbiAgICAgICAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5S2V5LCB7XG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlTWFwLmdldCh0aGlzKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6IGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xuICAgICAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKG5ld1ZhbHVlKSwgbWluLCBtYXgpO1xuICAgICAgICAgICAgICAgIHZhbHVlTWFwLnNldCh0aGlzLCBuZXdWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWNvcmF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyLCBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzVW5kZWYgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgdGltZVJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbi8qKlxuICogUGxheWVyIGlzIGFuIGF1ZGlvIGZpbGUgcGxheWVyIHdpdGggc3RhcnQsIGxvb3AsIGFuZCBzdG9wIGZ1bmN0aW9ucy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9nb25nXzEubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHBsYXkgYXMgc29vbiBhcyB0aGUgYnVmZmVyIGlzIGxvYWRlZFxuICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBQbGF5ZXIgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQbGF5ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQbGF5ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgYWN0aXZlIGJ1ZmZlciBzb3VyY2Ugbm9kZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBuZXcgU2V0KCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQbGF5ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKHtcbiAgICAgICAgICAgIG9ubG9hZDogdGhpcy5fb25sb2FkLmJpbmQodGhpcywgb3B0aW9ucy5vbmxvYWQpLFxuICAgICAgICAgICAgb25lcnJvcjogb3B0aW9ucy5vbmVycm9yLFxuICAgICAgICAgICAgcmV2ZXJzZTogb3B0aW9ucy5yZXZlcnNlLFxuICAgICAgICAgICAgdXJsOiBvcHRpb25zLnVybCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXV0b3N0YXJ0ID0gb3B0aW9ucy5hdXRvc3RhcnQ7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcbiAgICAgICAgdGhpcy5mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdXRvc3RhcnQ6IGZhbHNlLFxuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgICAgICByZXZlcnNlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWQgdGhlIGF1ZGlvIGZpbGUgYXMgYW4gYXVkaW8gYnVmZmVyLlxuICAgICAqIERlY29kZXMgdGhlIGF1ZGlvIGFzeW5jaHJvbm91c2x5IGFuZCBpbnZva2VzXG4gICAgICogdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGF1ZGlvIGJ1ZmZlciBsb2Fkcy5cbiAgICAgKiBOb3RlOiB0aGlzIGRvZXMgbm90IG5lZWQgdG8gYmUgY2FsbGVkIGlmIGEgdXJsXG4gICAgICogd2FzIHBhc3NlZCBpbiB0byB0aGUgY29uc3RydWN0b3IuIE9ubHkgdXNlIHRoaXNcbiAgICAgKiBpZiB5b3Ugd2FudCB0byBtYW51YWxseSBsb2FkIGEgbmV3IHVybC5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIGJ1ZmZlciB0byBsb2FkLiBGaWxldHlwZSBzdXBwb3J0IGRlcGVuZHMgb24gdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHlpZWxkIHRoaXMuX2J1ZmZlci5sb2FkKHVybCk7XG4gICAgICAgICAgICB0aGlzLl9vbmxvYWQoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgY2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGxvYWRlZC5cbiAgICAgKi9cbiAgICBfb25sb2FkKGNhbGxiYWNrID0gbm9PcCkge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICBpZiAodGhpcy5hdXRvc3RhcnQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBjYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgZG9uZSBwbGF5aW5nLlxuICAgICAqL1xuICAgIF9vblNvdXJjZUVuZChzb3VyY2UpIHtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBvbnN0b3AgZnVuY3Rpb25cbiAgICAgICAgdGhpcy5vbnN0b3AodGhpcyk7XG4gICAgICAgIC8vIGRlbGV0ZSB0aGUgc291cmNlIGZyb20gdGhlIGFjdGl2ZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZGVsZXRlKHNvdXJjZSk7XG4gICAgICAgIGlmICh0aGlzLl9hY3RpdmVTb3VyY2VzLnNpemUgPT09IDAgJiYgIXRoaXMuX3N5bmNlZCAmJlxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlICdpbXBsaWNpdEVuZCcgZXZlbnQgYW5kIHJlcGxhY2Ugd2l0aCBhbiBleHBsaWNpdCBlbmRcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aGlzLm5vdygpKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aGlzLm5vdygpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQbGF5IHRoZSBidWZmZXIgYXQgdGhlIGdpdmVuIHN0YXJ0VGltZS4gT3B0aW9uYWxseSBhZGQgYW4gb2Zmc2V0XG4gICAgICogYW5kL29yIGR1cmF0aW9uIHdoaWNoIHdpbGwgcGxheSB0aGUgYnVmZmVyIGZyb20gYSBwb3NpdGlvblxuICAgICAqIHdpdGhpbiB0aGUgYnVmZmVyIGZvciB0aGUgZ2l2ZW4gZHVyYXRpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcGxheWVyIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc2FtcGxlIHRvIHN0YXJ0IGF0LlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb24gaXMgZ2l2ZW4sIGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHN1cGVyLnN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgc3RhcnQgbWV0aG9kXG4gICAgICovXG4gICAgX3N0YXJ0KHN0YXJ0VGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICAvLyBpZiBpdCdzIGEgbG9vcCB0aGUgZGVmYXVsdCBvZmZzZXQgaXMgdGhlIGxvb3BTdGFydCBwb2ludFxuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIDBcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBjb21wdXRlIHRoZSB2YWx1ZXMgaW4gc2Vjb25kc1xuICAgICAgICBjb25zdCBjb21wdXRlZE9mZnNldCA9IHRoaXMudG9TZWNvbmRzKG9mZnNldCk7XG4gICAgICAgIC8vIGNvbXB1dGUgdGhlIGR1cmF0aW9uIHdoaWNoIGlzIGVpdGhlciB0aGUgcGFzc2VkIGluIGR1cmF0aW9uIG9mIHRoZSBidWZmZXIuZHVyYXRpb24gLSBvZmZzZXRcbiAgICAgICAgY29uc3Qgb3JpZ0R1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICAgIGR1cmF0aW9uID0gZGVmYXVsdEFyZyhkdXJhdGlvbiwgTWF0aC5tYXgodGhpcy5fYnVmZmVyLmR1cmF0aW9uIC0gY29tcHV0ZWRPZmZzZXQsIDApKTtcbiAgICAgICAgbGV0IGNvbXB1dGVkRHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIC8vIHNjYWxlIGl0IGJ5IHRoZSBwbGF5YmFjayByYXRlXG4gICAgICAgIGNvbXB1dGVkRHVyYXRpb24gPSBjb21wdXRlZER1cmF0aW9uIC8gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgICAgICAvLyBnZXQgdGhlIHN0YXJ0IHRpbWVcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgLy8gbWFrZSB0aGUgc291cmNlXG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgIHVybDogdGhpcy5fYnVmZmVyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZmFkZUluOiB0aGlzLmZhZGVJbixcbiAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuZmFkZU91dCxcbiAgICAgICAgICAgIGxvb3A6IHRoaXMuX2xvb3AsXG4gICAgICAgICAgICBsb29wRW5kOiB0aGlzLl9sb29wRW5kLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLl9sb29wU3RhcnQsXG4gICAgICAgICAgICBvbmVuZGVkOiB0aGlzLl9vblNvdXJjZUVuZC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiB0aGlzLl9wbGF5YmFja1JhdGUsXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAvLyBzZXQgdGhlIGxvb3BpbmcgcHJvcGVydGllc1xuICAgICAgICBpZiAoIXRoaXMuX2xvb3AgJiYgIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgLy8gY2FuY2VsIHRoZSBwcmV2aW91cyBzdG9wXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoc3RhcnRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIG5vdCBsb29waW5nLCBzZXQgdGhlIHN0YXRlIGNoYW5nZSBhdCB0aGUgZW5kIG9mIHRoZSBzYW1wbGVcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBzdGFydFRpbWUgKyBjb21wdXRlZER1cmF0aW9uLCB7XG4gICAgICAgICAgICAgICAgaW1wbGljaXRFbmQ6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGFycmF5IG9mIGFjdGl2ZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuYWRkKHNvdXJjZSk7XG4gICAgICAgIC8vIHN0YXJ0IGl0XG4gICAgICAgIGlmICh0aGlzLl9sb29wICYmIGlzVW5kZWYob3JpZ0R1cmF0aW9uKSkge1xuICAgICAgICAgICAgc291cmNlLnN0YXJ0KHN0YXJ0VGltZSwgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gc3VidHJhY3QgdGhlIGZhZGUgb3V0IHRpbWVcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydChzdGFydFRpbWUsIGNvbXB1dGVkT2Zmc2V0LCBjb21wdXRlZER1cmF0aW9uIC0gdGhpcy50b1NlY29uZHModGhpcy5mYWRlT3V0KSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBwbGF5YmFjay5cbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5zdG9wKGNvbXB1dGVkVGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIGFuZCB0aGVuIHJlc3RhcnQgdGhlIHBsYXllciBmcm9tIHRoZSBiZWdpbm5pbmcgKG9yIG9mZnNldClcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcGxheWVyIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc2FtcGxlIHRvIHN0YXJ0IGF0LlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb24gaXMgZ2l2ZW4sXG4gICAgICogXHRcdFx0XHRcdGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgc3VwZXIucmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlZWsgdG8gYSBzcGVjaWZpYyB0aW1lIGluIHRoZSBwbGF5ZXIncyBidWZmZXIuIElmIHRoZVxuICAgICAqIHNvdXJjZSBpcyBubyBsb25nZXIgcGxheWluZyBhdCB0aGF0IHRpbWUsIGl0IHdpbGwgc3RvcC5cbiAgICAgKiBAcGFyYW0gb2Zmc2V0IFRoZSB0aW1lIHRvIHNlZWsgdG8uXG4gICAgICogQHBhcmFtIHdoZW4gVGhlIHRpbWUgZm9yIHRoZSBzZWVrIGV2ZW50IHRvIG9jY3VyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvZ3VyZ2xpbmdfdGhlcmVtaW5fMS5tcDNcIiwgKCkgPT4ge1xuICAgICAqIFx0cGxheWVyLnN0YXJ0KCk7XG4gICAgICogXHQvLyBzZWVrIHRvIHRoZSBvZmZzZXQgaW4gMSBzZWNvbmQgZnJvbSBub3dcbiAgICAgKiBcdHBsYXllci5zZWVrKDAuNCwgXCIrMVwiKTtcbiAgICAgKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICovXG4gICAgc2VlayhvZmZzZXQsIHdoZW4pIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHMod2hlbik7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRPZmZzZXQgPSB0aGlzLnRvU2Vjb25kcyhvZmZzZXQpO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBjdXJyZW50bHkgcGxheWluZywgc3RvcCBpdFxuICAgICAgICAgICAgdGhpcy5fc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgLy8gcmVzdGFydCBpdCBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAgICAgICAgdGhpcy5fc3RhcnQoY29tcHV0ZWRUaW1lLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgbG9vcCBzdGFydCBhbmQgZW5kLiBXaWxsIG9ubHkgbG9vcCBpZiBsb29wIGlzIHNldCB0byB0cnVlLlxuICAgICAqIEBwYXJhbSBsb29wU3RhcnQgVGhlIGxvb3Agc3RhcnQgdGltZVxuICAgICAqIEBwYXJhbSBsb29wRW5kIFRoZSBsb29wIGVuZCB0aW1lXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9tYWxldm9pY2VzX2FhMl9GMy5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIGxvb3AgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9pbnRzXG4gICAgICogcGxheWVyLnNldExvb3BQb2ludHMoMC4yLCAwLjMpO1xuICAgICAqIHBsYXllci5sb29wID0gdHJ1ZTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXRMb29wUG9pbnRzKGxvb3BTdGFydCwgbG9vcEVuZCkge1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IGxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBzdGFydCBhdCB0aGlzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wU3RhcnQ7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IGxvb3BTdGFydDtcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHMobG9vcFN0YXJ0KSwgMCwgdGhpcy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdldCB0aGUgY3VycmVudCBzb3VyY2VcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UubG9vcFN0YXJ0ID0gbG9vcFN0YXJ0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgbG9vcCBpcyB0cnVlLCB0aGUgbG9vcCB3aWxsIGVuZCBhdCB0aGlzIHBvc2l0aW9uLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQobG9vcEVuZCkge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHMobG9vcEVuZCksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZXQgdGhlIGN1cnJlbnQgc291cmNlXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGF1ZGlvIGJ1ZmZlciBiZWxvbmdpbmcgdG8gdGhlIHBsYXllci5cbiAgICAgKi9cbiAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyO1xuICAgIH1cbiAgICBzZXQgYnVmZmVyKGJ1ZmZlcikge1xuICAgICAgICB0aGlzLl9idWZmZXIuc2V0KGJ1ZmZlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgc2hvdWxkIGxvb3Agb25jZSBpdCdzIG92ZXIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vZHJ1bS1zYW1wbGVzL2JyZWFrYmVhdC5tcDNcIikudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBsYXllci5sb29wID0gdHJ1ZTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgLy8gaWYgbm8gY2hhbmdlLCBkbyBub3RoaW5nXG4gICAgICAgIGlmICh0aGlzLl9sb29wID09PSBsb29wKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9vcCA9IGxvb3A7XG4gICAgICAgIC8vIHNldCB0aGUgbG9vcCBvZiBhbGwgb2YgdGhlIHNvdXJjZXNcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UubG9vcCA9IGxvb3A7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAobG9vcCkge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBuZXh0IHN0b3BFdmVudFxuICAgICAgICAgICAgY29uc3Qgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TmV4dFN0YXRlKFwic3RvcHBlZFwiLCB0aGlzLm5vdygpKTtcbiAgICAgICAgICAgIGlmIChzdG9wRXZlbnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoc3RvcEV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE5vcm1hbCBzcGVlZCBpcyAxLiBUaGUgcGl0Y2ggd2lsbCBjaGFuZ2Ugd2l0aCB0aGUgcGxheWJhY2sgcmF0ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2ZlbWFsZXZvaWNlc19hYTJfQTUubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBwbGF5IGF0IDEvNCBzcGVlZFxuICAgICAqIHBsYXllci5wbGF5YmFja1JhdGUgPSAwLjI1O1xuICAgICAqIC8vIHBsYXkgYXMgc29vbiBhcyB0aGUgYnVmZmVyIGlzIGxvYWRlZFxuICAgICAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHN0b3AgZXZlbnQgc2luY2UgaXQncyBhdCBhIGRpZmZlcmVudCB0aW1lIG5vd1xuICAgICAgICBjb25zdCBzdG9wRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXROZXh0U3RhdGUoXCJzdG9wcGVkXCIsIG5vdyk7XG4gICAgICAgIGlmIChzdG9wRXZlbnQgJiYgc3RvcEV2ZW50LmltcGxpY2l0RW5kKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoc3RvcEV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2UuY2FuY2VsU3RvcCgpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgYWxsIHRoZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLnBsYXliYWNrUmF0ZS5zZXRWYWx1ZUF0VGltZShyYXRlLCBub3cpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBzaG91bGQgYmUgcmV2ZXJzZWRcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2NoaW1lXzEubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKiBwbGF5ZXIucmV2ZXJzZSA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IHJldmVyc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIucmV2ZXJzZTtcbiAgICB9XG4gICAgc2V0IHJldmVyc2UocmV2KSB7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5yZXZlcnNlID0gcmV2O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIGlzIGxvYWRlZFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIubG9hZGVkO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIC8vIGRpc2Nvbm5lY3QgYWxsIG9mIHRoZSBwbGF5ZXJzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBQbGF5ZXIucHJvdG90eXBlLCBcImZhZGVJblwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBQbGF5ZXIucHJvdG90eXBlLCBcImZhZGVPdXRcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsYXllci5qcy5tYXAiLCJpbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi4vLi4vY29tcG9uZW50L2NoYW5uZWwvVm9sdW1lXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXJzIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IG5vT3AsIHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IFBsYXllciB9IGZyb20gXCIuL1BsYXllclwiO1xuLyoqXG4gKiBQbGF5ZXJzIGNvbWJpbmVzIG11bHRpcGxlIFtbUGxheWVyXV0gb2JqZWN0cy5cbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFBsYXllcnMgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVycy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIl0sIFwidXJsc1wiKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGxheWVyc1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogUGxheWVycyBoYXMgbm8gaW5wdXQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNvbnRhaW5lciBvZiBhbGwgb2YgdGhlIHBsYXllcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3BsYXllcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQbGF5ZXJzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiXSwgXCJ1cmxzXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCB2b2x1bWUgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gbmV3IFRvbmVBdWRpb0J1ZmZlcnMoe1xuICAgICAgICAgICAgdXJsczogb3B0aW9ucy51cmxzLFxuICAgICAgICAgICAgb25sb2FkOiBvcHRpb25zLm9ubG9hZCxcbiAgICAgICAgICAgIGJhc2VVcmw6IG9wdGlvbnMuYmFzZVVybCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG9wdGlvbnMub25lcnJvclxuICAgICAgICB9KTtcbiAgICAgICAgLy8gbXV0ZSBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICB0aGlzLl9mYWRlSW4gPSBvcHRpb25zLmZhZGVJbjtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZVVybDogXCJcIixcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICB1cmxzOiB7fSxcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUgdGhlIG91dHB1dC5cbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVJbiB0aW1lIG9mIHRoZSBlbnZlbG9wZSBhcHBsaWVkIHRvIHRoZSBzb3VyY2UuXG4gICAgICovXG4gICAgZ2V0IGZhZGVJbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVJbjtcbiAgICB9XG4gICAgc2V0IGZhZGVJbihmYWRlSW4pIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gZmFkZUluO1xuICAgICAgICB0aGlzLl9wbGF5ZXJzLmZvckVhY2gocGxheWVyID0+IHtcbiAgICAgICAgICAgIHBsYXllci5mYWRlSW4gPSBmYWRlSW47XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBlYWNoIG9mIHRoZSBzb3VyY2VzLlxuICAgICAqL1xuICAgIGdldCBmYWRlT3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZU91dDtcbiAgICB9XG4gICAgc2V0IGZhZGVPdXQoZmFkZU91dCkge1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gZmFkZU91dDtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiB7XG4gICAgICAgICAgICBwbGF5ZXIuZmFkZU91dCA9IGZhZGVPdXQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3RhdGUgb2YgdGhlIHBsYXllcnMgb2JqZWN0LiBSZXR1cm5zIFwic3RhcnRlZFwiIGlmIGFueSBvZiB0aGUgcGxheWVycyBhcmUgcGxheWluZy5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIGNvbnN0IHBsYXlpbmcgPSBBcnJheS5mcm9tKHRoaXMuX3BsYXllcnMpLnNvbWUoKFtfLCBwbGF5ZXJdKSA9PiBwbGF5ZXIuc3RhdGUgPT09IFwic3RhcnRlZFwiKTtcbiAgICAgICAgcmV0dXJuIHBsYXlpbmcgPyBcInN0YXJ0ZWRcIiA6IFwic3RvcHBlZFwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcnVlIGlmIHRoZSBidWZmZXJzIG9iamVjdCBoYXMgYSBidWZmZXIgYnkgdGhhdCBuYW1lLlxuICAgICAqIEBwYXJhbSBuYW1lICBUaGUga2V5IG9yIGluZGV4IG9mIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuaGFzKG5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYSBwbGF5ZXIgYnkgbmFtZS5cbiAgICAgKiBAcGFyYW0gIG5hbWUgIFRoZSBwbGF5ZXJzIG5hbWUgYXMgZGVmaW5lZCBpbiB0aGUgY29uc3RydWN0b3Igb2JqZWN0IG9yIGBhZGRgIG1ldGhvZC5cbiAgICAgKi9cbiAgICBwbGF5ZXIobmFtZSkge1xuICAgICAgICBhc3NlcnQodGhpcy5oYXMobmFtZSksIGBObyBQbGF5ZXIgd2l0aCB0aGUgbmFtZSAke25hbWV9IGV4aXN0cyBvbiB0aGlzIG9iamVjdGApO1xuICAgICAgICBpZiAoIXRoaXMuX3BsYXllcnMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICBjb25zdCBwbGF5ZXIgPSBuZXcgUGxheWVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgZmFkZUluOiB0aGlzLl9mYWRlSW4sXG4gICAgICAgICAgICAgICAgZmFkZU91dDogdGhpcy5fZmFkZU91dCxcbiAgICAgICAgICAgICAgICB1cmw6IHRoaXMuX2J1ZmZlcnMuZ2V0KG5hbWUpLFxuICAgICAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICB0aGlzLl9wbGF5ZXJzLnNldChuYW1lLCBwbGF5ZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5ZXJzLmdldChuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgYWxsIHRoZSBidWZmZXJzIGFyZSBsb2FkZWQgb3Igbm90XG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMubG9hZGVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBwbGF5ZXIgYnkgbmFtZSBhbmQgdXJsIHRvIHRoZSBQbGF5ZXJzXG4gICAgICogQHBhcmFtICBuYW1lIEEgdW5pcXVlIG5hbWUgdG8gZ2l2ZSB0aGUgcGxheWVyXG4gICAgICogQHBhcmFtICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZlciBvciBhIGJ1ZmZlciB3aGljaCB3aWxsIGJlIGFkZGVkIHdpdGggdGhlIGdpdmVuIG5hbWUuXG4gICAgICogQHBhcmFtIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIHVybCBpcyBsb2FkZWQuXG4gICAgICovXG4gICAgYWRkKG5hbWUsIHVybCwgY2FsbGJhY2spIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9idWZmZXJzLmhhcyhuYW1lKSwgXCJBIGJ1ZmZlciB3aXRoIHRoYXQgbmFtZSBhbHJlYWR5IGV4aXN0cyBvbiB0aGlzIG9iamVjdFwiKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5hZGQobmFtZSwgdXJsLCBjYWxsYmFjayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIGFsbCBvZiB0aGUgcGxheWVycyBhdCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRvIHN0b3AgYWxsIG9mIHRoZSBwbGF5ZXJzLlxuICAgICAqL1xuICAgIHN0b3BBbGwodGltZSkge1xuICAgICAgICB0aGlzLl9wbGF5ZXJzLmZvckVhY2gocGxheWVyID0+IHBsYXllci5zdG9wKHRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wbGF5ZXJzLmZvckVhY2gocGxheWVyID0+IHBsYXllci5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGxheWVycy5qcy5tYXAiLCJpbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IENsb2NrIH0gZnJvbSBcIi4uLy4uL2NvcmUvY2xvY2svQ2xvY2tcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQnVmZmVyU291cmNlXCI7XG5pbXBvcnQgeyBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8gfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogR3JhaW5QbGF5ZXIgaW1wbGVtZW50cyBbZ3JhbnVsYXIgc3ludGhlc2lzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9HcmFudWxhcl9zeW50aGVzaXMpLlxuICogR3JhbnVsYXIgU3ludGhlc2lzIGVuYWJsZXMgeW91IHRvIGFkanVzdCBwaXRjaCBhbmQgcGxheWJhY2sgcmF0ZSBpbmRlcGVuZGVudGx5LiBUaGUgZ3JhaW5TaXplIGlzIHRoZVxuICogYW1vdW50IG9mIHRpbWUgZWFjaCBzbWFsbCBjaHVuayBvZiBhdWRpbyBpcyBwbGF5ZWQgZm9yIGFuZCB0aGUgb3ZlcmxhcCBpcyB0aGVcbiAqIGFtb3VudCBvZiBjcm9zc2ZhZGluZyB0cmFuc2l0aW9uIHRpbWUgYmV0d2VlbiBzdWNjZXNzaXZlIGdyYWlucy5cbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEdyYWluUGxheWVyIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JhaW5QbGF5ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHcmFpblBsYXllclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW50ZXJuYWwgbG9vcFN0YXJ0IHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSAwO1xuICAgICAgICAvKipcbiAgICAgICAgICogSW50ZXJuYWwgbG9vcFN0YXJ0IHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgY3VycmVudGx5IHBsYXlpbmcgQnVmZmVyU291cmNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JhaW5QbGF5ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pO1xuICAgICAgICB0aGlzLmJ1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIoe1xuICAgICAgICAgICAgb25sb2FkOiBvcHRpb25zLm9ubG9hZCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG9wdGlvbnMub25lcnJvcixcbiAgICAgICAgICAgIHJldmVyc2U6IG9wdGlvbnMucmV2ZXJzZSxcbiAgICAgICAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jayA9IG5ldyBDbG9jayh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fdGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAxIC8gb3B0aW9ucy5ncmFpblNpemVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLl9ncmFpblNpemUgPSBvcHRpb25zLmdyYWluU2l6ZTtcbiAgICAgICAgdGhpcy5fb3ZlcmxhcCA9IG9wdGlvbnMub3ZlcmxhcDtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBvcHRpb25zLmRldHVuZTtcbiAgICAgICAgLy8gc2V0dXBcbiAgICAgICAgdGhpcy5vdmVybGFwID0gb3B0aW9ucy5vdmVybGFwO1xuICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuZ3JhaW5TaXplID0gb3B0aW9ucy5ncmFpblNpemU7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5yZXZlcnNlID0gb3B0aW9ucy5yZXZlcnNlO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0b3BcIiwgdGhpcy5fb25zdG9wLmJpbmQodGhpcykpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb3ZlcmxhcDogMC4xLFxuICAgICAgICAgICAgZ3JhaW5TaXplOiAwLjIsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICByZXZlcnNlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgc3RhcnQgbWV0aG9kXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIDApO1xuICAgICAgICBvZmZzZXQgPSB0aGlzLnRvU2Vjb25kcyhvZmZzZXQpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGdyYWluU2l6ZSA9IDEgLyB0aGlzLl9jbG9jay5mcmVxdWVuY3kuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0YXJ0KHRpbWUsIG9mZnNldCAvIGdyYWluU2l6ZSk7XG4gICAgICAgIGlmIChkdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgYW5kIHRoZW4gcmVzdGFydCB0aGUgcGxheWVyIGZyb20gdGhlIGJlZ2lubmluZyAob3Igb2Zmc2V0KVxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBwbGF5ZXIgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzYW1wbGUgdG8gc3RhcnQgYXQuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgc2FtcGxlIHNob3VsZCBwbGF5LiBJZiBubyBkdXJhdGlvbiBpcyBnaXZlbixcbiAgICAgKiBcdFx0XHRcdFx0aXQgd2lsbCBkZWZhdWx0IHRvIHRoZSBmdWxsIGxlbmd0aCBvZiB0aGUgc2FtcGxlIChtaW51cyBhbnkgb2Zmc2V0KVxuICAgICAqL1xuICAgIHJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBzdXBlci5yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgc3RvcCBtZXRob2RcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0b3AodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZWQgd2hlbiB0aGUgY2xvY2sgaXMgc3RvcHBlZFxuICAgICAqL1xuICAgIF9vbnN0b3AodGltZSkge1xuICAgICAgICAvLyBzdG9wIHRoZSBwbGF5ZXJzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaCgoc291cmNlKSA9PiB7XG4gICAgICAgICAgICBzb3VyY2UuZmFkZU91dCA9IDA7XG4gICAgICAgICAgICBzb3VyY2Uuc3RvcCh0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub25zdG9wKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIG9uIGVhY2ggY2xvY2sgdGljay4gc2NoZWR1bGVkIGEgbmV3IGdyYWluIGF0IHRoaXMgdGltZS5cbiAgICAgKi9cbiAgICBfdGljayh0aW1lKSB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGl0IHNob3VsZCBzdG9wIGxvb3BpbmdcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGlja3MgKiB0aGlzLl9ncmFpblNpemU7XG4gICAgICAgIHRoaXMubG9nKFwib2Zmc2V0XCIsIG9mZnNldCk7XG4gICAgICAgIGlmICghdGhpcy5sb29wICYmIG9mZnNldCA+IHRoaXMuYnVmZmVyLmR1cmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AodGltZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZmlsZSwgdGhlIGZhZGUgaW4gc2hvdWxkIGJlIDBcbiAgICAgICAgY29uc3QgZmFkZUluID0gb2Zmc2V0IDwgdGhpcy5fb3ZlcmxhcCA/IDAgOiB0aGlzLl9vdmVybGFwO1xuICAgICAgICAvLyBjcmVhdGUgYSBidWZmZXIgc291cmNlXG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVybDogdGhpcy5idWZmZXIsXG4gICAgICAgICAgICBmYWRlSW46IGZhZGVJbixcbiAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX292ZXJsYXAsXG4gICAgICAgICAgICBsb29wOiB0aGlzLmxvb3AsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IHRoaXMuX2xvb3BTdGFydCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IHRoaXMuX2xvb3BFbmQsXG4gICAgICAgICAgICAvLyBjb21wdXRlIHRoZSBwbGF5YmFja1JhdGUgYmFzZWQgb24gdGhlIGRldHVuZVxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8odGhpcy5kZXR1bmUgLyAxMDApXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICBzb3VyY2Uuc3RhcnQodGltZSwgdGhpcy5fZ3JhaW5TaXplICogdGlja3MpO1xuICAgICAgICBzb3VyY2Uuc3RvcCh0aW1lICsgdGhpcy5fZ3JhaW5TaXplIC8gdGhpcy5wbGF5YmFja1JhdGUpO1xuICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGFjdGl2ZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgICAvLyByZW1vdmUgaXQgd2hlbiBpdCdzIGRvbmVcbiAgICAgICAgc291cmNlLm9uZW5kZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuaW5kZXhPZihzb3VyY2UpO1xuICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIHNhbXBsZVxuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICBhc3NlcnRSYW5nZShyYXRlLCAwLjAwMSk7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIHRoaXMuZ3JhaW5TaXplID0gdGhpcy5fZ3JhaW5TaXplO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcCBzdGFydCB0aW1lLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wU3RhcnQ7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQodGltZSkge1xuICAgICAgICBpZiAodGhpcy5idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgMCwgdGhpcy5idWZmZXIuZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcCBlbmQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHModGltZSksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkaXJlY3Rpb24gdGhlIGJ1ZmZlciBzaG91bGQgcGxheSBpblxuICAgICAqL1xuICAgIGdldCByZXZlcnNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIucmV2ZXJzZTtcbiAgICB9XG4gICAgc2V0IHJldmVyc2UocmV2KSB7XG4gICAgICAgIHRoaXMuYnVmZmVyLnJldmVyc2UgPSByZXY7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaXplIG9mIGVhY2ggY2h1bmsgb2YgYXVkaW8gdGhhdCB0aGVcbiAgICAgKiBidWZmZXIgaXMgY2hvcHBlZCBpbnRvIGFuZCBwbGF5ZWQgYmFjayBhdC5cbiAgICAgKi9cbiAgICBnZXQgZ3JhaW5TaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ3JhaW5TaXplO1xuICAgIH1cbiAgICBzZXQgZ3JhaW5TaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fZ3JhaW5TaXplID0gdGhpcy50b1NlY29uZHMoc2l6ZSk7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZSh0aGlzLl9wbGF5YmFja1JhdGUgLyB0aGlzLl9ncmFpblNpemUsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gb2YgdGhlIGNyb3NzLWZhZGUgYmV0d2VlbiBzdWNjZXNzaXZlIGdyYWlucy5cbiAgICAgKi9cbiAgICBnZXQgb3ZlcmxhcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX292ZXJsYXA7XG4gICAgfVxuICAgIHNldCBvdmVybGFwKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydFJhbmdlKGNvbXB1dGVkVGltZSwgMCk7XG4gICAgICAgIHRoaXMuX292ZXJsYXAgPSBjb21wdXRlZFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGFsbCB0aGUgYnVmZmVyIGlzIGxvYWRlZFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1ZmZlci5sb2FkZWQ7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jbG9jay5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaCgoc291cmNlKSA9PiBzb3VyY2UuZGlzcG9zZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R3JhaW5QbGF5ZXIuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vTm9pc2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1VzZXJNZWRpYVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0FNT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9GTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvUHVsc2VPc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0ZhdE9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvUFdNT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9Ub25lT3NjaWxsYXRvck5vZGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvTEZPXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL1BsYXllclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL1BsYXllcnNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9HcmFpblBsYXllclwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbi8qKlxuICogUmV0dXJuIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiBhbiBpbmNvbWluZyBzaWduYWwuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhYnMgPSBuZXcgVG9uZS5BYnMoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgxKTtcbiAqIFx0c2lnbmFsLnJhbXBUbygtMSwgMC41KTtcbiAqIFx0c2lnbmFsLmNvbm5lY3QoYWJzKTtcbiAqIH0sIDAuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBBYnMgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQWJzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hYnMgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB2YWwgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChNYXRoLmFicyh2YWwpIDwgMC4wMDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWF0aC5hYnModmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBBdWRpb1JhbmdlIGlucHV0IFstMSwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9hYnM7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IHJhbmdlIFswLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9hYnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hYnMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BYnMuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbi8qKlxuICogR2FpblRvQXVkaW8gY29udmVydHMgYW4gaW5wdXQgaW4gTm9ybWFsUmFuZ2UgWzAsMV0gdG8gQXVkaW9SYW5nZSBbLTEsMV0uXG4gKiBTZWUgW1tBdWRpb1RvR2Fpbl1dLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgR2FpblRvQXVkaW8gZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR2FpblRvQXVkaW9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBub2RlIHdoaWNoIGNvbnZlcnRzIHRoZSBhdWRpbyByYW5nZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX25vcm0gPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXBwaW5nOiB4ID0+IE1hdGguYWJzKHgpICogMiAtIDEsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIE5vcm1hbFJhbmdlIGlucHV0IFswLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX25vcm07XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBvdXRwdXQgWy0xLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9ub3JtO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbm9ybS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdhaW5Ub0F1ZGlvLmpzLm1hcCIsImltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4vTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogTmVnYXRlIHRoZSBpbmNvbWluZyBzaWduYWwuIGkuZS4gYW4gaW5wdXQgc2lnbmFsIG9mIDEwIHdpbGwgb3V0cHV0IC0xMFxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBuZWcgPSBuZXcgVG9uZS5OZWdhdGUoKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgtMikuY29ubmVjdChuZWcpO1xuICogLy8gb3V0cHV0IG9mIG5lZyBpcyBwb3NpdGl2ZSAyLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgTmVnYXRlIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk5lZ2F0ZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogbmVnYXRpb24gaXMgZG9uZSBieSBtdWx0aXBseWluZyBieSAtMVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbXVsdGlwbHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IC0xLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCBhbmQgb3V0cHV0IGFyZSBlcXVhbCB0byB0aGUgbXVsdGlwbHkgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX211bHRpcGx5O1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX211bHRpcGx5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqIEByZXR1cm5zIHtOZWdhdGV9IHRoaXNcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX211bHRpcGx5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TmVnYXRlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3RTZXJpZXMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTmVnYXRlIH0gZnJvbSBcIi4uL3NpZ25hbC9OZWdhdGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG4vKipcbiAqIFN1YnRyYWN0IHRoZSBzaWduYWwgY29ubmVjdGVkIHRvIHRoZSBpbnB1dCBpcyBzdWJ0cmFjdGVkIGZyb20gdGhlIHNpZ25hbCBjb25uZWN0ZWRcbiAqIFRoZSBzdWJ0cmFoZW5kLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBzdWJ0cmFjdCBhIHNjYWxhciBmcm9tIGEgc2lnbmFsXG4gKiBjb25zdCBzdWIgPSBuZXcgVG9uZS5TdWJ0cmFjdCgxKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCg0KS5jb25uZWN0KHN1Yik7XG4gKiAvLyB0aGUgb3V0cHV0IG9mIHN1YiBpcyAzLlxuICogQGV4YW1wbGVcbiAqIC8vIHN1YnRyYWN0IHR3byBzaWduYWxzXG4gKiBjb25zdCBzdWIgPSBuZXcgVG9uZS5TdWJ0cmFjdCgpO1xuICogY29uc3Qgc2lnQSA9IG5ldyBUb25lLlNpZ25hbCgxMCk7XG4gKiBjb25zdCBzaWdCID0gbmV3IFRvbmUuU2lnbmFsKDIuNSk7XG4gKiBzaWdBLmNvbm5lY3Qoc3ViKTtcbiAqIHNpZ0IuY29ubmVjdChzdWIuc3VidHJhaGVuZCk7XG4gKiAvLyBvdXRwdXQgb2Ygc3ViIGlzIDcuNVxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgU3VidHJhY3QgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN1YnRyYWN0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdWJ0cmFjdFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHN1bW1pbmcgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3VtID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9zdW07XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICAvKipcbiAgICAgICAgICogTmVnYXRlIHRoZSBpbnB1dCBvZiB0aGUgc2Vjb25kIGlucHV0IGJlZm9yZSBjb25uZWN0aW5nIGl0IHRvIHRoZSBzdW1taW5nIG5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZWcgPSBuZXcgTmVnYXRlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZhbHVlIHdoaWNoIGlzIHN1YnRyYWN0ZWQgZnJvbSB0aGUgbWFpbiBzaWduYWxcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuc3VidHJhaGVuZCA9IHRoaXMuX3BhcmFtO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuX2NvbnN0YW50U291cmNlLCB0aGlzLl9uZWcsIHRoaXMuX3N1bSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9uZWcuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdW0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdWJ0cmFjdC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIEdyZWF0ZXJUaGFuWmVybyBvdXRwdXRzIDEgd2hlbiB0aGUgaW5wdXQgaXMgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHplcm9cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZ3QwID0gbmV3IFRvbmUuR3JlYXRlclRoYW5aZXJvKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KGd0MCk7XG4gKiBcdHNpZy5zZXRWYWx1ZUF0VGltZSgtMSwgMC4wNSk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgR3JlYXRlclRoYW5aZXJvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyZWF0ZXJUaGFuWmVyby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR3JlYXRlclRoYW5aZXJvXCI7XG4gICAgICAgIHRoaXMuX3RocmVzaCA9IHRoaXMub3V0cHV0ID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbGVuZ3RoOiAxMjcsXG4gICAgICAgICAgICBtYXBwaW5nOiAodmFsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NjYWxlID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMTAwMDBcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3NjYWxlLmNvbm5lY3QodGhpcy5fdGhyZXNoKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RocmVzaC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdyZWF0ZXJUaGFuWmVyby5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4vU3VidHJhY3RcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuaW1wb3J0IHsgR3JlYXRlclRoYW5aZXJvIH0gZnJvbSBcIi4vR3JlYXRlclRoYW5aZXJvXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIE91dHB1dCAxIGlmIHRoZSBzaWduYWwgaXMgZ3JlYXRlciB0aGFuIHRoZSB2YWx1ZSwgb3RoZXJ3aXNlIG91dHB1dHMgMC5cbiAqIGNhbiBjb21wYXJlIHR3byBzaWduYWxzIG9yIGEgc2lnbmFsIGFuZCBhIG51bWJlci5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGd0ID0gbmV3IFRvbmUuR3JlYXRlclRoYW4oMikudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoNCkuY29ubmVjdChndCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgR3JlYXRlclRoYW4gZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyZWF0ZXJUaGFuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR3JlYXRlclRoYW5cIjtcbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR3JlYXRlclRoYW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX3N1YnRyYWN0ID0gdGhpcy5pbnB1dCA9IG5ldyBTdWJ0cmFjdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy52YWx1ZVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZ3R6ID0gdGhpcy5vdXRwdXQgPSBuZXcgR3JlYXRlclRoYW5aZXJvKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmNvbXBhcmF0b3IgPSB0aGlzLl9wYXJhbSA9IHRoaXMuX3N1YnRyYWN0LnN1YnRyYWhlbmQ7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiY29tcGFyYXRvclwiKTtcbiAgICAgICAgLy8gY29ubmVjdFxuICAgICAgICB0aGlzLl9zdWJ0cmFjdC5jb25uZWN0KHRoaXMuX2d0eik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ndHouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdWJ0cmFjdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29tcGFyYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdyZWF0ZXJUaGFuLmpzLm1hcCIsImltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogUG93IGFwcGxpZXMgYW4gZXhwb25lbnQgdG8gdGhlIGluY29taW5nIHNpZ25hbC4gVGhlIGluY29taW5nIHNpZ25hbCBtdXN0IGJlIEF1ZGlvUmFuZ2UgWy0xLCAxXVxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwb3cgPSBuZXcgVG9uZS5Qb3coMik7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHBvdyk7XG4gKiAvLyBvdXRwdXQgb2YgcG93IGlzIDAuMjUuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBQb3cgZXh0ZW5kcyBTaWduYWxPcGVyYXRvciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoUG93LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUG93XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQb3cuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50U2NhbGVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogdGhpcy5fZXhwRnVuYyhvcHRpb25zLnZhbHVlKSxcbiAgICAgICAgICAgIGxlbmd0aDogODE5MixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50ID0gb3B0aW9ucy52YWx1ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWxPcGVyYXRvci5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHRoZSBmdW5jdGlvbiB3aGljaCBtYXBzIHRoZSB3YXZlc2hhcGVyXG4gICAgICogQHBhcmFtIGV4cG9uZW50IGV4cG9uZW50IHZhbHVlXG4gICAgICovXG4gICAgX2V4cEZ1bmMoZXhwb25lbnQpIHtcbiAgICAgICAgcmV0dXJuICh2YWwpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLnBvdyhNYXRoLmFicyh2YWwpLCBleHBvbmVudCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB2YWx1ZSBvZiB0aGUgZXhwb25lbnQuXG4gICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwb25lbnQ7XG4gICAgfVxuICAgIHNldCB2YWx1ZShleHBvbmVudCkge1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IGV4cG9uZW50O1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlci5zZXRNYXAodGhpcy5fZXhwRnVuYyh0aGlzLl9leHBvbmVudCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50U2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UG93LmpzLm1hcCIsImltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4vU2NhbGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUG93IH0gZnJvbSBcIi4vUG93XCI7XG4vKipcbiAqIFBlcmZvcm1zIGFuIGV4cG9uZW50aWFsIHNjYWxpbmcgb24gYW4gaW5wdXQgc2lnbmFsLlxuICogU2NhbGVzIGEgTm9ybWFsUmFuZ2UgdmFsdWUgWzAsMV0gZXhwb25lbnRpYWxseVxuICogdG8gdGhlIG91dHB1dCByYW5nZSBvZiBvdXRwdXRNaW4gdG8gb3V0cHV0TWF4LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNjYWxlRXhwID0gbmV3IFRvbmUuU2NhbGVFeHAoMCwgMTAwLCAyKTtcbiAqIGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCgwLjUpLmNvbm5lY3Qoc2NhbGVFeHApO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgU2NhbGVFeHAgZXh0ZW5kcyBTY2FsZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGVFeHAuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIiwgXCJleHBvbmVudFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTY2FsZUV4cFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGVFeHAuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIiwgXCJleHBvbmVudFwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9leHAgPSBuZXcgUG93KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmV4cG9uZW50LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZXhwLmNvbm5lY3QodGhpcy5fbXVsdCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2NhbGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZXhwb25lbnQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnN0ZWFkIG9mIGludGVycG9sYXRpbmcgbGluZWFybHkgYmV0d2VlbiB0aGUgW1ttaW5dXSBhbmRcbiAgICAgKiBbW21heF1dIHZhbHVlcywgc2V0dGluZyB0aGUgZXhwb25lbnQgd2lsbCBpbnRlcnBvbGF0ZSBiZXR3ZWVuXG4gICAgICogdGhlIHR3byB2YWx1ZXMgd2l0aCBhbiBleHBvbmVudGlhbCBjdXJ2ZS5cbiAgICAgKi9cbiAgICBnZXQgZXhwb25lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9leHAudmFsdWU7XG4gICAgfVxuICAgIHNldCBleHBvbmVudChleHApIHtcbiAgICAgICAgdGhpcy5fZXhwLnZhbHVlID0gZXhwO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V4cC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNjYWxlRXhwLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IFRvbmVDb25zdGFudFNvdXJjZSB9IGZyb20gXCIuL1RvbmVDb25zdGFudFNvdXJjZVwiO1xuLyoqXG4gKiBBZGRzIHRoZSBhYmlsaXR5IHRvIHN5bmNocm9uaXplIHRoZSBzaWduYWwgdG8gdGhlIFtbVHJhbnNwb3J0XV1cbiAqL1xuZXhwb3J0IGNsYXNzIFN5bmNlZFNpZ25hbCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCIsIFwidW5pdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTeW5jZWRTaWduYWxcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERvbid0IG92ZXJyaWRlIHdoZW4gc29tZXRoaW5nIGlzIGNvbm5lY3RlZCB0byB0aGUgaW5wdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCIsIFwidW5pdHNcIl0pO1xuICAgICAgICB0aGlzLl9sYXN0VmFsID0gb3B0aW9ucy52YWx1ZTtcbiAgICAgICAgdGhpcy5fc3luY2VkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aGlzLl9vblRpY2suYmluZCh0aGlzKSwgXCIxaVwiKTtcbiAgICAgICAgdGhpcy5fc3luY2VkQ2FsbGJhY2sgPSB0aGlzLl9hbmNob3JWYWx1ZS5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwic3RvcFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIC8vIGRpc2Nvbm5lY3QgdGhlIGNvbnN0YW50IHNvdXJjZSBmcm9tIHRoZSBvdXRwdXQgYW5kIHJlcGxhY2UgaXQgd2l0aCBhbm90aGVyIG9uZVxuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLnN0b3AoMCk7XG4gICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBvbmVcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UgPSB0aGlzLm91dHB1dCA9IG5ldyBUb25lQ29uc3RhbnRTb3VyY2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb2Zmc2V0OiBvcHRpb25zLnZhbHVlLFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgIH0pLnN0YXJ0KDApO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKG9wdGlvbnMudmFsdWUsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayB3aGljaCBpcyBpbnZva2VkIGV2ZXJ5IHRpY2suXG4gICAgICovXG4gICAgX29uVGljayh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHN1cGVyLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgIC8vIGFwcHJveGltYXRlIHJhbXAgY3VydmVzIHdpdGggbGluZWFyIHJhbXBzXG4gICAgICAgIGlmICh0aGlzLl9sYXN0VmFsICE9PSB2YWwpIHtcbiAgICAgICAgICAgIHRoaXMuX2xhc3RWYWwgPSB2YWw7XG4gICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQuc2V0VmFsdWVBdFRpbWUodmFsLCB0aW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbmNob3IgdGhlIHZhbHVlIGF0IHRoZSBzdGFydCBhbmQgc3RvcCBvZiB0aGUgVHJhbnNwb3J0XG4gICAgICovXG4gICAgX2FuY2hvclZhbHVlKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdmFsID0gc3VwZXIuZ2V0VmFsdWVBdFRpbWUodGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgdGhpcy5fbGFzdFZhbCA9IHZhbDtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldC5zZXRWYWx1ZUF0VGltZSh2YWwsIHRpbWUpO1xuICAgIH1cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgcmV0dXJuIHN1cGVyLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgfVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuc2V0VmFsdWVBdFRpbWUodmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5zZXRUYXJnZXRBdFRpbWUodmFsdWUsIGNvbXB1dGVkVGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbFNjaGVkdWxlZFZhbHVlcyhzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICBzdXBlci5zZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgY29tcHV0ZWRUaW1lLCBkdXJhdGlvbiwgc2NhbGluZyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5jYW5jZWxBbmRIb2xkQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRSYW1wUG9pbnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnNldFJhbXBQb2ludChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIubGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIudGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcih0aGlzLl9zeW5jZWQpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RvcFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3luY2VkU2lnbmFsLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0FkZFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQWJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9BdWRpb1RvR2FpblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vR2FpblRvQXVkaW9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0dyZWF0ZXJUaGFuXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9HcmVhdGVyVGhhblplcm9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL011bHRpcGx5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9OZWdhdGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1Bvd1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2lnbmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TY2FsZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2NhbGVFeHBcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1N1YnRyYWN0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TeW5jZWRTaWduYWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1plcm9cIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciwgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc09iamVjdCwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgY29ubmVjdFNpZ25hbCwgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgcmFuZ2UsIHRpbWVSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIEVudmVsb3BlIGlzIGFuIFtBRFNSXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TeW50aGVzaXplciNBRFNSX2VudmVsb3BlKVxuICogZW52ZWxvcGUgZ2VuZXJhdG9yLiBFbnZlbG9wZSBvdXRwdXRzIGEgc2lnbmFsIHdoaWNoXG4gKiBjYW4gYmUgY29ubmVjdGVkIHRvIGFuIEF1ZGlvUGFyYW0gb3IgVG9uZS5TaWduYWwuXG4gKiBgYGBcbiAqICAgICAgICAgICAvXFxcbiAqICAgICAgICAgIC8gIFxcXG4gKiAgICAgICAgIC8gICAgXFxcbiAqICAgICAgICAvICAgICAgXFxcbiAqICAgICAgIC8gICAgICAgIFxcX19fX19fX19fX19cbiAqICAgICAgLyAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgICAgLyAgICAgICAgICAgICAgICAgICAgICAgXFxcbiAqICAgIC8gICAgICAgICAgICAgICAgICAgICAgICAgXFxcbiAqICAgLyAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoe1xuICogXHRcdGF0dGFjazogMC4xLFxuICogXHRcdGRlY2F5OiAwLjIsXG4gKiBcdFx0c3VzdGFpbjogMC41LFxuICogXHRcdHJlbGVhc2U6IDAuOCxcbiAqIFx0fSkudG9EZXN0aW5hdGlvbigpO1xuICogXHRlbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoMC41KTtcbiAqIH0sIDEuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBFbnZlbG9wZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFbnZlbG9wZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIHNpZ25hbCB3aGljaCBpcyBvdXRwdXQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zaWcgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgc2lnbmFsIG9mIHRoZSBlbnZlbG9wZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9zaWc7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbnZlbG9wZSBoYXMgbm8gaW5wdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG9wdGlvbnMuYXR0YWNrO1xuICAgICAgICB0aGlzLmRlY2F5ID0gb3B0aW9ucy5kZWNheTtcbiAgICAgICAgdGhpcy5zdXN0YWluID0gb3B0aW9ucy5zdXN0YWluO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBvcHRpb25zLnJlbGVhc2U7XG4gICAgICAgIHRoaXMuYXR0YWNrQ3VydmUgPSBvcHRpb25zLmF0dGFja0N1cnZlO1xuICAgICAgICB0aGlzLnJlbGVhc2VDdXJ2ZSA9IG9wdGlvbnMucmVsZWFzZUN1cnZlO1xuICAgICAgICB0aGlzLmRlY2F5Q3VydmUgPSBvcHRpb25zLmRlY2F5Q3VydmU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICBhdHRhY2tDdXJ2ZTogXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGRlY2F5OiAwLjEsXG4gICAgICAgICAgICBkZWNheUN1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICByZWxlYXNlOiAxLFxuICAgICAgICAgICAgcmVsZWFzZUN1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICBzdXN0YWluOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBlbnZlbG9wZS4gVXNlZnVsIGZvclxuICAgICAqIHN5bmNocm9uaXppbmcgdmlzdWFsIG91dHB1dCB0byB0aGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJ2ZVxuICAgICAqIEBwYXJhbSAgY3VydmVcbiAgICAgKiBAcGFyYW0gIGRpcmVjdGlvbiAgSW4vT3V0XG4gICAgICogQHJldHVybiBUaGUgY3VydmUgbmFtZVxuICAgICAqL1xuICAgIF9nZXRDdXJ2ZShjdXJ2ZSwgZGlyZWN0aW9uKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyhjdXJ2ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIGN1cnZlcyBhcnJheVxuICAgICAgICAgICAgbGV0IGN1cnZlTmFtZTtcbiAgICAgICAgICAgIGZvciAoY3VydmVOYW1lIGluIEVudmVsb3BlQ3VydmVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKEVudmVsb3BlQ3VydmVzW2N1cnZlTmFtZV1bZGlyZWN0aW9uXSA9PT0gY3VydmUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnZlTmFtZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyByZXR1cm4gdGhlIGN1c3RvbSBjdXJ2ZVxuICAgICAgICAgICAgcmV0dXJuIGN1cnZlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzc2lnbiBhIHRoZSBjdXJ2ZSB0byB0aGUgZ2l2ZW4gbmFtZSB1c2luZyB0aGUgZGlyZWN0aW9uXG4gICAgICogQHBhcmFtICBuYW1lXG4gICAgICogQHBhcmFtICBkaXJlY3Rpb24gSW4vT3V0XG4gICAgICogQHBhcmFtICBjdXJ2ZVxuICAgICAqL1xuICAgIF9zZXRDdXJ2ZShuYW1lLCBkaXJlY3Rpb24sIGN1cnZlKSB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGl0J3MgYSB2YWxpZCB0eXBlXG4gICAgICAgIGlmIChpc1N0cmluZyhjdXJ2ZSkgJiYgUmVmbGVjdC5oYXMoRW52ZWxvcGVDdXJ2ZXMsIGN1cnZlKSkge1xuICAgICAgICAgICAgY29uc3QgY3VydmVEZWYgPSBFbnZlbG9wZUN1cnZlc1tjdXJ2ZV07XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoY3VydmVEZWYpKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5hbWUgIT09IFwiX2RlY2F5Q3VydmVcIikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzW25hbWVdID0gY3VydmVEZWZbZGlyZWN0aW9uXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzW25hbWVdID0gY3VydmVEZWY7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNBcnJheShjdXJ2ZSkgJiYgbmFtZSAhPT0gXCJfZGVjYXlDdXJ2ZVwiKSB7XG4gICAgICAgICAgICB0aGlzW25hbWVdID0gY3VydmU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJFbnZlbG9wZTogaW52YWxpZCBjdXJ2ZTogXCIgKyBjdXJ2ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNoYXBlIG9mIHRoZSBhdHRhY2suXG4gICAgICogQ2FuIGJlIGFueSBvZiB0aGVzZSBzdHJpbmdzOlxuICAgICAqICogXCJsaW5lYXJcIlxuICAgICAqICogXCJleHBvbmVudGlhbFwiXG4gICAgICogKiBcInNpbmVcIlxuICAgICAqICogXCJjb3NpbmVcIlxuICAgICAqICogXCJib3VuY2VcIlxuICAgICAqICogXCJyaXBwbGVcIlxuICAgICAqICogXCJzdGVwXCJcbiAgICAgKlxuICAgICAqIENhbiBhbHNvIGJlIGFuIGFycmF5IHdoaWNoIGRlc2NyaWJlcyB0aGUgY3VydmUuIFZhbHVlc1xuICAgICAqIGluIHRoZSBhcnJheSBhcmUgZXZlbmx5IHN1YmRpdmlkZWQgYW5kIGxpbmVhcmx5XG4gICAgICogaW50ZXJwb2xhdGVkIG92ZXIgdGhlIGR1cmF0aW9uIG9mIHRoZSBhdHRhY2suXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKDAuNCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIFx0ZW52LmF0dGFja0N1cnZlID0gXCJsaW5lYXJcIjtcbiAgICAgKiBcdGVudi50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICogfSwgMSwgMSk7XG4gICAgICovXG4gICAgZ2V0IGF0dGFja0N1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q3VydmUodGhpcy5fYXR0YWNrQ3VydmUsIFwiSW5cIik7XG4gICAgfVxuICAgIHNldCBhdHRhY2tDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICB0aGlzLl9zZXRDdXJ2ZShcIl9hdHRhY2tDdXJ2ZVwiLCBcIkluXCIsIGN1cnZlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNoYXBlIG9mIHRoZSByZWxlYXNlLiBTZWUgdGhlIGF0dGFjayBjdXJ2ZSB0eXBlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICAgICAqIFx0Y29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoe1xuICAgICAqIFx0XHRyZWxlYXNlOiAwLjhcbiAgICAgKiBcdH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBcdGVudi50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICogXHQvLyByZWxlYXNlIGN1cnZlIGNvdWxkIGFsc28gYmUgZGVmaW5lZCBieSBhbiBhcnJheVxuICAgICAqIFx0ZW52LnJlbGVhc2VDdXJ2ZSA9IFsxLCAwLjMsIDAuNCwgMC4yLCAwLjcsIDBdO1xuICAgICAqIFx0ZW52LnRyaWdnZXJSZWxlYXNlKDAuMik7XG4gICAgICogfSwgMSwgMSk7XG4gICAgICovXG4gICAgZ2V0IHJlbGVhc2VDdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnZlKHRoaXMuX3JlbGVhc2VDdXJ2ZSwgXCJPdXRcIik7XG4gICAgfVxuICAgIHNldCByZWxlYXNlQ3VydmUoY3VydmUpIHtcbiAgICAgICAgdGhpcy5fc2V0Q3VydmUoXCJfcmVsZWFzZUN1cnZlXCIsIFwiT3V0XCIsIGN1cnZlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNoYXBlIG9mIHRoZSBkZWNheSBlaXRoZXIgXCJsaW5lYXJcIiBvciBcImV4cG9uZW50aWFsXCJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICAgICAqIFx0Y29uc3QgZW52ID0gbmV3IFRvbmUuRW52ZWxvcGUoe1xuICAgICAqIFx0XHRzdXN0YWluOiAwLjEsXG4gICAgICogXHRcdGRlY2F5OiAwLjVcbiAgICAgKiBcdH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBcdGVudi5kZWNheUN1cnZlID0gXCJsaW5lYXJcIjtcbiAgICAgKiBcdGVudi50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICogfSwgMSwgMSk7XG4gICAgICovXG4gICAgZ2V0IGRlY2F5Q3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNheUN1cnZlO1xuICAgIH1cbiAgICBzZXQgZGVjYXlDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICBhc3NlcnQoW1wibGluZWFyXCIsIFwiZXhwb25lbnRpYWxcIl0uc29tZShjID0+IGMgPT09IGN1cnZlKSwgYEludmFsaWQgZW52ZWxvcGUgY3VydmU6ICR7Y3VydmV9YCk7XG4gICAgICAgIHRoaXMuX2RlY2F5Q3VydmUgPSBjdXJ2ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrL2RlY2F5IHBvcnRpb24gb2YgdGhlIEFEU1IgZW52ZWxvcGUuXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIGF0dGFjayBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgZW52ZWxvcGUgc2NhbGVzIHRoZSB2YWxlcy5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyIGJldHdlZW4gMC0xXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChlbnYpLnN0YXJ0KCk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgYXR0YWNrIDAuNSBzZWNvbmRzIGZyb20gbm93IHdpdGggYSB2ZWxvY2l0eSBvZiAwLjJcbiAgICAgKiBlbnYudHJpZ2dlckF0dGFjayhcIiswLjVcIiwgMC4yKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsQXR0YWNrID0gdGhpcy50b1NlY29uZHModGhpcy5hdHRhY2spO1xuICAgICAgICBsZXQgYXR0YWNrID0gb3JpZ2luYWxBdHRhY2s7XG4gICAgICAgIGNvbnN0IGRlY2F5ID0gdGhpcy50b1NlY29uZHModGhpcy5kZWNheSk7XG4gICAgICAgIC8vIGNoZWNrIGlmIGl0J3Mgbm90IGEgY29tcGxldGUgYXR0YWNrXG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPiAwKSB7XG4gICAgICAgICAgICAvLyBzdWJ0cmFjdCB0aGUgY3VycmVudCB2YWx1ZSBmcm9tIHRoZSBhdHRhY2sgdGltZVxuICAgICAgICAgICAgY29uc3QgYXR0YWNrUmF0ZSA9IDEgLyBhdHRhY2s7XG4gICAgICAgICAgICBjb25zdCByZW1haW5pbmdEaXN0YW5jZSA9IDEgLSBjdXJyZW50VmFsdWU7XG4gICAgICAgICAgICAvLyB0aGUgYXR0YWNrIGlzIG5vdyB0aGUgcmVtYWluaW5nIHRpbWVcbiAgICAgICAgICAgIGF0dGFjayA9IHJlbWFpbmluZ0Rpc3RhbmNlIC8gYXR0YWNrUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBhdHRhY2tcbiAgICAgICAgaWYgKGF0dGFjayA8IHRoaXMuc2FtcGxlVGltZSkge1xuICAgICAgICAgICAgdGhpcy5fc2lnLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgICAgIC8vIGNhc2Ugd2hlcmUgdGhlIGF0dGFjayB0aW1lIGlzIDAgc2hvdWxkIHNldCBpbnN0YW50bHlcbiAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUF0VGltZSh2ZWxvY2l0eSwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fYXR0YWNrQ3VydmUgPT09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy5saW5lYXJSYW1wVG8odmVsb2NpdHksIGF0dGFjaywgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fYXR0YWNrQ3VydmUgPT09IFwiZXhwb25lbnRpYWxcIikge1xuICAgICAgICAgICAgdGhpcy5fc2lnLnRhcmdldFJhbXBUbyh2ZWxvY2l0eSwgYXR0YWNrLCB0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICAgICAgbGV0IGN1cnZlID0gdGhpcy5fYXR0YWNrQ3VydmU7XG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgY3VydmVcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgY3VydmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAvLyB0aGUgc3RhcnRpbmcgaW5kZXggaXMgYmV0d2VlbiB0aGUgdHdvIHZhbHVlc1xuICAgICAgICAgICAgICAgIGlmIChjdXJ2ZVtpIC0gMV0gPD0gY3VycmVudFZhbHVlICYmIGN1cnJlbnRWYWx1ZSA8PSBjdXJ2ZVtpXSkge1xuICAgICAgICAgICAgICAgICAgICBjdXJ2ZSA9IHRoaXMuX2F0dGFja0N1cnZlLnNsaWNlKGkpO1xuICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZmlyc3QgaW5kZXggaXMgdGhlIGN1cnJlbnQgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgY3VydmVbMF0gPSBjdXJyZW50VmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUN1cnZlQXRUaW1lKGN1cnZlLCB0aW1lLCBhdHRhY2ssIHZlbG9jaXR5KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBkZWNheVxuICAgICAgICBpZiAoZGVjYXkgJiYgdGhpcy5zdXN0YWluIDwgMSkge1xuICAgICAgICAgICAgY29uc3QgZGVjYXlWYWx1ZSA9IHZlbG9jaXR5ICogdGhpcy5zdXN0YWluO1xuICAgICAgICAgICAgY29uc3QgZGVjYXlTdGFydCA9IHRpbWUgKyBhdHRhY2s7XG4gICAgICAgICAgICB0aGlzLmxvZyhcImRlY2F5XCIsIGRlY2F5U3RhcnQpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RlY2F5Q3VydmUgPT09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoZGVjYXlWYWx1ZSwgZGVjYXkgKyBkZWNheVN0YXJ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoZGVjYXlWYWx1ZSwgZGVjYXlTdGFydCwgZGVjYXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyB0aGUgcmVsZWFzZSBvZiB0aGUgZW52ZWxvcGUuXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGUgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcih7XG4gICAgICogXHR0eXBlOiBcInNhd3Rvb3RoXCJcbiAgICAgKiB9KS5jb25uZWN0KGVudikuc3RhcnQoKTtcbiAgICAgKiBlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2UgaGFsZiBhIHNlY29uZCBhZnRlciB0aGUgYXR0YWNrXG4gICAgICogZW52LnRyaWdnZXJSZWxlYXNlKFwiKzAuNVwiKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlclJlbGVhc2VcIiwgdGltZSk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKGN1cnJlbnRWYWx1ZSA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbGVhc2UgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLnJlbGVhc2UpO1xuICAgICAgICAgICAgaWYgKHJlbGVhc2UgPCB0aGlzLnNhbXBsZVRpbWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9yZWxlYXNlQ3VydmUgPT09IFwibGluZWFyXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcubGluZWFyUmFtcFRvKDAsIHJlbGVhc2UsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fcmVsZWFzZUN1cnZlID09PSBcImV4cG9uZW50aWFsXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcudGFyZ2V0UmFtcFRvKDAsIHJlbGVhc2UsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkodGhpcy5fcmVsZWFzZUN1cnZlKSwgXCJyZWxlYXNlQ3VydmUgbXVzdCBiZSBlaXRoZXIgJ2xpbmVhcicsICdleHBvbmVudGlhbCcgb3IgYW4gYXJyYXlcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQ3VydmVBdFRpbWUodGhpcy5fcmVsZWFzZUN1cnZlLCB0aW1lLCByZWxlYXNlLCBjdXJyZW50VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHNjaGVkdWxlZCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS4gVGhpcyB3aWxsXG4gICAgICogcmV0dXJuIHRoZSB1bmNvbnZlcnRlZCAocmF3KSB2YWx1ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKDAuNSwgMSwgMC40LCAyKTtcbiAgICAgKiBlbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoMik7XG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2coZW52LmdldFZhbHVlQXRUaW1lKFRvbmUubm93KCkpKSwgMTAwKTtcbiAgICAgKi9cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaWcuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHRyaWdnZXJBdHRhY2tSZWxlYXNlIGlzIHNob3J0aGFuZCBmb3IgdHJpZ2dlckF0dGFjaywgdGhlbiB3YWl0aW5nXG4gICAgICogc29tZSBkdXJhdGlvbiwgdGhlbiB0cmlnZ2VyUmVsZWFzZS5cbiAgICAgKiBAcGFyYW0gZHVyYXRpb24gVGhlIGR1cmF0aW9uIG9mIHRoZSBzdXN0YWluLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdGhlIGF0dGFjayBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIGVudmVsb3BlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoZW52KS5zdGFydCgpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2UgMC41IHNlY29uZHMgYWZ0ZXIgdGhlIGF0dGFja1xuICAgICAqIGVudi50cmlnZ2VyQXR0YWNrUmVsZWFzZSgwLjUpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VscyBhbGwgc2NoZWR1bGVkIGVudmVsb3BlIGNoYW5nZXMgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIHRoaXMuX3NpZy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGhpcy50b1NlY29uZHMoYWZ0ZXIpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIGVudmVsb3BlIHRvIGEgZGVzdGluYXRpb24gbm9kZS5cbiAgICAgKi9cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW1iZXIgPSAwLCBpbnB1dE51bWJlciA9IDApIHtcbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtYmVyLCBpbnB1dE51bWJlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgdGhlIGVudmVsb3BlIGN1cnZlIHRvIGFuIGFycmF5IG9mIHRoZSBnaXZlbiBsZW5ndGguXG4gICAgICogR29vZCBmb3IgdmlzdWFsaXppbmcgdGhlIGVudmVsb3BlIGN1cnZlLiBSZXNjYWxlcyB0aGUgZHVyYXRpb24gb2YgdGhlXG4gICAgICogZW52ZWxvcGUgdG8gZml0IHRoZSBsZW5ndGguXG4gICAgICovXG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IGxlbmd0aCAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dCgxLCBkdXJhdGlvbiwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgLy8gbm9ybWFsaXplIHRoZSBBRFNSIGZvciB0aGUgZ2l2ZW4gZHVyYXRpb24gd2l0aCAyMCUgc3VzdGFpbiB0aW1lXG4gICAgICAgICAgICBjb25zdCBhdHRhY2tQb3J0aW9uID0gdGhpcy50b1NlY29uZHModGhpcy5hdHRhY2spICsgdGhpcy50b1NlY29uZHModGhpcy5kZWNheSk7XG4gICAgICAgICAgICBjb25zdCBlbnZlbG9wZUR1cmF0aW9uID0gYXR0YWNrUG9ydGlvbiArIHRoaXMudG9TZWNvbmRzKHRoaXMucmVsZWFzZSk7XG4gICAgICAgICAgICBjb25zdCBzdXN0YWluVGltZSA9IGVudmVsb3BlRHVyYXRpb24gKiAwLjE7XG4gICAgICAgICAgICBjb25zdCB0b3RhbER1cmF0aW9uID0gZW52ZWxvcGVEdXJhdGlvbiArIHN1c3RhaW5UaW1lO1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgY2xvbmUgPSBuZXcgdGhpcy5jb25zdHJ1Y3RvcihPYmplY3QuYXNzaWduKHRoaXMuZ2V0KCksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5hdHRhY2spIC8gdG90YWxEdXJhdGlvbixcbiAgICAgICAgICAgICAgICBkZWNheTogZHVyYXRpb24gKiB0aGlzLnRvU2Vjb25kcyh0aGlzLmRlY2F5KSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogZHVyYXRpb24gKiB0aGlzLnRvU2Vjb25kcyh0aGlzLnJlbGVhc2UpIC8gdG90YWxEdXJhdGlvbixcbiAgICAgICAgICAgICAgICBjb250ZXh0XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBjbG9uZS5fc2lnLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgICAgIGNsb25lLnRyaWdnZXJBdHRhY2tSZWxlYXNlKGR1cmF0aW9uICogKGF0dGFja1BvcnRpb24gKyBzdXN0YWluVGltZSkgLyB0b3RhbER1cmF0aW9uLCAwKTtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgICAgICByZXR1cm4gYnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWcuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJhdHRhY2tcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgRW52ZWxvcGUucHJvdG90eXBlLCBcImRlY2F5XCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICByYW5nZSgwLCAxKVxuXSwgRW52ZWxvcGUucHJvdG90eXBlLCBcInN1c3RhaW5cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgRW52ZWxvcGUucHJvdG90eXBlLCBcInJlbGVhc2VcIiwgdm9pZCAwKTtcbi8qKlxuICogR2VuZXJhdGUgc29tZSBjb21wbGV4IGVudmVsb3BlIGN1cnZlcy5cbiAqL1xuY29uc3QgRW52ZWxvcGVDdXJ2ZXMgPSAoKCkgPT4ge1xuICAgIGNvbnN0IGN1cnZlTGVuID0gMTI4O1xuICAgIGxldCBpO1xuICAgIGxldCBrO1xuICAgIC8vIGNvc2luZSBjdXJ2ZVxuICAgIGNvbnN0IGNvc2luZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgY29zaW5lQ3VydmVbaV0gPSBNYXRoLnNpbigoaSAvIChjdXJ2ZUxlbiAtIDEpKSAqIChNYXRoLlBJIC8gMikpO1xuICAgIH1cbiAgICAvLyByaXBwbGUgY3VydmVcbiAgICBjb25zdCByaXBwbGVDdXJ2ZSA9IFtdO1xuICAgIGNvbnN0IHJpcHBsZUN1cnZlRnJlcSA9IDYuNDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW4gLSAxOyBpKyspIHtcbiAgICAgICAgayA9IChpIC8gKGN1cnZlTGVuIC0gMSkpO1xuICAgICAgICBjb25zdCBzaW5lV2F2ZSA9IE1hdGguc2luKGsgKiAoTWF0aC5QSSAqIDIpICogcmlwcGxlQ3VydmVGcmVxIC0gTWF0aC5QSSAvIDIpICsgMTtcbiAgICAgICAgcmlwcGxlQ3VydmVbaV0gPSBzaW5lV2F2ZSAvIDEwICsgayAqIDAuODM7XG4gICAgfVxuICAgIHJpcHBsZUN1cnZlW2N1cnZlTGVuIC0gMV0gPSAxO1xuICAgIC8vIHN0YWlycyBjdXJ2ZVxuICAgIGNvbnN0IHN0YWlyc0N1cnZlID0gW107XG4gICAgY29uc3Qgc3RlcHMgPSA1O1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIHN0YWlyc0N1cnZlW2ldID0gTWF0aC5jZWlsKChpIC8gKGN1cnZlTGVuIC0gMSkpICogc3RlcHMpIC8gc3RlcHM7XG4gICAgfVxuICAgIC8vIGluLW91dCBlYXNpbmcgY3VydmVcbiAgICBjb25zdCBzaW5lQ3VydmUgPSBbXTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBrID0gaSAvIChjdXJ2ZUxlbiAtIDEpO1xuICAgICAgICBzaW5lQ3VydmVbaV0gPSAwLjUgKiAoMSAtIE1hdGguY29zKE1hdGguUEkgKiBrKSk7XG4gICAgfVxuICAgIC8vIGEgYm91bmNlIGN1cnZlXG4gICAgY29uc3QgYm91bmNlQ3VydmUgPSBbXTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBrID0gaSAvIChjdXJ2ZUxlbiAtIDEpO1xuICAgICAgICBjb25zdCBmcmVxID0gTWF0aC5wb3coaywgMykgKiA0ICsgMC4yO1xuICAgICAgICBjb25zdCB2YWwgPSBNYXRoLmNvcyhmcmVxICogTWF0aC5QSSAqIDIgKiBrKTtcbiAgICAgICAgYm91bmNlQ3VydmVbaV0gPSBNYXRoLmFicyh2YWwgKiAoMSAtIGspKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52ZXJ0IGEgdmFsdWUgY3VydmUgdG8gbWFrZSBpdCB3b3JrIGZvciB0aGUgcmVsZWFzZVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGludmVydEN1cnZlKGN1cnZlKSB7XG4gICAgICAgIGNvbnN0IG91dCA9IG5ldyBBcnJheShjdXJ2ZS5sZW5ndGgpO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGN1cnZlLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBvdXRbal0gPSAxIC0gY3VydmVbal07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG91dDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogcmV2ZXJzZSB0aGUgY3VydmVcbiAgICAgKi9cbiAgICBmdW5jdGlvbiByZXZlcnNlQ3VydmUoY3VydmUpIHtcbiAgICAgICAgcmV0dXJuIGN1cnZlLnNsaWNlKDApLnJldmVyc2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogYXR0YWNrIGFuZCByZWxlYXNlIGN1cnZlIGFycmF5c1xuICAgICAqL1xuICAgIHJldHVybiB7XG4gICAgICAgIGJvdW5jZToge1xuICAgICAgICAgICAgSW46IGludmVydEN1cnZlKGJvdW5jZUN1cnZlKSxcbiAgICAgICAgICAgIE91dDogYm91bmNlQ3VydmUsXG4gICAgICAgIH0sXG4gICAgICAgIGNvc2luZToge1xuICAgICAgICAgICAgSW46IGNvc2luZUN1cnZlLFxuICAgICAgICAgICAgT3V0OiByZXZlcnNlQ3VydmUoY29zaW5lQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBleHBvbmVudGlhbDogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICBsaW5lYXI6IFwibGluZWFyXCIsXG4gICAgICAgIHJpcHBsZToge1xuICAgICAgICAgICAgSW46IHJpcHBsZUN1cnZlLFxuICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShyaXBwbGVDdXJ2ZSksXG4gICAgICAgIH0sXG4gICAgICAgIHNpbmU6IHtcbiAgICAgICAgICAgIEluOiBzaW5lQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IGludmVydEN1cnZlKHNpbmVDdXJ2ZSksXG4gICAgICAgIH0sXG4gICAgICAgIHN0ZXA6IHtcbiAgICAgICAgICAgIEluOiBzdGFpcnNDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUoc3RhaXJzQ3VydmUpLFxuICAgICAgICB9LFxuICAgIH07XG59KSgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RW52ZWxvcGUuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEJhc2UtY2xhc3MgZm9yIGFsbCBpbnN0cnVtZW50c1xuICovXG5leHBvcnQgY2xhc3MgSW5zdHJ1bWVudCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiBhbGwgZXZlbnRzIHNjaGVkdWxlZCB0byB0aGUgdHJhbnNwb3J0XG4gICAgICAgICAqIHdoZW4gdGhlIGluc3RydW1lbnQgaXMgJ3N5bmNlZCdcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgdGhlIGluc3RydW1lbnQgaXMgY3VycmVudGx5IHN5bmNlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuX29yaWdpbmFsX3RyaWdnZXJBdHRhY2sgPSB0aGlzLnRyaWdnZXJBdHRhY2s7XG4gICAgICAgIHRoaXMuX29yaWdpbmFsX3RyaWdnZXJSZWxlYXNlID0gdGhpcy50cmlnZ2VyUmVsZWFzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgaW5zdHJ1bWVudCB0byB0aGUgVHJhbnNwb3J0LiBBbGwgc3Vic2VxdWVudCBjYWxscyBvZlxuICAgICAqIFtbdHJpZ2dlckF0dGFja11dIGFuZCBbW3RyaWdnZXJSZWxlYXNlXV0gd2lsbCBiZSBzY2hlZHVsZWQgYWxvbmcgdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZtU3ludGggPSBuZXcgVG9uZS5GTVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGZtU3ludGgudm9sdW1lLnZhbHVlID0gLTY7XG4gICAgICogZm1TeW50aC5zeW5jKCk7XG4gICAgICogLy8gc2NoZWR1bGUgMyBub3RlcyB3aGVuIHRoZSB0cmFuc3BvcnQgZmlyc3Qgc3RhcnRzXG4gICAgICogZm1TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIiwgMCk7XG4gICAgICogZm1TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkU0XCIsIFwiOG5cIiwgXCI4blwiKTtcbiAgICAgKiBmbVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiRzRcIiwgXCI4blwiLCBcIjRuXCIpO1xuICAgICAqIC8vIHN0YXJ0IHRoZSB0cmFuc3BvcnQgdG8gaGVhciB0aGUgbm90ZXNcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jU3RhdGUoKSkge1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJBdHRhY2tcIiwgMSk7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlclJlbGVhc2VcIiwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHNldCBfc3luY1xuICAgICAqL1xuICAgIF9zeW5jU3RhdGUoKSB7XG4gICAgICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGlmICghdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoYW5nZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdyYXAgdGhlIGdpdmVuIG1ldGhvZCBzbyB0aGF0IGl0IGNhbiBiZSBzeW5jaHJvbml6ZWRcbiAgICAgKiBAcGFyYW0gbWV0aG9kIFdoaWNoIG1ldGhvZCB0byB3cmFwIGFuZCBzeW5jXG4gICAgICogQHBhcmFtICB0aW1lUG9zaXRpb24gV2hhdCBwb3NpdGlvbiB0aGUgdGltZSBhcmd1bWVudCBhcHBlYXJzIGluXG4gICAgICovXG4gICAgX3N5bmNNZXRob2QobWV0aG9kLCB0aW1lUG9zaXRpb24pIHtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSB0aGlzW1wiX29yaWdpbmFsX1wiICsgbWV0aG9kXSA9IHRoaXNbbWV0aG9kXTtcbiAgICAgICAgdGhpc1ttZXRob2RdID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRpbWUgPSBhcmdzW3RpbWVQb3NpdGlvbl07XG4gICAgICAgICAgICBjb25zdCBpZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUoKHQpID0+IHtcbiAgICAgICAgICAgICAgICBhcmdzW3RpbWVQb3NpdGlvbl0gPSB0O1xuICAgICAgICAgICAgICAgIG9yaWdpbmFsTWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfSwgdGltZSk7XG4gICAgICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMucHVzaChpZCk7XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgaW5zdHJ1bWVudCBmcm9tIHRoZSBUcmFuc3BvcnRcbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cy5mb3JFYWNoKGlkID0+IHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoaWQpKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzID0gW107XG4gICAgICAgIGlmICh0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrID0gdGhpcy5fb3JpZ2luYWxfdHJpZ2dlckF0dGFjaztcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UgPSB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyUmVsZWFzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIGFuZCB0aGVuIHRoZSByZWxlYXNlIGFmdGVyIHRoZSBkdXJhdGlvbi5cbiAgICAgKiBAcGFyYW0gIG5vdGUgICAgIFRoZSBub3RlIHRvIHRyaWdnZXIuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBIb3cgbG9uZyB0aGUgbm90ZSBzaG91bGQgYmUgaGVsZCBmb3IgYmVmb3JlXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcmluZyB0aGUgcmVsZWFzZS4gVGhpcyB2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwLlxuICAgICAqIEBwYXJhbSB0aW1lICBXaGVuIHRoZSBub3RlIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgdGhlIG5vdGUgc2hvdWxkIGJlIHRyaWdnZXJlZCBhdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gdHJpZ2dlciBcIkM0XCIgZm9yIHRoZSBkdXJhdGlvbiBvZiBhbiA4dGggbm90ZVxuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShub3RlLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkRHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlLCBjb21wdXRlZFRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShjb21wdXRlZFRpbWUgKyBjb21wdXRlZER1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICogQHJldHVybnMge0luc3RydW1lbnR9IHRoaXNcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1JbnN0cnVtZW50LmpzLm1hcCIsImltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9GcmVxdWVuY3lcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4uL2luc3RydW1lbnQvSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgdGltZVJhbmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbi8qKlxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3Igb3RoZXIgbW9ub3Bob25pYyBpbnN0cnVtZW50cyB0byBleHRlbmQuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb25vcGhvbmljIGV4dGVuZHMgSW5zdHJ1bWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucG9ydGFtZW50byA9IG9wdGlvbnMucG9ydGFtZW50bztcbiAgICAgICAgdGhpcy5vbnNpbGVuY2UgPSBvcHRpb25zLm9uc2lsZW5jZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIG9uc2lsZW5jZTogbm9PcCxcbiAgICAgICAgICAgIHBvcnRhbWVudG86IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgb2YgdGhlIG5vdGUgb3B0aW9uYWxseSB3aXRoIGEgZ2l2ZW4gdmVsb2NpdHkuXG4gICAgICogQHBhcmFtICBub3RlIFRoZSBub3RlIHRvIHRyaWdnZXIuXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIG5vdGUgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHNjYWxlciBkZXRlcm1pbmVzIGhvdyBcImxvdWRcIiB0aGUgbm90ZSB3aWxsIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgbm90ZSBhIGhhbGYgc2Vjb25kIGZyb20gbm93IGF0IGhhbGYgdmVsb2NpdHlcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFwiQzRcIiwgXCIrMC41XCIsIDAuNSk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayhub3RlLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIG5vdGUsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2soc2Vjb25kcywgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnNldE5vdGUobm90ZSwgc2Vjb25kcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtICB0aW1lIElmIG5vIHRpbWUgaXMgZ2l2ZW4sIHRoZSByZWxlYXNlIGhhcHBlbnMgaW1tZWRpYXRseVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFwiQzRcIik7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgcmVsZWFzZSBhIHNlY29uZCBmcm9tIG5vd1xuICAgICAqIHN5bnRoLnRyaWdnZXJSZWxlYXNlKFwiKzFcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIHRpbWUpO1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2Uoc2Vjb25kcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIG5vdGUgYXQgdGhlIGdpdmVuIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sIHRoZSBub3RlXG4gICAgICogd2lsbCBzZXQgaW1tZWRpYXRlbHkuXG4gICAgICogQHBhcmFtIG5vdGUgVGhlIG5vdGUgdG8gY2hhbmdlIHRvLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB3aGVuIHRoZSBub3RlIHNob3VsZCBiZSBzZXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soXCJDNFwiKTtcbiAgICAgKiAvLyBjaGFuZ2UgdG8gRiM2IGluIG9uZSBxdWFydGVyIG5vdGUgZnJvbSBub3cuXG4gICAgICogc3ludGguc2V0Tm90ZShcIkYjNlwiLCBcIis0blwiKTtcbiAgICAgKi9cbiAgICBzZXROb3RlKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkRnJlcXVlbmN5ID0gbm90ZSBpbnN0YW5jZW9mIEZyZXF1ZW5jeUNsYXNzID8gbm90ZS50b0ZyZXF1ZW5jeSgpIDogbm90ZTtcbiAgICAgICAgaWYgKHRoaXMucG9ydGFtZW50byA+IDAgJiYgdGhpcy5nZXRMZXZlbEF0VGltZShjb21wdXRlZFRpbWUpID4gMC4wNSkge1xuICAgICAgICAgICAgY29uc3QgcG9ydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLnBvcnRhbWVudG8pO1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuZXhwb25lbnRpYWxSYW1wVG8oY29tcHV0ZWRGcmVxdWVuY3ksIHBvcnRUaW1lLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRGcmVxdWVuY3ksIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBNb25vcGhvbmljLnByb3RvdHlwZSwgXCJwb3J0YW1lbnRvXCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb25vcGhvbmljLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi9FbnZlbG9wZVwiO1xuLyoqXG4gKiBBbXBsaXR1ZGVFbnZlbG9wZSBpcyBhIFRvbmUuRW52ZWxvcGUgY29ubmVjdGVkIHRvIGEgZ2FpbiBub2RlLlxuICogVW5saWtlIFRvbmUuRW52ZWxvcGUsIHdoaWNoIG91dHB1dHMgdGhlIGVudmVsb3BlJ3MgdmFsdWUsIEFtcGxpdHVkZUVudmVsb3BlIGFjY2VwdHNcbiAqIGFuIGF1ZGlvIHNpZ25hbCBhcyB0aGUgaW5wdXQgYW5kIHdpbGwgYXBwbHkgdGhlIGVudmVsb3BlIHRvIHRoZSBhbXBsaXR1ZGVcbiAqIG9mIHRoZSBzaWduYWwuXG4gKiBSZWFkIG1vcmUgYWJvdXQgQURTUiBFbnZlbG9wZXMgb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ludGhlc2l6ZXIjQURTUl9lbnZlbG9wZSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhbXBFbnYgPSBuZXcgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSh7XG4gKiBcdFx0YXR0YWNrOiAwLjEsXG4gKiBcdFx0ZGVjYXk6IDAuMixcbiAqIFx0XHRzdXN0YWluOiAxLjAsXG4gKiBcdFx0cmVsZWFzZTogMC44XG4gKiBcdH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Ly8gY3JlYXRlIGFuIG9zY2lsbGF0b3IgYW5kIGNvbm5lY3QgaXRcbiAqIFx0Y29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoYW1wRW52KS5zdGFydCgpO1xuICogXHQvLyB0cmlnZ2VyIHRoZSBlbnZlbG9wZXMgYXR0YWNrIGFuZCByZWxlYXNlIFwiOHRcIiBhcGFydFxuICogXHRhbXBFbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoXCI4dFwiKTtcbiAqIH0sIDEuNSwgMSk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBbXBsaXR1ZGVFbnZlbG9wZSBleHRlbmRzIEVudmVsb3BlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQW1wbGl0dWRlRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQW1wbGl0dWRlRW52ZWxvcGVcIjtcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLl9zaWcuY29ubmVjdCh0aGlzLl9nYWluTm9kZS5nYWluKTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BbXBsaXR1ZGVFbnZlbG9wZS5qcy5tYXAiLCJpbXBvcnQgeyBBbXBsaXR1ZGVFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGVcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgT21uaU9zY2lsbGF0b3IgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuLyoqXG4gKiBTeW50aCBpcyBjb21wb3NlZCBzaW1wbHkgb2YgYSBbW09tbmlPc2NpbGxhdG9yXV0gcm91dGVkIHRocm91Z2ggYW4gW1tBbXBsaXR1ZGVFbnZlbG9wZV1dLlxuICogYGBgXG4gKiArLS0tLS0tLS0tLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIHwgT21uaU9zY2lsbGF0b3IgKz4tLT4gQW1wbGl0dWRlRW52ZWxvcGUgKz4tLT4gT3V0cHV0XG4gKiArLS0tLS0tLS0tLS0tLS0tLSsgICArLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG5ldyBPbW5pT3NjaWxsYXRvcihPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICB9LCBvcHRpb25zLm9zY2lsbGF0b3IpKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLm9zY2lsbGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMub3NjaWxsYXRvci5kZXR1bmU7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgQW1wbGl0dWRlRW52ZWxvcGUoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0sIG9wdGlvbnMuZW52ZWxvcGUpKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgb3NjaWxsYXRvcnMgdG8gdGhlIG91dHB1dFxuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuY2hhaW4odGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJvc2NpbGxhdG9yXCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiZW52ZWxvcGVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDA1LFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjMsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgWy4uLk9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ0cmlhbmdsZVwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIGF0dGFjayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlICgwLTEpXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICAvLyB0aGUgZW52ZWxvcGVzXG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgLy8gaWYgdGhlcmUgaXMgbm8gcmVsZWFzZSBwb3J0aW9uLCBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkQXR0YWNrID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spO1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWREZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpO1xuICAgICAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIGNvbXB1dGVkQXR0YWNrICsgY29tcHV0ZWREZWNheSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgcmVsZWFzZSBzaG91bGQgc3RhcnRcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IE9tbmlPc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgU3ludGggfSBmcm9tIFwiLi9TeW50aFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBib3RoIEFNIGFuZCBGTSBzeW50aHNcbiAqL1xuZXhwb3J0IGNsYXNzIE1vZHVsYXRpb25TeW50aCBleHRlbmRzIE1vbm9waG9uaWMge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb2R1bGF0aW9uU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTW9kdWxhdGlvblN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNb2R1bGF0aW9uU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBTeW50aCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBvcHRpb25zLm9zY2lsbGF0b3IsXG4gICAgICAgICAgICBlbnZlbG9wZTogb3B0aW9ucy5lbnZlbG9wZSxcbiAgICAgICAgICAgIG9uc2lsZW5jZTogKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcyksXG4gICAgICAgICAgICB2b2x1bWU6IC0xMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBTeW50aCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBvcHRpb25zLm1vZHVsYXRpb24sXG4gICAgICAgICAgICBlbnZlbG9wZTogb3B0aW9ucy5tb2R1bGF0aW9uRW52ZWxvcGUsXG4gICAgICAgICAgICB2b2x1bWU6IC0xMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvciA9IHRoaXMuX2NhcnJpZXIub3NjaWxsYXRvcjtcbiAgICAgICAgdGhpcy5lbnZlbG9wZSA9IHRoaXMuX2NhcnJpZXIuZW52ZWxvcGU7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbiA9IHRoaXMuX21vZHVsYXRvci5vc2NpbGxhdG9yO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25FbnZlbG9wZSA9IHRoaXMuX21vZHVsYXRvci5lbnZlbG9wZTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgICAgICBtaW5WYWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImhhcm1vbmljaXR5XCIsIFwib3NjaWxsYXRvclwiLCBcImVudmVsb3BlXCIsIFwibW9kdWxhdGlvblwiLCBcIm1vZHVsYXRpb25FbnZlbG9wZVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBoYXJtb25pY2l0eTogMyxcbiAgICAgICAgICAgIG9zY2lsbGF0b3I6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgW1xuICAgICAgICAgICAgICAgIC4uLk9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSxcbiAgICAgICAgICAgICAgICBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgICAgIFwiZGV0dW5lXCJcbiAgICAgICAgICAgIF0pLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzaW5lXCJcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgbW9kdWxhdGlvbjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBbXG4gICAgICAgICAgICAgICAgLi4uT2JqZWN0LmtleXMoU291cmNlLmdldERlZmF1bHRzKCkpLFxuICAgICAgICAgICAgICAgIFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICAgICAgXCJkZXR1bmVcIlxuICAgICAgICAgICAgXSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNxdWFyZVwiXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1vZHVsYXRpb25FbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC41LFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2NhcnJpZXIuX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9kdWxhdGlvblN5bnRoLmpzLm1hcCIsImltcG9ydCB7IEF1ZGlvVG9HYWluIH0gZnJvbSBcIi4uL3NpZ25hbC9BdWRpb1RvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNb2R1bGF0aW9uU3ludGggfSBmcm9tIFwiLi9Nb2R1bGF0aW9uU3ludGhcIjtcbi8qKlxuICogQU1TeW50aCB1c2VzIHRoZSBvdXRwdXQgb2Ygb25lIFRvbmUuU3ludGggdG8gbW9kdWxhdGUgdGhlXG4gKiBhbXBsaXR1ZGUgb2YgYW5vdGhlciBUb25lLlN5bnRoLiBUaGUgaGFybW9uaWNpdHkgKHRoZSByYXRpbyBiZXR3ZWVuXG4gKiB0aGUgdHdvIHNpZ25hbHMpIGFmZmVjdHMgdGhlIHRpbWJyZSBvZiB0aGUgb3V0cHV0IHNpZ25hbCBncmVhdGx5LlxuICogUmVhZCBtb3JlIGFib3V0IEFtcGxpdHVkZSBNb2R1bGF0aW9uIFN5bnRoZXNpcyBvblxuICogW1NvdW5kT25Tb3VuZF0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDA0MTAzNjUzL2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbTo4MC9zb3MvbWFyMDAvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuQU1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI0blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgQU1TeW50aCBleHRlbmRzIE1vZHVsYXRpb25TeW50aCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFNU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQU1TeW50aFwiO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUgPSBuZXcgQXVkaW9Ub0dhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29udHJvbCB0aGUgdHdvIHZvaWNlcyBmcmVxdWVuY3lcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMuX21vZHVsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmRldHVuZS5mYW4odGhpcy5fY2Fycmllci5kZXR1bmUsIHRoaXMuX21vZHVsYXRvci5kZXR1bmUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY2hhaW4odGhpcy5fbW9kdWxhdGlvblNjYWxlLCB0aGlzLl9tb2R1bGF0aW9uTm9kZS5nYWluKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jaGFpbih0aGlzLl9tb2R1bGF0aW9uTm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFNU3ludGguanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogVGhpbiB3cmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIFdlYiBBdWRpbyBbQmlxdWFkRmlsdGVyTm9kZV0oaHR0cHM6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jYmlxdWFkZmlsdGVybm9kZSkuXG4gKiBCaXF1YWRGaWx0ZXIgaXMgc2ltaWxhciB0byBbW0ZpbHRlcl1dIGJ1dCBkb2Vzbid0IGhhdmUgdGhlIG9wdGlvbiB0byBzZXQgdGhlIFwicm9sbG9mZlwiIHZhbHVlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQmlxdWFkRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpcXVhZEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJCaXF1YWRGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpcXVhZEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9maWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuX2ZpbHRlcjtcbiAgICAgICAgdGhpcy5RID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuUSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2ZpbHRlci5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2ZpbHRlci5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdhaW4gPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZ2FpbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMzUwLFxuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoaXMgQmlxdWFkRmlsdGVyTm9kZS4gRm9yIGEgY29tcGxldGUgbGlzdCBvZiB0eXBlcyBhbmQgdGhlaXIgYXR0cmlidXRlcywgc2VlIHRoZVxuICAgICAqIFtXZWIgQXVkaW8gQVBJXShodHRwczovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNkb20tYmlxdWFkZmlsdGVydHlwZS1sb3dwYXNzKVxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgY29uc3QgdHlwZXMgPSBbXCJsb3dwYXNzXCIsIFwiaGlnaHBhc3NcIiwgXCJiYW5kcGFzc1wiLFxuICAgICAgICAgICAgXCJsb3dzaGVsZlwiLCBcImhpZ2hzaGVsZlwiLCBcIm5vdGNoXCIsIFwiYWxscGFzc1wiLCBcInBlYWtpbmdcIl07XG4gICAgICAgIGFzc2VydCh0eXBlcy5pbmRleE9mKHR5cGUpICE9PSAtMSwgYEludmFsaWQgZmlsdGVyIHR5cGU6ICR7dHlwZX1gKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZS4gVGhpcyBjdXJ2ZSByZXByZXNlbnRzIGhvdyB0aGUgZmlsdGVyXG4gICAgICogcmVzcG9uc2VzIHRvIGZyZXF1ZW5jaWVzIGJldHdlZW4gMjBoei0yMGtoei5cbiAgICAgKiBAcGFyYW0gIGxlbiBUaGUgbnVtYmVyIG9mIHZhbHVlcyB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUgYmV0d2VlbiAyMC0yMGtIelxuICAgICAqL1xuICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGxlbiA9IDEyOCkge1xuICAgICAgICAvLyBzdGFydCB3aXRoIGFsbCAxc1xuICAgICAgICBjb25zdCBmcmVxVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBub3JtID0gTWF0aC5wb3coaSAvIGxlbiwgMik7XG4gICAgICAgICAgICBjb25zdCBmcmVxID0gbm9ybSAqICgyMDAwMCAtIDIwKSArIDIwO1xuICAgICAgICAgICAgZnJlcVZhbHVlc1tpXSA9IGZyZXE7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWFnVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICBjb25zdCBwaGFzZVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgLy8gY2xvbmUgdGhlIGZpbHRlciB0byByZW1vdmUgYW55IGNvbm5lY3Rpb25zIHdoaWNoIG1heSBiZSBjaGFuZ2luZyB0aGUgdmFsdWVcbiAgICAgICAgY29uc3QgZmlsdGVyQ2xvbmUgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgIGZpbHRlckNsb25lLnR5cGUgPSB0aGlzLnR5cGU7XG4gICAgICAgIGZpbHRlckNsb25lLlEudmFsdWUgPSB0aGlzLlEudmFsdWU7XG4gICAgICAgIGZpbHRlckNsb25lLmZyZXF1ZW5jeS52YWx1ZSA9IHRoaXMuZnJlcXVlbmN5LnZhbHVlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5nYWluLnZhbHVlID0gdGhpcy5nYWluLnZhbHVlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxVmFsdWVzLCBtYWdWYWx1ZXMsIHBoYXNlVmFsdWVzKTtcbiAgICAgICAgcmV0dXJuIG1hZ1ZhbHVlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZ2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QmlxdWFkRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzTnVtYmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBCaXF1YWRGaWx0ZXIgfSBmcm9tIFwiLi9CaXF1YWRGaWx0ZXJcIjtcbi8qKlxuICogVG9uZS5GaWx0ZXIgaXMgYSBmaWx0ZXIgd2hpY2ggYWxsb3dzIGZvciBhbGwgb2YgdGhlIHNhbWUgbmF0aXZlIG1ldGhvZHNcbiAqIGFzIHRoZSBbQmlxdWFkRmlsdGVyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtYmlxdWFkZmlsdGVybm9kZS1pbnRlcmZhY2UpLlxuICogVG9uZS5GaWx0ZXIgaGFzIHRoZSBhZGRlZCBhYmlsaXR5IHRvIHNldCB0aGUgZmlsdGVyIHJvbGxvZmYgYXQgLTEyXG4gKiAoZGVmYXVsdCksIC0yNCBhbmQgLTQ4LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcigxNTAwLCBcImhpZ2hwYXNzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGZpbHRlci5mcmVxdWVuY3kucmFtcFRvKDIwMDAwLCAxMCk7XG4gKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKCkuY29ubmVjdChmaWx0ZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInJvbGxvZmZcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGaWx0ZXJcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9maWx0ZXJzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwicm9sbG9mZlwiXSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMgPSBbXTtcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5nYWluID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5nYWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5yb2xsb2ZmID0gb3B0aW9ucy5yb2xsb2ZmO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJkZXR1bmVcIiwgXCJmcmVxdWVuY3lcIiwgXCJnYWluXCIsIFwiUVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAzNTAsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICAgICAgcm9sbG9mZjogLTEyLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgZmlsdGVyLiBUeXBlczogXCJsb3dwYXNzXCIsIFwiaGlnaHBhc3NcIixcbiAgICAgKiBcImJhbmRwYXNzXCIsIFwibG93c2hlbGZcIiwgXCJoaWdoc2hlbGZcIiwgXCJub3RjaFwiLCBcImFsbHBhc3NcIiwgb3IgXCJwZWFraW5nXCIuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gW1wibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsIFwiYmFuZHBhc3NcIixcbiAgICAgICAgICAgIFwibG93c2hlbGZcIiwgXCJoaWdoc2hlbGZcIiwgXCJub3RjaFwiLCBcImFsbHBhc3NcIiwgXCJwZWFraW5nXCJdO1xuICAgICAgICBhc3NlcnQodHlwZXMuaW5kZXhPZih0eXBlKSAhPT0gLTEsIGBJbnZhbGlkIGZpbHRlciB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IGZpbHRlci50eXBlID0gdHlwZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSByb2xsb2ZmIG9mIHRoZSBmaWx0ZXIgd2hpY2ggaXMgdGhlIGRyb3AgaW4gZGJcbiAgICAgKiBwZXIgb2N0YXZlLiBJbXBsZW1lbnRlZCBpbnRlcm5hbGx5IGJ5IGNhc2NhZGluZyBmaWx0ZXJzLlxuICAgICAqIE9ubHkgYWNjZXB0cyB0aGUgdmFsdWVzIC0xMiwgLTI0LCAtNDggYW5kIC05Ni5cbiAgICAgKi9cbiAgICBnZXQgcm9sbG9mZigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3JvbGxvZmY7XG4gICAgfVxuICAgIHNldCByb2xsb2ZmKHJvbGxvZmYpIHtcbiAgICAgICAgY29uc3Qgcm9sbG9mZk51bSA9IGlzTnVtYmVyKHJvbGxvZmYpID8gcm9sbG9mZiA6IHBhcnNlSW50KHJvbGxvZmYsIDEwKTtcbiAgICAgICAgY29uc3QgcG9zc2liaWxpdGllcyA9IFstMTIsIC0yNCwgLTQ4LCAtOTZdO1xuICAgICAgICBsZXQgY2FzY2FkaW5nQ291bnQgPSBwb3NzaWJpbGl0aWVzLmluZGV4T2Yocm9sbG9mZk51bSk7XG4gICAgICAgIC8vIGNoZWNrIHRoZSByb2xsb2ZmIGlzIHZhbGlkXG4gICAgICAgIGFzc2VydChjYXNjYWRpbmdDb3VudCAhPT0gLTEsIGByb2xsb2ZmIGNhbiBvbmx5IGJlICR7cG9zc2liaWxpdGllcy5qb2luKFwiLCBcIil9YCk7XG4gICAgICAgIGNhc2NhZGluZ0NvdW50ICs9IDE7XG4gICAgICAgIHRoaXMuX3JvbGxvZmYgPSByb2xsb2ZmTnVtO1xuICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiBmaWx0ZXIuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycyA9IG5ldyBBcnJheShjYXNjYWRpbmdDb3VudCk7XG4gICAgICAgIGZvciAobGV0IGNvdW50ID0gMDsgY291bnQgPCBjYXNjYWRpbmdDb3VudDsgY291bnQrKykge1xuICAgICAgICAgICAgY29uc3QgZmlsdGVyID0gbmV3IEJpcXVhZEZpbHRlcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBmaWx0ZXIudHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KGZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdChmaWx0ZXIuZGV0dW5lKTtcbiAgICAgICAgICAgIHRoaXMuUS5jb25uZWN0KGZpbHRlci5RKTtcbiAgICAgICAgICAgIHRoaXMuZ2Fpbi5jb25uZWN0KGZpbHRlci5nYWluKTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlcnNbY291bnRdID0gZmlsdGVyO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSB0aGlzLl9maWx0ZXJzO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIC4uLnRoaXMuX2ludGVybmFsQ2hhbm5lbHMsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgY29uc3QgZmlsdGVyQ2xvbmUgPSBuZXcgQmlxdWFkRmlsdGVyKHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogdGhpcy5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICBnYWluOiB0aGlzLmdhaW4udmFsdWUsXG4gICAgICAgICAgICBROiB0aGlzLlEudmFsdWUsXG4gICAgICAgICAgICB0eXBlOiB0aGlzLl90eXBlLFxuICAgICAgICAgICAgZGV0dW5lOiB0aGlzLmRldHVuZS52YWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHN0YXJ0IHdpdGggYWxsIDFzXG4gICAgICAgIGNvbnN0IHRvdGFsUmVzcG9uc2UgPSBuZXcgRmxvYXQzMkFycmF5KGxlbikubWFwKCgpID0+IDEpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBmaWx0ZXJDbG9uZS5nZXRGcmVxdWVuY3lSZXNwb25zZShsZW4pO1xuICAgICAgICAgICAgcmVzcG9uc2UuZm9yRWFjaCgodmFsLCBpKSA9PiB0b3RhbFJlc3BvbnNlW2ldICo9IHZhbCk7XG4gICAgICAgIH0pO1xuICAgICAgICBmaWx0ZXJDbG9uZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0b3RhbFJlc3BvbnNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4ge1xuICAgICAgICAgICAgZmlsdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFtcImRldHVuZVwiLCBcImZyZXF1ZW5jeVwiLCBcImdhaW5cIiwgXCJRXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZ2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4vRW52ZWxvcGVcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgUG93IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9Qb3dcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBGcmVxdWVuY3lFbnZlbG9wZSBpcyBhbiBbW0VudmVsb3BlXV0gd2hpY2ggcmFtcHMgYmV0d2VlbiBbW2Jhc2VGcmVxdWVuY3ldXVxuICogYW5kIFtbb2N0YXZlc11dLiBJdCBjYW4gYWxzbyBoYXZlIGFuIG9wdGlvbmFsIFtbZXhwb25lbnRdXSB0byBhZGp1c3QgdGhlIGN1cnZlXG4gKiB3aGljaCBpdCByYW1wcy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogY29uc3QgZnJlcUVudiA9IG5ldyBUb25lLkZyZXF1ZW5jeUVudmVsb3BlKHtcbiAqIFx0YXR0YWNrOiAwLjIsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IFwiQzJcIixcbiAqIFx0b2N0YXZlczogNFxuICogfSk7XG4gKiBmcmVxRW52LmNvbm5lY3Qob3NjaWxsYXRvci5mcmVxdWVuY3kpO1xuICogZnJlcUVudi50cmlnZ2VyQXR0YWNrKCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVxdWVuY3lFbnZlbG9wZSBleHRlbmRzIEVudmVsb3BlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5RW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlcXVlbmN5RW52ZWxvcGVcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSk7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KG9wdGlvbnMuYmFzZUZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50ID0gdGhpcy5pbnB1dCA9IG5ldyBQb3coe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZXhwb25lbnRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NjYWxlID0gdGhpcy5vdXRwdXQgPSBuZXcgU2NhbGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiB0aGlzLl9iYXNlRnJlcXVlbmN5LFxuICAgICAgICAgICAgbWF4OiB0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgdGhpcy5fb2N0YXZlcyksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaWcuY2hhaW4odGhpcy5fZXhwb25lbnQsIHRoaXMuX3NjYWxlKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFbnZlbG9wZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiYXNlRnJlcXVlbmN5OiAyMDAsXG4gICAgICAgICAgICBleHBvbmVudDogMSxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZW52ZWxvcGUncyBtaW5pbXVtIG91dHB1dCB2YWx1ZS4gVGhpcyBpcyB0aGUgdmFsdWUgd2hpY2ggaXRcbiAgICAgKiBzdGFydHMgYXQuXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShtaW4pIHtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3kobWluKTtcbiAgICAgICAgYXNzZXJ0UmFuZ2UoZnJlcSwgMCk7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSBmcmVxO1xuICAgICAgICB0aGlzLl9zY2FsZS5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICAvLyB1cGRhdGUgdGhlIG1heCB2YWx1ZSB3aGVuIHRoZSBtaW4gY2hhbmdlc1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgYWJvdmUgdGhlIGJhc2VGcmVxdWVuY3kgdGhhdCB0aGVcbiAgICAgKiBlbnZlbG9wZSB3aWxsIHNjYWxlIHRvLlxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgdGhpcy5fc2NhbGUubWF4ID0gdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIG9jdGF2ZXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZW52ZWxvcGUncyBleHBvbmVudCB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgZXhwb25lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9leHBvbmVudC52YWx1ZTtcbiAgICB9XG4gICAgc2V0IGV4cG9uZW50KGV4cG9uZW50KSB7XG4gICAgICAgIHRoaXMuX2V4cG9uZW50LnZhbHVlID0gZXhwb25lbnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHBvbmVudC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlcXVlbmN5RW52ZWxvcGUuanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZpbHRlclwiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuLi9pbnN0cnVtZW50L01vbm9waG9uaWNcIjtcbmltcG9ydCB7IE9tbmlPc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5RW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0ZyZXF1ZW5jeUVudmVsb3BlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIE1vbm9TeW50aCBpcyBjb21wb3NlZCBvZiBvbmUgYG9zY2lsbGF0b3JgLCBvbmUgYGZpbHRlcmAsIGFuZCB0d28gYGVudmVsb3Blc2AuXG4gKiBUaGUgYW1wbGl0dWRlIG9mIHRoZSBPc2NpbGxhdG9yIGFuZCB0aGUgY3V0b2ZmIGZyZXF1ZW5jeSBvZiB0aGVcbiAqIEZpbHRlciBhcmUgY29udHJvbGxlZCBieSBFbnZlbG9wZXMuXG4gKiA8aW1nIHNyYz1cImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RyYXdpbmdzL2QvMWdhWTFERjlfSHprb2RxZjhKSTFDZzJWWmZ3U0VscEZRZkk5NElRd2FkMzgvcHViP3c9OTI0Jmg9MjQwXCI+XG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Nb25vU3ludGgoe1xuICogXHRvc2NpbGxhdG9yOiB7XG4gKiBcdFx0dHlwZTogXCJzcXVhcmVcIlxuICogXHR9LFxuICogXHRlbnZlbG9wZToge1xuICogXHRcdGF0dGFjazogMC4xXG4gKiBcdH1cbiAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNb25vU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1vbm9TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvciA9IG5ldyBPbW5pT3NjaWxsYXRvcihPYmplY3QuYXNzaWduKG9wdGlvbnMub3NjaWxsYXRvciwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnNpbGVuY2UodGhpcyksXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLm9zY2lsbGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMub3NjaWxsYXRvci5kZXR1bmU7XG4gICAgICAgIHRoaXMuZmlsdGVyID0gbmV3IEZpbHRlcihPYmplY3QuYXNzaWduKG9wdGlvbnMuZmlsdGVyLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUgPSBuZXcgRnJlcXVlbmN5RW52ZWxvcGUoT2JqZWN0LmFzc2lnbihvcHRpb25zLmZpbHRlckVudmVsb3BlLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgQW1wbGl0dWRlRW52ZWxvcGUoT2JqZWN0LmFzc2lnbihvcHRpb25zLmVudmVsb3BlLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3JzIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmNoYWluKHRoaXMuZmlsdGVyLCB0aGlzLmVudmVsb3BlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGZpbHRlciBlbnZlbG9wZVxuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLmNvbm5lY3QodGhpcy5maWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wib3NjaWxsYXRvclwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImZpbHRlclwiLCBcImZpbHRlckVudmVsb3BlXCIsIFwiZW52ZWxvcGVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDA1LFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGZpbHRlcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgICAgIHJvbGxvZmY6IC0xMixcbiAgICAgICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZmlsdGVyRW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRnJlcXVlbmN5RW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuNixcbiAgICAgICAgICAgICAgICBiYXNlRnJlcXVlbmN5OiAyMDAsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMixcbiAgICAgICAgICAgICAgICBleHBvbmVudDogMixcbiAgICAgICAgICAgICAgICBvY3RhdmVzOiAzLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDIsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC41LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgYXR0YWNrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSB0aGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUgKDAtMSlcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRBdHRhY2sgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjayk7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZERlY2F5ID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5kZWNheSk7XG4gICAgICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgY29tcHV0ZWRBdHRhY2sgKyBjb21wdXRlZERlY2F5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSByZWxlYXNlIHNob3VsZCBzdGFydFxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vbm9TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuaW1wb3J0IHsgTW9ub1N5bnRoIH0gZnJvbSBcIi4vTW9ub1N5bnRoXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgR2FpbiwgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlLCBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIER1b1N5bnRoIGlzIGEgbW9ub3Bob25pYyBzeW50aCBjb21wb3NlZCBvZiB0d28gW1tNb25vU3ludGhzXV0gcnVuIGluIHBhcmFsbGVsIHdpdGggY29udHJvbCBvdmVyIHRoZVxuICogZnJlcXVlbmN5IHJhdGlvIGJldHdlZW4gdGhlIHR3byB2b2ljZXMgYW5kIHZpYnJhdG8gZWZmZWN0LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGR1b1N5bnRoID0gbmV3IFRvbmUuRHVvU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBkdW9TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiMm5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgRHVvU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRHVvU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRHVvU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKER1b1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMudm9pY2UwID0gbmV3IE1vbm9TeW50aChPYmplY3QuYXNzaWduKG9wdGlvbnMudm9pY2UwLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvbnNpbGVuY2U6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy52b2ljZTEgPSBuZXcgTW9ub1N5bnRoKE9iamVjdC5hc3NpZ24ob3B0aW9ucy52b2ljZTEsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSkpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy52aWJyYXRvUmF0ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogLTUwLFxuICAgICAgICAgICAgbWF4OiA1MFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIHZpYnJhdG8gaW1tZWRpYXRlbHlcbiAgICAgICAgdGhpcy5fdmlicmF0by5zdGFydCgpO1xuICAgICAgICB0aGlzLnZpYnJhdG9SYXRlID0gdGhpcy5fdmlicmF0by5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMudmlicmF0b0Ftb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52aWJyYXRvQW1vdW50ID0gdGhpcy5fdmlicmF0b0dhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IDQ0MFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmVcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy52b2ljZTAuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy52b2ljZTEuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fdmlicmF0by5jb25uZWN0KHRoaXMuX3ZpYnJhdG9HYWluKTtcbiAgICAgICAgdGhpcy5fdmlicmF0b0dhaW4uZmFuKHRoaXMudm9pY2UwLmRldHVuZSwgdGhpcy52b2ljZTEuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMudm9pY2UwLmRldHVuZSwgdGhpcy52b2ljZTEuZGV0dW5lKTtcbiAgICAgICAgdGhpcy52b2ljZTAuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMudm9pY2UxLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ2b2ljZTBcIiwgXCJ2b2ljZTFcIiwgXCJmcmVxdWVuY3lcIiwgXCJ2aWJyYXRvQW1vdW50XCIsIFwidmlicmF0b1JhdGVcIl0pO1xuICAgIH1cbiAgICBnZXRMZXZlbEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9pY2UwLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpICsgdGhpcy52b2ljZTEuZW52ZWxvcGUuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBNZXJnZShNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZpYnJhdG9BbW91bnQ6IDAuNSxcbiAgICAgICAgICAgIHZpYnJhdG9SYXRlOiA1LFxuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEuNSxcbiAgICAgICAgICAgIHZvaWNlMDogZGVlcE1lcmdlKG9taXRGcm9tT2JqZWN0KE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdm9pY2UxOiBkZWVwTWVyZ2Uob21pdEZyb21PYmplY3QoTW9ub1N5bnRoLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgZmlsdGVyRW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMC5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMS5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBub3RlXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMudm9pY2UwLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMudm9pY2UxLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvaWNlMC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9pY2UxLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZpYnJhdG9SYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdmlicmF0b0dhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RHVvU3ludGguanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IE1vZHVsYXRpb25TeW50aCB9IGZyb20gXCIuL01vZHVsYXRpb25TeW50aFwiO1xuLyoqXG4gKiBGTVN5bnRoIGlzIGNvbXBvc2VkIG9mIHR3byBUb25lLlN5bnRocyB3aGVyZSBvbmUgVG9uZS5TeW50aCBtb2R1bGF0ZXNcbiAqIHRoZSBmcmVxdWVuY3kgb2YgYSBzZWNvbmQgVG9uZS5TeW50aC4gQSBsb3Qgb2Ygc3BlY3RyYWwgY29udGVudFxuICogY2FuIGJlIGV4cGxvcmVkIHVzaW5nIHRoZSBtb2R1bGF0aW9uSW5kZXggcGFyYW1ldGVyLiBSZWFkIG1vcmUgYWJvdXRcbiAqIGZyZXF1ZW5jeSBtb2R1bGF0aW9uIHN5bnRoZXNpcyBvbiBTb3VuZCBPbiBTb3VuZDogW1BhcnQgMV0oaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTYwNDAzMTIzNzA0L2h0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvYXByMDAvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSksIFtQYXJ0IDJdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwMzExNTgzNS9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb20vc29zL21heTAwL2FydGljbGVzL3N5bnRoLmh0bSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZtU3ludGggPSBuZXcgVG9uZS5GTVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogZm1TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM1XCIsIFwiNG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEZNU3ludGggZXh0ZW5kcyBNb2R1bGF0aW9uU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZNU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZNU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uSW5kZXggPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubW9kdWxhdGlvbkluZGV4LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29udHJvbCB0aGUgdHdvIHZvaWNlcyBmcmVxdWVuY3lcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMuX21vZHVsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLm1vZHVsYXRpb25JbmRleCwgdGhpcy5fbW9kdWxhdGlvbk5vZGUpO1xuICAgICAgICB0aGlzLmRldHVuZS5mYW4odGhpcy5fY2Fycmllci5kZXR1bmUsIHRoaXMuX21vZHVsYXRvci5kZXR1bmUpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuY29ubmVjdCh0aGlzLl9tb2R1bGF0aW9uTm9kZS5nYWluKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuY29ubmVjdCh0aGlzLl9jYXJyaWVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1vZHVsYXRpb25JbmRleDogMTAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Rk1TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZpbHRlclwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlLCBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi4vc2lnbmFsL1NjYWxlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgRk1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0ZNT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbi8qKlxuICogSW5oYXJtb25pYyByYXRpbyBvZiBmcmVxdWVuY2llcyBiYXNlZCBvbiB0aGUgUm9sYW5kIFRSLTgwOFxuICogVGFrZW4gZnJvbSBodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9wYXBlcnMvdHItODA4LWN5bWJhbC1waHlzaWNhbGx5LWluZm9ybWVkLWNpcmN1aXQtYmVuZGFibGUtZGlnaXRhbC1tb2RlbFxuICovXG5jb25zdCBpbmhhcm1SYXRpb3MgPSBbMS4wLCAxLjQ4MywgMS45MzIsIDIuNTQ2LCAyLjYzMCwgMy44OTddO1xuLyoqXG4gKiBBIGhpZ2hseSBpbmhhcm1vbmljIGFuZCBzcGVjdHJhbGx5IGNvbXBsZXggc291cmNlIHdpdGggYSBoaWdocGFzcyBmaWx0ZXJcbiAqIGFuZCBhbXBsaXR1ZGUgZW52ZWxvcGUgd2hpY2ggaXMgZ29vZCBmb3IgbWFraW5nIG1ldGFsbG9waG9uZSBzb3VuZHMuXG4gKiBCYXNlZCBvbiBDeW1iYWxTeW50aCBieSBbQHBvbHlyaHl0aG1hdGljXShodHRwczovL2dpdGh1Yi5jb20vcG9seXJoeXRobWF0aWMpLlxuICogSW5zcGlyYXRpb24gZnJvbSBbU291bmQgb24gU291bmRdKGh0dHBzOi8vc2hvcnR1cmwuYXQvclNaMTIpLlxuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1ldGFsU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0YWxTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZXRhbFN5bnRoXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXJyYXkgb2YgRk1Pc2NpbGxhdG9yc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBmcmVxdWVuY3kgbXVsdGlwbGllcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0YWxTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9oaWdocGFzcyA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgLy8gUTogLTMuMDEwMjk5OTU2NjM5ODEyNSxcbiAgICAgICAgICAgIFE6IDAsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcImhpZ2hwYXNzXCIsXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmhhcm1SYXRpb3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG9zYyA9IG5ldyBGTU9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBoYXJtb25pY2l0eTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IG9wdGlvbnMubW9kdWxhdGlvbkluZGV4LFxuICAgICAgICAgICAgICAgIG1vZHVsYXRpb25UeXBlOiBcInNxdWFyZVwiLFxuICAgICAgICAgICAgICAgIG9uc3RvcDogaSA9PT0gMCA/ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpIDogbm9PcCxcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNxdWFyZVwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBvc2MuY29ubmVjdCh0aGlzLl9oaWdocGFzcyk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yc1tpXSA9IG9zYztcbiAgICAgICAgICAgIGNvbnN0IG11bHQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogaW5oYXJtUmF0aW9zW2ldLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9mcmVxTXVsdGlwbGllcnNbaV0gPSBtdWx0O1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4obXVsdCwgb3NjLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB0aGlzLmRldHVuZS5jb25uZWN0KG9zYy5kZXR1bmUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIgPSBuZXcgU2NhbGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4OiA3MDAwLFxuICAgICAgICAgICAgbWluOiB0aGlzLnRvRnJlcXVlbmN5KG9wdGlvbnMucmVzb25hbmNlKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgRW52ZWxvcGUoe1xuICAgICAgICAgICAgYXR0YWNrOiBvcHRpb25zLmVudmVsb3BlLmF0dGFjayxcbiAgICAgICAgICAgIGF0dGFja0N1cnZlOiBcImxpbmVhclwiLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVjYXk6IG9wdGlvbnMuZW52ZWxvcGUuZGVjYXksXG4gICAgICAgICAgICByZWxlYXNlOiBvcHRpb25zLmVudmVsb3BlLnJlbGVhc2UsXG4gICAgICAgICAgICBzdXN0YWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5jaGFpbih0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLCB0aGlzLl9oaWdocGFzcy5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlLmdhaW4pO1xuICAgICAgICAvLyBzZXQgdGhlIG9jdGF2ZXNcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDEsXG4gICAgICAgICAgICAgICAgZGVjYXk6IDEuNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiA1LjEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDMyLFxuICAgICAgICAgICAgb2N0YXZlczogMS41LFxuICAgICAgICAgICAgcmVzb25hbmNlOiA0MDAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdGhlIGF0dGFjayBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgdGhhdCB0aGUgZW52ZWxvcGUgc2hvdWxkIGJlIHRyaWdnZXJlZCBhdC5cbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKG9zYyA9PiBvc2Muc3RhcnQodGltZSkpO1xuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKG9zYyA9PiB7XG4gICAgICAgICAgICAgICAgb3NjLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIG9mIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSByZWxlYXNlIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKG9zYyA9PiBvc2Muc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbW9kdWxhdGlvbkluZGV4IG9mIHRoZSBvc2NpbGxhdG9ycyB3aGljaCBtYWtlIHVwIHRoZSBzb3VyY2UuXG4gICAgICogc2VlIFtbRk1Pc2NpbGxhdG9yLm1vZHVsYXRpb25JbmRleF1dXG4gICAgICogQG1pbiAxXG4gICAgICogQG1heCAxMDBcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvbkluZGV4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0ubW9kdWxhdGlvbkluZGV4LnZhbHVlO1xuICAgIH1cbiAgICBzZXQgbW9kdWxhdGlvbkluZGV4KHZhbCkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKG9zYyA9PiAob3NjLm1vZHVsYXRpb25JbmRleC52YWx1ZSA9IHZhbCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaGFybW9uaWNpdHkgb2YgdGhlIG9zY2lsbGF0b3JzIHdoaWNoIG1ha2UgdXAgdGhlIHNvdXJjZS5cbiAgICAgKiBzZWUgVG9uZS5GTU9zY2lsbGF0b3IuaGFybW9uaWNpdHlcbiAgICAgKiBAbWluIDAuMVxuICAgICAqIEBtYXggMTBcbiAgICAgKi9cbiAgICBnZXQgaGFybW9uaWNpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5oYXJtb25pY2l0eS52YWx1ZTtcbiAgICB9XG4gICAgc2V0IGhhcm1vbmljaXR5KHZhbCkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKG9zYyA9PiAob3NjLmhhcm1vbmljaXR5LnZhbHVlID0gdmFsKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb3dlciBsZXZlbCBvZiB0aGUgaGlnaHBhc3MgZmlsdGVyIHdoaWNoIGlzIGF0dGFjaGVkIHRvIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBUaGlzIHZhbHVlIHNob3VsZCBiZSBiZXR3ZWVuIFswLCA3MDAwXVxuICAgICAqIEBtaW4gMFxuICAgICAqIEBtYXggNzAwMFxuICAgICAqL1xuICAgIGdldCByZXNvbmFuY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbjtcbiAgICB9XG4gICAgc2V0IHJlc29uYW5jZSh2YWwpIHtcbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5taW4gPSB0aGlzLnRvRnJlcXVlbmN5KHZhbCk7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyBhYm92ZSB0aGUgXCJyZXNvbmFuY2VcIiBmcmVxdWVuY3lcbiAgICAgKiB0aGF0IHRoZSBmaWx0ZXIgcmFtcHMgZHVyaW5nIHRoZSBhdHRhY2svZGVjYXkgZW52ZWxvcGVcbiAgICAgKiBAbWluIDBcbiAgICAgKiBAbWF4IDhcbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKHZhbCkge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gdmFsO1xuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1heCA9IHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluICogTWF0aC5wb3coMiwgdmFsKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9ycy5mb3JFYWNoKG9zYyA9PiBvc2MuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzLmZvckVhY2goZnJlcU11bHQgPT4gZnJlcU11bHQuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5faGlnaHBhc3MuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NZXRhbFN5bnRoLmpzLm1hcCIsImltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9GcmVxdWVuY3lcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNb25vcGhvbmljIH0gZnJvbSBcIi4vTW9ub3Bob25pY1wiO1xuaW1wb3J0IHsgU3ludGggfSBmcm9tIFwiLi9TeW50aFwiO1xuaW1wb3J0IHsgcmFuZ2UsIHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIE1lbWJyYW5lU3ludGggbWFrZXMga2ljayBhbmQgdG9tIHNvdW5kcyB1c2luZyBhIHNpbmdsZSBvc2NpbGxhdG9yXG4gKiB3aXRoIGFuIGFtcGxpdHVkZSBlbnZlbG9wZSBhbmQgZnJlcXVlbmN5IHJhbXAuIEEgVG9uZS5PbW5pT3NjaWxsYXRvclxuICogaXMgcm91dGVkIHRocm91Z2ggYSBUb25lLkFtcGxpdHVkZUVudmVsb3BlIHRvIHRoZSBvdXRwdXQuIFRoZSBkcnVtXG4gKiBxdWFsaXR5IG9mIHRoZSBzb3VuZCBjb21lcyBmcm9tIHRoZSBmcmVxdWVuY3kgZW52ZWxvcGUgYXBwbGllZFxuICogZHVyaW5nIE1lbWJyYW5lU3ludGgudHJpZ2dlckF0dGFjayhub3RlKS4gVGhlIGZyZXF1ZW5jeSBlbnZlbG9wZVxuICogc3RhcnRzIGF0IDxjb2RlPm5vdGUgKiAub2N0YXZlczwvY29kZT4gYW5kIHJhbXBzIHRvIDxjb2RlPm5vdGU8L2NvZGU+XG4gKiBvdmVyIHRoZSBkdXJhdGlvbiBvZiA8Y29kZT4ucGl0Y2hEZWNheTwvY29kZT4uXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1lbWJyYW5lU3ludGggZXh0ZW5kcyBTeW50aCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1lbWJyYW5lU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWVtYnJhbmVTeW50aFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogUG9ydGFtZW50byBpcyBpZ25vcmVkIGluIHRoaXMgc3ludGguIHVzZSBwaXRjaCBkZWNheSBpbnN0ZWFkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5wb3J0YW1lbnRvID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1lbWJyYW5lU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5waXRjaERlY2F5ID0gb3B0aW9ucy5waXRjaERlY2F5O1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm9zY2lsbGF0b3JcIiwgXCJlbnZlbG9wZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBNZXJnZShNb25vcGhvbmljLmdldERlZmF1bHRzKCksIFN5bnRoLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwMSxcbiAgICAgICAgICAgICAgICBhdHRhY2tDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMS40LFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuMDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb2N0YXZlczogMTAsXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGl0Y2hEZWNheTogMC4wNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHNldE5vdGUobm90ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGhlcnR6ID0gdGhpcy50b0ZyZXF1ZW5jeShub3RlIGluc3RhbmNlb2YgRnJlcXVlbmN5Q2xhc3MgPyBub3RlLnRvRnJlcXVlbmN5KCkgOiBub3RlKTtcbiAgICAgICAgY29uc3QgbWF4Tm90ZSA9IGhlcnR6ICogdGhpcy5vY3RhdmVzO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZnJlcXVlbmN5LnNldFZhbHVlQXRUaW1lKG1heE5vdGUsIHNlY29uZHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IuZnJlcXVlbmN5LmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUoaGVydHosIHNlY29uZHMgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLnBpdGNoRGVjYXkpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgcmFuZ2UoMClcbl0sIE1lbWJyYW5lU3ludGgucHJvdG90eXBlLCBcIm9jdGF2ZXNcIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgTWVtYnJhbmVTeW50aC5wcm90b3R5cGUsIFwicGl0Y2hEZWNheVwiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWVtYnJhbmVTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBBbXBsaXR1ZGVFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGVcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5vaXNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Ob2lzZVwiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuL0luc3RydW1lbnRcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbi8qKlxuICogVG9uZS5Ob2lzZVN5bnRoIGlzIGNvbXBvc2VkIG9mIFtbTm9pc2VdXSB0aHJvdWdoIGFuIFtbQW1wbGl0dWRlRW52ZWxvcGVdXS5cbiAqIGBgYFxuICogKy0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8IE5vaXNlICs+LS0+IEFtcGxpdHVkZUVudmVsb3BlICs+LS0+IE91dHB1dFxuICogKy0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBub2lzZVN5bnRoID0gbmV3IFRvbmUuTm9pc2VTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIG5vaXNlU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCI4blwiLCAwLjA1KTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBOb2lzZVN5bnRoIGV4dGVuZHMgSW5zdHJ1bWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTm9pc2VTeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTm9pc2VTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5vaXNlID0gbmV3IE5vaXNlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLm5vaXNlKSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSBuZXcgQW1wbGl0dWRlRW52ZWxvcGUoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0sIG9wdGlvbnMuZW52ZWxvcGUpKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgbm9pc2UgdG8gdGhlIG91dHB1dFxuICAgICAgICB0aGlzLm5vaXNlLmNoYWluKHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgZGVjYXk6IDAuMSxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG5vaXNlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE5vaXNlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcIndoaXRlXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVzLiBVbmxpa2Ugb3RoZXJcbiAgICAgKiBpbnN0cnVtZW50cywgVG9uZS5Ob2lzZVN5bnRoIGRvZXNuJ3QgaGF2ZSBhIG5vdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBub2lzZVN5bnRoID0gbmV3IFRvbmUuTm9pc2VTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBub2lzZVN5bnRoLnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIHRoZSBlbnZlbG9wZXNcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG5vaXNlXG4gICAgICAgIHRoaXMubm9pc2Uuc3RhcnQodGltZSk7XG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMubm9pc2Uuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5kZWNheSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZXMuXG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2UodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMubm9pc2Uuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDApO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgZHVyYXRpb24gPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UodGltZSArIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5ub2lzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ob2lzZVN5bnRoLmpzLm1hcCIsIi8qKlxuICogQWxsIG9mIHRoZSBjbGFzc2VzIG9yIGZ1bmN0aW9ucyB3aGljaCBhcmUgbG9hZGVkIGludG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmNvbnN0IHdvcmtsZXRDb250ZXh0ID0gbmV3IFNldCgpO1xuLyoqXG4gKiBBZGQgYSBjbGFzcyB0byB0aGUgQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFRvV29ya2xldChjbGFzc09yRnVuY3Rpb24pIHtcbiAgICB3b3JrbGV0Q29udGV4dC5hZGQoY2xhc3NPckZ1bmN0aW9uKTtcbn1cbi8qKlxuICogUmVnaXN0ZXIgYSBwcm9jZXNzb3IgaW4gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlIHdpdGggdGhlIGdpdmVuIG5hbWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyUHJvY2Vzc29yKG5hbWUsIGNsYXNzRGVzYykge1xuICAgIGNvbnN0IHByb2Nlc3NvciA9IC8qIGphdmFzY3JpcHQgKi8gYHJlZ2lzdGVyUHJvY2Vzc29yKFwiJHtuYW1lfVwiLCAke2NsYXNzRGVzY30pYDtcbiAgICB3b3JrbGV0Q29udGV4dC5hZGQocHJvY2Vzc29yKTtcbn1cbi8qKlxuICogR2V0IGFsbCBvZiB0aGUgbW9kdWxlcyB3aGljaCBoYXZlIGJlZW4gcmVnaXN0ZXJlZCB0byB0aGUgQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmtsZXRHbG9iYWxTY29wZSgpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh3b3JrbGV0Q29udGV4dCkuam9pbihcIlxcblwiKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVdvcmtsZXRHbG9iYWxTY29wZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgZ2V0V29ya2xldEdsb2JhbFNjb3BlIH0gZnJvbSBcIi4vV29ya2xldEdsb2JhbFNjb3BlXCI7XG5leHBvcnQgY2xhc3MgVG9uZUF1ZGlvV29ya2xldCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvV29ya2xldFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNvbnN0cnVjdG9yIG9wdGlvbnMgZm9yIHRoZSBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLndvcmtsZXRPcHRpb25zID0ge307XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsYmFjayB3aGljaCBpcyBpbnZva2VkIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIHByb2Nlc3NpbmdcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub25wcm9jZXNzb3JlcnJvciA9IG5vT3A7XG4gICAgICAgIGNvbnN0IGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFtnZXRXb3JrbGV0R2xvYmFsU2NvcGUoKV0sIHsgdHlwZTogXCJ0ZXh0L2phdmFzY3JpcHRcIiB9KSk7XG4gICAgICAgIGNvbnN0IG5hbWUgPSB0aGlzLl9hdWRpb1dvcmtsZXROYW1lKCk7XG4gICAgICAgIHRoaXMuX2R1bW15R2FpbiA9IHRoaXMuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIHRoaXMuX2R1bW15UGFyYW0gPSB0aGlzLl9kdW1teUdhaW4uZ2FpbjtcbiAgICAgICAgLy8gUmVnaXN0ZXIgdGhlIHByb2Nlc3NvclxuICAgICAgICB0aGlzLmNvbnRleHQuYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKGJsb2JVcmwsIG5hbWUpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgLy8gY3JlYXRlIHRoZSB3b3JrbGV0IHdoZW4gaXQncyByZWFkXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl93b3JrbGV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUF1ZGlvV29ya2xldE5vZGUobmFtZSwgdGhpcy53b3JrbGV0T3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldC5vbnByb2Nlc3NvcmVycm9yID0gdGhpcy5vbnByb2Nlc3NvcmVycm9yLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5vblJlYWR5KHRoaXMuX3dvcmtsZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kdW1teUdhaW4uZGlzY29ubmVjdCgpO1xuICAgICAgICBpZiAodGhpcy5fd29ya2xldCkge1xuICAgICAgICAgICAgdGhpcy5fd29ya2xldC5wb3J0LnBvc3RNZXNzYWdlKFwiZGlzcG9zZVwiKTtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb1dvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgYWRkVG9Xb3JrbGV0IH0gZnJvbSBcIi4vV29ya2xldEdsb2JhbFNjb3BlXCI7XG5jb25zdCB0b25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdC8qKlxuXHQgKiBUaGUgYmFzZSBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgZm9yIHVzZSBpbiBUb25lLmpzLiBXb3JrcyB3aXRoIHRoZSBbW1RvbmVBdWRpb1dvcmtsZXRdXS4gXG5cdCAqL1xuXHRjbGFzcyBUb25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtcblxuXHRcdGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcblx0XHRcdFxuXHRcdFx0c3VwZXIob3B0aW9ucyk7XG5cdFx0XHQvKipcblx0XHRcdCAqIElmIHRoZSBwcm9jZXNzb3Igd2FzIGRpc3Bvc2VkIG9yIG5vdC4gS2VlcCBhbGl2ZSB1bnRpbCBpdCdzIGRpc3Bvc2VkLlxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLmRpc3Bvc2VkID0gZmFsc2U7XG5cdFx0ICAgXHQvKiogXG5cdFx0XHQgKiBUaGUgbnVtYmVyIG9mIHNhbXBsZXMgaW4gdGhlIHByb2Nlc3NpbmcgYmxvY2tcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5ibG9ja1NpemUgPSAxMjg7XG5cdFx0XHQvKipcblx0XHRcdCAqIHRoZSBzYW1wbGUgcmF0ZVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuXG5cdFx0XHR0aGlzLnBvcnQub25tZXNzYWdlID0gKGV2ZW50KSA9PiB7XG5cdFx0XHRcdC8vIHdoZW4gaXQgcmVjZWl2ZXMgYSBkaXNwb3NlIFxuXHRcdFx0XHRpZiAoZXZlbnQuZGF0YSA9PT0gXCJkaXNwb3NlXCIpIHtcblx0XHRcdFx0XHR0aGlzLmRpc3Bvc2VkID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHR9XG5cdH1cbmA7XG5hZGRUb1dvcmtsZXQodG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IFwiLi9Ub25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLndvcmtsZXRcIjtcbmltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNvbnN0IHNpbmdsZUlPUHJvY2VzcyA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHQvKipcblx0ICogQWJzdHJhY3QgY2xhc3MgZm9yIGEgc2luZ2xlIGlucHV0L291dHB1dCBwcm9jZXNzb3IuIFxuXHQgKiBoYXMgYSAnZ2VuZXJhdGUnIGZ1bmN0aW9uIHdoaWNoIHByb2Nlc3NlcyBvbmUgc2FtcGxlIGF0IGEgdGltZVxuXHQgKi9cblx0Y2xhc3MgU2luZ2xlSU9Qcm9jZXNzb3IgZXh0ZW5kcyBUb25lQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtcblxuXHRcdGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcblx0XHRcdHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9ucywge1xuXHRcdFx0XHRudW1iZXJPZklucHV0czogMSxcblx0XHRcdFx0bnVtYmVyT2ZPdXRwdXRzOiAxXG5cdFx0XHR9KSk7XG5cdFx0XHQvKipcblx0XHRcdCAqIEhvbGRzIHRoZSBuYW1lIG9mIHRoZSBwYXJhbWV0ZXIgYW5kIGEgc2luZ2xlIHZhbHVlIG9mIHRoYXRcblx0XHRcdCAqIHBhcmFtZXRlciBhdCB0aGUgY3VycmVudCBzYW1wbGVcblx0XHRcdCAqIEB0eXBlIHsgW25hbWU6IHN0cmluZ106IG51bWJlciB9XG5cdFx0XHQgKi9cblx0XHRcdHRoaXMucGFyYW1zID0ge31cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBHZW5lcmF0ZSBhbiBvdXRwdXQgc2FtcGxlIGZyb20gdGhlIGlucHV0IHNhbXBsZSBhbmQgcGFyYW1ldGVyc1xuXHRcdCAqIEBhYnN0cmFjdFxuXHRcdCAqIEBwYXJhbSBpbnB1dCBudW1iZXJcblx0XHQgKiBAcGFyYW0gY2hhbm5lbCBudW1iZXJcblx0XHQgKiBAcGFyYW0gcGFyYW1ldGVycyB7IFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfVxuXHRcdCAqIEByZXR1cm5zIG51bWJlclxuXHRcdCAqL1xuXHRcdGdlbmVyYXRlKCl7fVxuXG5cdFx0LyoqXG5cdFx0ICogVXBkYXRlIHRoZSBwcml2YXRlIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUgXG5cdFx0ICogdmFsdWVzIG9mIHRoZSBwYXJhbWV0ZXJzIGF0IHRoZSBnaXZlbiBpbmRleFxuXHRcdCAqIEBwYXJhbSBwYXJhbWV0ZXJzIHsgW25hbWU6IHN0cmluZ106IEZsb2F0MzJBcnJheSB9LFxuXHRcdCAqIEBwYXJhbSBpbmRleCBudW1iZXJcblx0XHQgKi9cblx0XHR1cGRhdGVQYXJhbXMocGFyYW1ldGVycywgaW5kZXgpIHtcblx0XHRcdGZvciAoY29uc3QgcGFyYW1OYW1lIGluIHBhcmFtZXRlcnMpIHtcblx0XHRcdFx0Y29uc3QgcGFyYW0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV07XG5cdFx0XHRcdGlmIChwYXJhbS5sZW5ndGggPiAxKSB7XG5cdFx0XHRcdFx0dGhpcy5wYXJhbXNbcGFyYW1OYW1lXSA9IHBhcmFtZXRlcnNbcGFyYW1OYW1lXVtpbmRleF07XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy5wYXJhbXNbcGFyYW1OYW1lXSA9IHBhcmFtZXRlcnNbcGFyYW1OYW1lXVswXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIFByb2Nlc3MgYSBzaW5nbGUgZnJhbWUgb2YgdGhlIGF1ZGlvXG5cdFx0ICogQHBhcmFtIGlucHV0cyBGbG9hdDMyQXJyYXlbXVtdXG5cdFx0ICogQHBhcmFtIG91dHB1dHMgRmxvYXQzMkFycmF5W11bXVxuXHRcdCAqL1xuXHRcdHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRjb25zdCBpbnB1dCA9IGlucHV0c1swXTtcblx0XHRcdGNvbnN0IG91dHB1dCA9IG91dHB1dHNbMF07XG5cdFx0XHQvLyBnZXQgdGhlIHBhcmFtZXRlciB2YWx1ZXNcblx0XHRcdGNvbnN0IGNoYW5uZWxDb3VudCA9IE1hdGgubWF4KGlucHV0ICYmIGlucHV0Lmxlbmd0aCB8fCAwLCBvdXRwdXQubGVuZ3RoKTtcblx0XHRcdGZvciAobGV0IHNhbXBsZSA9IDA7IHNhbXBsZSA8IHRoaXMuYmxvY2tTaXplOyBzYW1wbGUrKykge1xuXHRcdFx0XHR0aGlzLnVwZGF0ZVBhcmFtcyhwYXJhbWV0ZXJzLCBzYW1wbGUpO1xuXHRcdFx0XHRmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IGNoYW5uZWxDb3VudDsgY2hhbm5lbCsrKSB7XG5cdFx0XHRcdFx0Y29uc3QgaW5wdXRTYW1wbGUgPSBpbnB1dCAmJiBpbnB1dC5sZW5ndGggPyBpbnB1dFtjaGFubmVsXVtzYW1wbGVdIDogMDtcblx0XHRcdFx0XHRvdXRwdXRbY2hhbm5lbF1bc2FtcGxlXSA9IHRoaXMuZ2VuZXJhdGUoaW5wdXRTYW1wbGUsIGNoYW5uZWwsIHRoaXMucGFyYW1zKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuICF0aGlzLmRpc3Bvc2VkO1xuXHRcdH1cblx0fTtcbmA7XG5hZGRUb1dvcmtsZXQoc2luZ2xlSU9Qcm9jZXNzKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNpbmdsZUlPUHJvY2Vzc29yLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgYWRkVG9Xb3JrbGV0IH0gZnJvbSBcIi4vV29ya2xldEdsb2JhbFNjb3BlXCI7XG5jb25zdCBkZWxheUxpbmUgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0LyoqXG5cdCAqIEEgbXVsdGljaGFubmVsIGJ1ZmZlciBmb3IgdXNlIHdpdGhpbiBhbiBBdWRpb1dvcmtsZXRQcm9jZXNzb3IgYXMgYSBkZWxheSBsaW5lXG5cdCAqL1xuXHRjbGFzcyBEZWxheUxpbmUge1xuXHRcdFxuXHRcdGNvbnN0cnVjdG9yKHNpemUsIGNoYW5uZWxzKSB7XG5cdFx0XHR0aGlzLmJ1ZmZlciA9IFtdO1xuXHRcdFx0dGhpcy53cml0ZUhlYWQgPSBbXVxuXHRcdFx0dGhpcy5zaXplID0gc2l6ZTtcblxuXHRcdFx0Ly8gY3JlYXRlIHRoZSBlbXB0eSBjaGFubmVsc1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsczsgaSsrKSB7XG5cdFx0XHRcdHRoaXMuYnVmZmVyW2ldID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLnNpemUpO1xuXHRcdFx0XHR0aGlzLndyaXRlSGVhZFtpXSA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogUHVzaCBhIHZhbHVlIG9udG8gdGhlIGVuZFxuXHRcdCAqIEBwYXJhbSBjaGFubmVsIG51bWJlclxuXHRcdCAqIEBwYXJhbSB2YWx1ZSBudW1iZXJcblx0XHQgKi9cblx0XHRwdXNoKGNoYW5uZWwsIHZhbHVlKSB7XG5cdFx0XHR0aGlzLndyaXRlSGVhZFtjaGFubmVsXSArPSAxO1xuXHRcdFx0aWYgKHRoaXMud3JpdGVIZWFkW2NoYW5uZWxdID4gdGhpcy5zaXplKSB7XG5cdFx0XHRcdHRoaXMud3JpdGVIZWFkW2NoYW5uZWxdID0gMDtcblx0XHRcdH1cblx0XHRcdHRoaXMuYnVmZmVyW2NoYW5uZWxdW3RoaXMud3JpdGVIZWFkW2NoYW5uZWxdXSA9IHZhbHVlO1xuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIEdldCB0aGUgcmVjb3JkZWQgdmFsdWUgb2YgdGhlIGNoYW5uZWwgZ2l2ZW4gdGhlIGRlbGF5XG5cdFx0ICogQHBhcmFtIGNoYW5uZWwgbnVtYmVyXG5cdFx0ICogQHBhcmFtIGRlbGF5IG51bWJlciBkZWxheSBzYW1wbGVzXG5cdFx0ICovXG5cdFx0Z2V0KGNoYW5uZWwsIGRlbGF5KSB7XG5cdFx0XHRsZXQgcmVhZEhlYWQgPSB0aGlzLndyaXRlSGVhZFtjaGFubmVsXSAtIE1hdGguZmxvb3IoZGVsYXkpO1xuXHRcdFx0aWYgKHJlYWRIZWFkIDwgMCkge1xuXHRcdFx0XHRyZWFkSGVhZCArPSB0aGlzLnNpemU7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdGhpcy5idWZmZXJbY2hhbm5lbF1bcmVhZEhlYWRdO1xuXHRcdH1cblx0fVxuYDtcbmFkZFRvV29ya2xldChkZWxheUxpbmUpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVsYXlMaW5lLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IFwiLi4vLi4vY29yZS93b3JrbGV0L1NpbmdsZUlPUHJvY2Vzc29yLndvcmtsZXRcIjtcbmltcG9ydCBcIi4uLy4uL2NvcmUvd29ya2xldC9EZWxheUxpbmUud29ya2xldFwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJQcm9jZXNzb3IgfSBmcm9tIFwiLi4vLi4vY29yZS93b3JrbGV0L1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNvbnN0IHdvcmtsZXROYW1lID0gXCJmZWVkYmFjay1jb21iLWZpbHRlclwiO1xuY29uc3QgZmVlZGJhY2tDb21iRmlsdGVyID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdGNsYXNzIEZlZWRiYWNrQ29tYkZpbHRlcldvcmtsZXQgZXh0ZW5kcyBTaW5nbGVJT1Byb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRzdXBlcihvcHRpb25zKTtcblx0XHRcdHRoaXMuZGVsYXlMaW5lID0gbmV3IERlbGF5TGluZSh0aGlzLnNhbXBsZVJhdGUsIG9wdGlvbnMuY2hhbm5lbENvdW50IHx8IDIpO1xuXHRcdH1cblxuXHRcdHN0YXRpYyBnZXQgcGFyYW1ldGVyRGVzY3JpcHRvcnMoKSB7XG5cdFx0XHRyZXR1cm4gW3tcblx0XHRcdFx0bmFtZTogXCJkZWxheVRpbWVcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAwLjEsXG5cdFx0XHRcdG1pblZhbHVlOiAwLFxuXHRcdFx0XHRtYXhWYWx1ZTogMSxcblx0XHRcdFx0YXV0b21hdGlvblJhdGU6IFwiay1yYXRlXCJcblx0XHRcdH0sIHtcblx0XHRcdFx0bmFtZTogXCJmZWVkYmFja1wiLFxuXHRcdFx0XHRkZWZhdWx0VmFsdWU6IDAuNSxcblx0XHRcdFx0bWluVmFsdWU6IDAsXG5cdFx0XHRcdG1heFZhbHVlOiAwLjk5OTksXG5cdFx0XHRcdGF1dG9tYXRpb25SYXRlOiBcImstcmF0ZVwiXG5cdFx0XHR9XTtcblx0XHR9XG5cblx0XHRnZW5lcmF0ZShpbnB1dCwgY2hhbm5lbCwgcGFyYW1ldGVycykge1xuXHRcdFx0Y29uc3QgZGVsYXllZFNhbXBsZSA9IHRoaXMuZGVsYXlMaW5lLmdldChjaGFubmVsLCBwYXJhbWV0ZXJzLmRlbGF5VGltZSAqIHRoaXMuc2FtcGxlUmF0ZSk7XG5cdFx0XHR0aGlzLmRlbGF5TGluZS5wdXNoKGNoYW5uZWwsIGlucHV0ICsgZGVsYXllZFNhbXBsZSAqIHBhcmFtZXRlcnMuZmVlZGJhY2spO1xuXHRcdFx0cmV0dXJuIGRlbGF5ZWRTYW1wbGU7XG5cdFx0fVxuXHR9XG5gO1xucmVnaXN0ZXJQcm9jZXNzb3Iod29ya2xldE5hbWUsIGZlZWRiYWNrQ29tYkZpbHRlcik7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0NvbWJGaWx0ZXIud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvV29ya2xldCB9IGZyb20gXCIuLi8uLi9jb3JlL3dvcmtsZXQvVG9uZUF1ZGlvV29ya2xldFwiO1xuaW1wb3J0IHsgd29ya2xldE5hbWUgfSBmcm9tIFwiLi9GZWVkYmFja0NvbWJGaWx0ZXIud29ya2xldFwiO1xuLyoqXG4gKiBDb21iIGZpbHRlcnMgYXJlIGJhc2ljIGJ1aWxkaW5nIGJsb2NrcyBmb3IgcGh5c2ljYWwgbW9kZWxpbmcuIFJlYWQgbW9yZVxuICogYWJvdXQgY29tYiBmaWx0ZXJzIG9uIFtDQ1JNQSdzIHdlYnNpdGVdKGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L35qb3MvcGFzcC9GZWVkYmFja19Db21iX0ZpbHRlcnMuaHRtbCkuXG4gKlxuICogVGhpcyBjb21iIGZpbHRlciBpcyBpbXBsZW1lbnRlZCB3aXRoIHRoZSBBdWRpb1dvcmtsZXROb2RlIHdoaWNoIGFsbG93cyBpdCB0byBoYXZlIGZlZWRiYWNrIGRlbGF5cyBsZXNzIHRoYW4gdGhlXG4gKiBXZWIgQXVkaW8gcHJvY2Vzc2luZyBibG9jayBvZiAxMjggc2FtcGxlcy4gVGhlcmUgaXMgYSBwb2x5ZmlsbCBmb3IgYnJvd3NlcnMgdGhhdCBkb24ndCB5ZXQgc3VwcG9ydCB0aGVcbiAqIEF1ZGlvV29ya2xldE5vZGUsIGJ1dCBpdCB3aWxsIGFkZCBzb21lIGxhdGVuY3kgYW5kIGhhdmUgc2xvd2VyIHBlcmZvcm1hbmNlIHRoYW4gdGhlIEF1ZGlvV29ya2xldE5vZGUuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0NvbWJGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Xb3JrbGV0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmVlZGJhY2tDb21iRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIG1pblZhbHVlOiAwLFxuICAgICAgICAgICAgbWF4VmFsdWU6IDEsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZHVtbXlQYXJhbSxcbiAgICAgICAgICAgIHN3YXBwYWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVzb25hbmNlID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnJlc29uYW5jZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZHVtbXlQYXJhbSxcbiAgICAgICAgICAgIHN3YXBwYWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInJlc29uYW5jZVwiLCBcImRlbGF5VGltZVwiXSk7XG4gICAgfVxuICAgIF9hdWRpb1dvcmtsZXROYW1lKCkge1xuICAgICAgICByZXR1cm4gd29ya2xldE5hbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IHBhcmFtZXRlcnNcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLjEsXG4gICAgICAgICAgICByZXNvbmFuY2U6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG9uUmVhZHkobm9kZSkge1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIG5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29uc3QgZGVsYXlUaW1lID0gbm9kZS5wYXJhbWV0ZXJzLmdldChcImRlbGF5VGltZVwiKTtcbiAgICAgICAgO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5zZXRQYXJhbShkZWxheVRpbWUpO1xuICAgICAgICBjb25zdCBmZWVkYmFjayA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJmZWVkYmFja1wiKTtcbiAgICAgICAgO1xuICAgICAgICB0aGlzLnJlc29uYW5jZS5zZXRQYXJhbShmZWVkYmFjayk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnJlc29uYW5jZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZlZWRiYWNrQ29tYkZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbi8qKlxuICogQSBvbmUgcG9sZSBmaWx0ZXIgd2l0aCA2ZGItcGVyLW9jdGF2ZSByb2xsb2ZmLiBFaXRoZXIgXCJoaWdocGFzc1wiIG9yIFwibG93cGFzc1wiLlxuICogTm90ZSB0aGF0IGNoYW5naW5nIHRoZSB0eXBlIG9yIGZyZXF1ZW5jeSBtYXkgcmVzdWx0IGluIGEgZGlzY29udGludWl0eSB3aGljaFxuICogY2FuIHNvdW5kIGxpa2UgYSBjbGljayBvciBwb3AuXG4gKiBSZWZlcmVuY2VzOlxuICogKiBodHRwOi8vd3d3LmVhcmxldmVsLmNvbS9tYWluLzIwMTIvMTIvMTUvYS1vbmUtcG9sZS1maWx0ZXIvXG4gKiAqIGh0dHA6Ly93d3cuZHNwZ3VpZGUuY29tL2NoMTkvMi5odG1cbiAqICogaHR0cHM6Ly9naXRodWIuY29tL3ZpdGFsaXktYm9icm92L2pzLXJvY2tzL2Jsb2IvbWFzdGVyL3NyYy9hcHAvYXVkaW8vZWZmZWN0cy9vbmUtcG9sZS1maWx0ZXJzLnRzXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBPbmVQb2xlRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE9uZVBvbGVGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT25lUG9sZUZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT25lUG9sZUZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBvcHRpb25zLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9jcmVhdGVGaWx0ZXIoKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogODgwLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIGZpbHRlciBhbmQgZGlzcG9zZSB0aGUgb2xkIG9uZVxuICAgICAqL1xuICAgIF9jcmVhdGVGaWx0ZXIoKSB7XG4gICAgICAgIGNvbnN0IG9sZEZpbHRlciA9IHRoaXMuX2ZpbHRlcjtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3kodGhpcy5fZnJlcXVlbmN5KTtcbiAgICAgICAgY29uc3QgdCA9IDEgLyAoMiAqIE1hdGguUEkgKiBmcmVxKTtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgPT09IFwibG93cGFzc1wiKSB7XG4gICAgICAgICAgICBjb25zdCBhMCA9IDEgLyAodCAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIGNvbnN0IGIxID0gYTAgLSAxO1xuICAgICAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihbYTAsIDBdLCBbMSwgYjFdKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGIxID0gMSAvICh0ICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpIC0gMTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoWzEsIC0xXSwgWzEsIGIxXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9maWx0ZXIsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgaWYgKG9sZEZpbHRlcikge1xuICAgICAgICAgICAgLy8gZGlzcG9zZSBpdCBvbiB0aGUgbmV4dCBibG9ja1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5kaXNwb3NlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3Qob2xkRmlsdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgb2xkRmlsdGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCB0aGlzLmJsb2NrVGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZyZXF1ZW5jeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgZnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgZnJlcXVlbmN5KGZxKSB7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGZxO1xuICAgICAgICB0aGlzLl9jcmVhdGVGaWx0ZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIE9uZVBvbGUgRmlsdGVyIHR5cGUsIGVpdGhlciBcImhpZ2hwYXNzXCIgb3IgXCJsb3dwYXNzXCJcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHQpIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHQ7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUZpbHRlcigpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZS4gVGhpcyBjdXJ2ZSByZXByZXNlbnRzIGhvdyB0aGUgZmlsdGVyXG4gICAgICogcmVzcG9uc2VzIHRvIGZyZXF1ZW5jaWVzIGJldHdlZW4gMjBoei0yMGtoei5cbiAgICAgKiBAcGFyYW0gIGxlbiBUaGUgbnVtYmVyIG9mIHZhbHVlcyB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUgYmV0d2VlbiAyMC0yMGtIelxuICAgICAqL1xuICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGxlbiA9IDEyOCkge1xuICAgICAgICBjb25zdCBmcmVxVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBub3JtID0gTWF0aC5wb3coaSAvIGxlbiwgMik7XG4gICAgICAgICAgICBjb25zdCBmcmVxID0gbm9ybSAqICgyMDAwMCAtIDIwKSArIDIwO1xuICAgICAgICAgICAgZnJlcVZhbHVlc1tpXSA9IGZyZXE7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWFnVmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShsZW4pO1xuICAgICAgICBjb25zdCBwaGFzZVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXFWYWx1ZXMsIG1hZ1ZhbHVlcywgcGhhc2VWYWx1ZXMpO1xuICAgICAgICByZXR1cm4gbWFnVmFsdWVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU9uZVBvbGVGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBGZWVkYmFja0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi9GZWVkYmFja0NvbWJGaWx0ZXJcIjtcbmltcG9ydCB7IE9uZVBvbGVGaWx0ZXIgfSBmcm9tIFwiLi9PbmVQb2xlRmlsdGVyXCI7XG4vKipcbiAqIEEgbG93cGFzcyBmZWVkYmFjayBjb21iIGZpbHRlci4gSXQgaXMgc2ltaWxhciB0b1xuICogW1tGZWVkYmFja0NvbWJGaWx0ZXJdXSwgYnV0IGluY2x1ZGVzIGEgbG93cGFzcyBmaWx0ZXIuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBMb3dwYXNzQ29tYkZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhMb3dwYXNzQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiLCBcImRhbXBlbmluZ1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxvd3Bhc3NDb21iRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMb3dwYXNzQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiLCBcImRhbXBlbmluZ1wiXSk7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXIgPSB0aGlzLm91dHB1dCA9IG5ldyBGZWVkYmFja0NvbWJGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogb3B0aW9ucy5yZXNvbmFuY2UsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IHRoaXMuX2NvbWJGaWx0ZXIuZGVsYXlUaW1lO1xuICAgICAgICB0aGlzLnJlc29uYW5jZSA9IHRoaXMuX2NvbWJGaWx0ZXIucmVzb25hbmNlO1xuICAgICAgICB0aGlzLl9sb3dwYXNzID0gdGhpcy5pbnB1dCA9IG5ldyBPbmVQb2xlRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuY29ubmVjdCh0aGlzLl9jb21iRmlsdGVyKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRhbXBlbmluZzogMzAwMCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMC4xLFxuICAgICAgICAgICAgcmVzb25hbmNlOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGFtcGVuaW5nIGNvbnRyb2wgb2YgdGhlIGZlZWRiYWNrXG4gICAgICovXG4gICAgZ2V0IGRhbXBlbmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvd3Bhc3MuZnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgZGFtcGVuaW5nKGZxKSB7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuZnJlcXVlbmN5ID0gZnE7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Mb3dwYXNzQ29tYkZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBMb3dwYXNzQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5vaXNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Ob2lzZVwiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuL0luc3RydW1lbnRcIjtcbi8qKlxuICogS2FycGx1cy1TdHJpbmcgc3RyaW5nIHN5bnRoZXNpcy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwbHVja3kgPSBuZXcgVG9uZS5QbHVja1N5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDNFwiLCBcIiswLjVcIik7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkMzXCIsIFwiKzFcIik7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkMyXCIsIFwiKzEuNVwiKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzFcIiwgXCIrMlwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQbHVja1N5bnRoIGV4dGVuZHMgSW5zdHJ1bWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsdWNrU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGx1Y2tTeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGx1Y2tTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9ub2lzZSA9IG5ldyBOb2lzZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInBpbmtcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5hdHRhY2tOb2lzZSA9IG9wdGlvbnMuYXR0YWNrTm9pc2U7XG4gICAgICAgIHRoaXMuX2xmY2YgPSBuZXcgTG93cGFzc0NvbWJGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGFtcGVuaW5nOiBvcHRpb25zLmRhbXBlbmluZyxcbiAgICAgICAgICAgIHJlc29uYW5jZTogb3B0aW9ucy5yZXNvbmFuY2UsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlc29uYW5jZSA9IG9wdGlvbnMucmVzb25hbmNlO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBvcHRpb25zLnJlbGVhc2U7XG4gICAgICAgIHRoaXMuX25vaXNlLmNvbm5lY3QodGhpcy5fbGZjZik7XG4gICAgICAgIHRoaXMuX2xmY2YuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIGRlZXBNZXJnZShJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF0dGFja05vaXNlOiAxLFxuICAgICAgICAgICAgZGFtcGVuaW5nOiA0MDAwLFxuICAgICAgICAgICAgcmVzb25hbmNlOiAwLjcsXG4gICAgICAgICAgICByZWxlYXNlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRhbXBlbmluZyBjb250cm9sLiBpLmUuIHRoZSBsb3dwYXNzIGZpbHRlciBmcmVxdWVuY3kgb2YgdGhlIGNvbWIgZmlsdGVyXG4gICAgICogQG1pbiAwXG4gICAgICogQG1heCA3MDAwXG4gICAgICovXG4gICAgZ2V0IGRhbXBlbmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmY2YuZGFtcGVuaW5nO1xuICAgIH1cbiAgICBzZXQgZGFtcGVuaW5nKGZxKSB7XG4gICAgICAgIHRoaXMuX2xmY2YuZGFtcGVuaW5nID0gZnE7XG4gICAgfVxuICAgIHRyaWdnZXJBdHRhY2sobm90ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeShub3RlKTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBkZWxheUFtb3VudCA9IDEgLyBmcmVxO1xuICAgICAgICB0aGlzLl9sZmNmLmRlbGF5VGltZS5zZXRWYWx1ZUF0VGltZShkZWxheUFtb3VudCwgdGltZSk7XG4gICAgICAgIHRoaXMuX25vaXNlLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9ub2lzZS5zdG9wKHRpbWUgKyBkZWxheUFtb3VudCAqIHRoaXMuYXR0YWNrTm9pc2UpO1xuICAgICAgICB0aGlzLl9sZmNmLnJlc29uYW5jZS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgIHRoaXMuX2xmY2YucmVzb25hbmNlLnNldFZhbHVlQXRUaW1lKHRoaXMucmVzb25hbmNlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJhbXAgZG93biB0aGUgW1tyZXNvbmFuY2VdXSB0byAwIG92ZXIgdGhlIGR1cmF0aW9uIG9mIHRoZSByZWxlYXNlIHRpbWUuXG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLl9sZmNmLnJlc29uYW5jZS5saW5lYXJSYW1wVG8oMCwgdGhpcy5yZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbm9pc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZmNmLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGx1Y2tTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBNaWRpQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL01pZGlcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNOdW1iZXIgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuL0luc3RydW1lbnRcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IGFzc2VydCwgd2FybiB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogUG9seVN5bnRoIGhhbmRsZXMgdm9pY2UgY3JlYXRpb24gYW5kIGFsbG9jYXRpb24gZm9yIGFueVxuICogaW5zdHJ1bWVudHMgcGFzc2VkIGluIGFzIHRoZSBzZWNvbmQgcGFyYW10ZXIuIFBvbHlTeW50aCBpc1xuICogbm90IGEgc3ludGhlc2l6ZXIgYnkgaXRzZWxmLCBpdCBtZXJlbHkgbWFuYWdlcyB2b2ljZXMgb2ZcbiAqIG9uZSBvZiB0aGUgb3RoZXIgdHlwZXMgb2Ygc3ludGhzLCBhbGxvd2luZyBhbnkgb2YgdGhlXG4gKiBtb25vcGhvbmljIHN5bnRoZXNpemVycyB0byBiZSBwb2x5cGhvbmljLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHNldCB0aGUgYXR0cmlidXRlcyBhY3Jvc3MgYWxsIHRoZSB2b2ljZXMgdXNpbmcgJ3NldCdcbiAqIHN5bnRoLnNldCh7IGRldHVuZTogLTEyMDAgfSk7XG4gKiAvLyBwbGF5IGEgY2hvcmRcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkM0XCIsIFwiRTRcIiwgXCJBNFwiXSwgMSk7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgUG9seVN5bnRoIGV4dGVuZHMgSW5zdHJ1bWVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvbHlTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvaWNlXCIsIFwib3B0aW9uc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBvbHlTeW50aFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHZvaWNlcyB3aGljaCBhcmUgbm90IGN1cnJlbnRseSBpbiB1c2VcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZVZvaWNlcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGN1cnJlbnRseSBhY3RpdmUgdm9pY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgYWxsb2NhdGVkIHZvaWNlcyBmb3IgdGhpcyBzeW50aC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3ZvaWNlcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEdDIHRpbWVvdXQuIEhlbGQgc28gdGhhdCBpdCBjb3VsZCBiZSBjYW5jZWxsZWQgd2hlbiB0aGUgbm9kZSBpcyBkaXNwb3NlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2djVGltZW91dCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBtb3ZpbmcgYXZlcmFnZSBvZiB0aGUgbnVtYmVyIG9mIGFjdGl2ZSB2b2ljZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUG9seVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9pY2VcIiwgXCJvcHRpb25zXCJdKTtcbiAgICAgICAgLy8gY2hlY2sgYWdhaW5zdCB0aGUgb2xkIEFQSSAocHJlIDE0LjMuMClcbiAgICAgICAgYXNzZXJ0KCFpc051bWJlcihvcHRpb25zLnZvaWNlKSwgXCJERVBSRUNBVEVEOiBUaGUgcG9seXBob255IGNvdW50IGlzIG5vIGxvbmdlciB0aGUgZmlyc3QgYXJndW1lbnQuXCIpO1xuICAgICAgICBjb25zdCBkZWZhdWx0cyA9IG9wdGlvbnMudm9pY2UuZ2V0RGVmYXVsdHMoKTtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gT2JqZWN0LmFzc2lnbihkZWZhdWx0cywgb3B0aW9ucy5vcHRpb25zKTtcbiAgICAgICAgdGhpcy52b2ljZSA9IG9wdGlvbnMudm9pY2U7XG4gICAgICAgIHRoaXMubWF4UG9seXBob255ID0gb3B0aW9ucy5tYXhQb2x5cGhvbnk7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgZmlyc3Qgdm9pY2VcbiAgICAgICAgdGhpcy5fZHVtbXlWb2ljZSA9IHRoaXMuX2dldE5leHRBdmFpbGFibGVWb2ljZSgpO1xuICAgICAgICAvLyByZW1vdmUgaXQgZnJvbSB0aGUgdm9pY2VzIGxpc3RcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl92b2ljZXMuaW5kZXhPZih0aGlzLl9kdW1teVZvaWNlKTtcbiAgICAgICAgdGhpcy5fdm9pY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgIC8vIGtpY2sgb2ZmIHRoZSBHQyBpbnRlcnZhbFxuICAgICAgICB0aGlzLl9nY1RpbWVvdXQgPSB0aGlzLmNvbnRleHQuc2V0SW50ZXJ2YWwodGhpcy5fY29sbGVjdEdhcmJhZ2UuYmluZCh0aGlzKSwgMSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtYXhQb2x5cGhvbnk6IDMyLFxuICAgICAgICAgICAgb3B0aW9uczoge30sXG4gICAgICAgICAgICB2b2ljZTogU3ludGgsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGFjdGl2ZSB2b2ljZXMuXG4gICAgICovXG4gICAgZ2V0IGFjdGl2ZVZvaWNlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZVZvaWNlcy5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZWQgd2hlbiB0aGUgc291cmNlIGlzIGRvbmUgbWFraW5nIHNvdW5kLCBzbyB0aGF0IGl0IGNhbiBiZVxuICAgICAqIHJlYWRkZWQgdG8gdGhlIHBvb2wgb2YgYXZhaWxhYmxlIHZvaWNlc1xuICAgICAqL1xuICAgIF9tYWtlVm9pY2VBdmFpbGFibGUodm9pY2UpIHtcbiAgICAgICAgdGhpcy5fYXZhaWxhYmxlVm9pY2VzLnB1c2godm9pY2UpO1xuICAgICAgICAvLyByZW1vdmUgdGhlIG1pZGkgbm90ZSBmcm9tICdhY3RpdmUgdm9pY2VzJ1xuICAgICAgICBjb25zdCBhY3RpdmVWb2ljZUluZGV4ID0gdGhpcy5fYWN0aXZlVm9pY2VzLmZpbmRJbmRleCgoZSkgPT4gZS52b2ljZSA9PT0gdm9pY2UpO1xuICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMuc3BsaWNlKGFjdGl2ZVZvaWNlSW5kZXgsIDEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYW4gYXZhaWxhYmxlIHZvaWNlIGZyb20gdGhlIHBvb2wgb2YgYXZhaWxhYmxlIHZvaWNlcy5cbiAgICAgKiBJZiBvbmUgaXMgbm90IGF2YWlsYWJsZSBhbmQgdGhlIG1heFBvbHlwaG9ueSBsaW1pdCBpcyByZWFjaGVkLFxuICAgICAqIHN0ZWFsIGEgdm9pY2UsIG90aGVyd2lzZSByZXR1cm4gbnVsbC5cbiAgICAgKi9cbiAgICBfZ2V0TmV4dEF2YWlsYWJsZVZvaWNlKCkge1xuICAgICAgICAvLyBpZiB0aGVyZSBhcmUgYXZhaWxhYmxlIHZvaWNlcywgcmV0dXJuIHRoZSBmaXJzdCBvbmVcbiAgICAgICAgaWYgKHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdmFpbGFibGVWb2ljZXMuc2hpZnQoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl92b2ljZXMubGVuZ3RoIDwgdGhpcy5tYXhQb2x5cGhvbnkpIHtcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSBpZiB0aGVyZSBpcyBzdGlsbCBtb3JlIG1heFBvbHlwaG9ueSwgbWFrZSBhIG5ldyB2b2ljZVxuICAgICAgICAgICAgY29uc3Qgdm9pY2UgPSBuZXcgdGhpcy52b2ljZShPYmplY3QuYXNzaWduKHRoaXMub3B0aW9ucywge1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBvbnNpbGVuY2U6IHRoaXMuX21ha2VWb2ljZUF2YWlsYWJsZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgdm9pY2UuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICB0aGlzLl92b2ljZXMucHVzaCh2b2ljZSk7XG4gICAgICAgICAgICByZXR1cm4gdm9pY2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3YXJuKFwiTWF4IHBvbHlwaG9ueSBleGNlZWRlZC4gTm90ZSBkcm9wcGVkLlwiKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBPY2Nhc2lvbmFsbHkgY2hlY2sgaWYgdGhlcmUgYXJlIGFueSBhbGxvY2F0ZWQgdm9pY2VzIHdoaWNoIGNhbiBiZSBjbGVhbmVkIHVwLlxuICAgICAqL1xuICAgIF9jb2xsZWN0R2FyYmFnZSgpIHtcbiAgICAgICAgdGhpcy5fYXZlcmFnZUFjdGl2ZVZvaWNlcyA9IE1hdGgubWF4KHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgKiAwLjk1LCB0aGlzLmFjdGl2ZVZvaWNlcyk7XG4gICAgICAgIGlmICh0aGlzLl9hdmFpbGFibGVWb2ljZXMubGVuZ3RoICYmIHRoaXMuX3ZvaWNlcy5sZW5ndGggPiBNYXRoLmNlaWwodGhpcy5fYXZlcmFnZUFjdGl2ZVZvaWNlcyArIDEpKSB7XG4gICAgICAgICAgICAvLyB0YWtlIG9mZiBhbiBhdmFpbGFibGUgbm90ZVxuICAgICAgICAgICAgY29uc3QgZmlyc3RBdmFpbCA9IHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5zaGlmdCgpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl92b2ljZXMuaW5kZXhPZihmaXJzdEF2YWlsKTtcbiAgICAgICAgICAgIHRoaXMuX3ZvaWNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbnRleHQuaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgZmlyc3RBdmFpbC5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgbWV0aG9kIHdoaWNoIHRyaWdnZXJzIHRoZSBhdHRhY2tcbiAgICAgKi9cbiAgICBfdHJpZ2dlckF0dGFjayhub3RlcywgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgbm90ZXMuZm9yRWFjaChub3RlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1pZGlOb3RlID0gbmV3IE1pZGlDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgY29uc3Qgdm9pY2UgPSB0aGlzLl9nZXROZXh0QXZhaWxhYmxlVm9pY2UoKTtcbiAgICAgICAgICAgIGlmICh2b2ljZSkge1xuICAgICAgICAgICAgICAgIHZvaWNlLnRyaWdnZXJBdHRhY2sobm90ZSwgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgbWlkaTogbWlkaU5vdGUsIHZvaWNlLCByZWxlYXNlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIG5vdGUsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgbWV0aG9kIHdoaWNoIHRyaWdnZXJzIHRoZSByZWxlYXNlXG4gICAgICovXG4gICAgX3RyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKSB7XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpTm90ZSA9IG5ldyBNaWRpQ2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fYWN0aXZlVm9pY2VzLmZpbmQoKHsgbWlkaSwgcmVsZWFzZWQgfSkgPT4gbWlkaSA9PT0gbWlkaU5vdGUgJiYgIXJlbGVhc2VkKTtcbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIC8vIHRyaWdnZXIgcmVsZWFzZSBvbiB0aGF0IG5vdGVcbiAgICAgICAgICAgICAgICBldmVudC52b2ljZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgICAgICAgICAvLyBtYXJrIGl0IGFzIHJlbGVhc2VkXG4gICAgICAgICAgICAgICAgZXZlbnQucmVsZWFzZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nKFwidHJpZ2dlclJlbGVhc2VcIiwgbm90ZSwgdGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSB0aGUgYXR0YWNrL3JlbGVhc2UgZXZlbnRzLiBJZiB0aGUgdGltZSBpcyBpbiB0aGUgZnV0dXJlLCB0aGVuIGl0IHNob3VsZCBzZXQgYSB0aW1lb3V0XG4gICAgICogdG8gd2FpdCBmb3IganVzdC1pbi10aW1lIHNjaGVkdWxpbmdcbiAgICAgKi9cbiAgICBfc2NoZWR1bGVFdmVudCh0eXBlLCBub3RlcywgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLmRpc3Bvc2VkLCBcIlN5bnRoIHdhcyBhbHJlYWR5IGRpc3Bvc2VkXCIpO1xuICAgICAgICAvLyBpZiB0aGUgbm90ZXMgYXJlIGdyZWF0ZXIgdGhhbiB0aGlzIGFtb3VudCBvZiB0aW1lIGluIHRoZSBmdXR1cmUsIHRoZXkgc2hvdWxkIGJlIHNjaGVkdWxlZCB3aXRoIHNldFRpbWVvdXRcbiAgICAgICAgaWYgKHRpbWUgPD0gdGhpcy5ub3coKSkge1xuICAgICAgICAgICAgLy8gZG8gaXQgaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIGlmICh0eXBlID09PSBcImF0dGFja1wiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlckF0dGFjayhub3RlcywgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gc2NoZWR1bGUgaXQgdG8gc3RhcnQgaW4gdGhlIGZ1dHVyZVxuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlRXZlbnQodHlwZSwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgIH0sIHRpbWUgLSB0aGlzLm5vdygpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSBhdHRhY2sgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqIEBwYXJhbSAgbm90ZXMgVGhlIG5vdGVzIHRvIHBsYXkuIEFjY2VwdHMgYSBzaW5nbGUgRnJlcXVlbmN5IG9yIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHN0YXJ0IHRpbWUgb2YgdGhlIG5vdGUuXG4gICAgICogQHBhcmFtIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKFRvbmUuRk1TeW50aCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgYSBjaG9yZCBpbW1lZGlhdGVseSB3aXRoIGEgdmVsb2NpdHkgb2YgMC4yXG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhbXCJBYjNcIiwgXCJDNFwiLCBcIkY1XCJdLCBUb25lLm5vdygpLCAwLjIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShub3RlcykpIHtcbiAgICAgICAgICAgIG5vdGVzID0gW25vdGVzXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVFdmVudChcImF0dGFja1wiLCBub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyIHRoZSByZWxlYXNlIG9mIHRoZSBub3RlLiBVbmxpa2UgbW9ub3Bob25pYyBpbnN0cnVtZW50cyxcbiAgICAgKiBhIG5vdGUgKG9yIGFycmF5IG9mIG5vdGVzKSBuZWVkcyB0byBiZSBwYXNzZWQgaW4gYXMgdGhlIGZpcnN0IGFyZ3VtZW50LlxuICAgICAqIEBwYXJhbSAgbm90ZXMgVGhlIG5vdGVzIHRvIHBsYXkuIEFjY2VwdHMgYSBzaW5nbGUgRnJlcXVlbmN5IG9yIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0aGUgcmVsZWFzZSB3aWxsIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcG9seSA9IG5ldyBUb25lLlBvbHlTeW50aChUb25lLkFNU3ludGgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwb2x5LnRyaWdnZXJBdHRhY2soW1wiQWIzXCIsIFwiQzRcIiwgXCJGNVwiXSk7XG4gICAgICogLy8gdHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgZ2l2ZW4gbm90ZXMuXG4gICAgICogcG9seS50cmlnZ2VyUmVsZWFzZShbXCJBYjNcIiwgXCJDNFwiXSwgXCIrMVwiKTtcbiAgICAgKiBwb2x5LnRyaWdnZXJSZWxlYXNlKFwiRjVcIiwgXCIrM1wiKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG4gICAgICAgICAgICBub3RlcyA9IFtub3Rlc107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlRXZlbnQoXCJyZWxlYXNlXCIsIG5vdGVzLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIGFuZCByZWxlYXNlIGFmdGVyIHRoZSBzcGVjaWZpZWQgZHVyYXRpb25cbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlICBGcmVxdWVuY3kgb3IgYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiB0aGUgZHVyYXRpb24gb2YgdGhlIG5vdGVcbiAgICAgKiBAcGFyYW0gIHRpbWUgIGlmIG5vIHRpbWUgaXMgZ2l2ZW4sIGRlZmF1bHRzIHRvIG5vd1xuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgdGhlIHZlbG9jaXR5IG9mIHRoZSBhdHRhY2sgKDAtMSlcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoVG9uZS5BTVN5bnRoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gY2FuIHBhc3MgaW4gYW4gYXJyYXkgb2YgZHVyYXRpb25zIGFzIHdlbGxcbiAgICAgKiBwb2x5LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkViM1wiLCBcIkc0XCIsIFwiQmI0XCIsIFwiRDVcIl0sIFs0LCAzLCAyLCAxXSk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZXMsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKG5vdGVzLCBjb21wdXRlZFRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgaWYgKGlzQXJyYXkoZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBhc3NlcnQoaXNBcnJheShub3RlcyksIFwiSWYgdGhlIGR1cmF0aW9uIGlzIGFuIGFycmF5LCB0aGUgbm90ZXMgbXVzdCBhbHNvIGJlIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgbm90ZXMgPSBub3RlcztcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm90ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBkID0gZHVyYXRpb25bTWF0aC5taW4oaSwgZHVyYXRpb24ubGVuZ3RoIC0gMSldO1xuICAgICAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uU2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKGQpO1xuICAgICAgICAgICAgICAgIGFzc2VydChkdXJhdGlvblNlY29uZHMgPiAwLCBcIlRoZSBkdXJhdGlvbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZXNbaV0sIGNvbXB1dGVkVGltZSArIGR1cmF0aW9uU2Vjb25kcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBkdXJhdGlvblNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgICAgICBhc3NlcnQoZHVyYXRpb25TZWNvbmRzID4gMCwgXCJUaGUgZHVyYXRpb24gbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZXMsIGNvbXB1dGVkVGltZSArIGR1cmF0aW9uU2Vjb25kcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jU3RhdGUoKSkge1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJBdHRhY2tcIiwgMSk7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlclJlbGVhc2VcIiwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCBhIG1lbWJlci9hdHRyaWJ1dGUgb2YgdGhlIHZvaWNlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcG9seSA9IG5ldyBUb25lLlBvbHlTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzZXQgYWxsIG9mIHRoZSB2b2ljZXMgdXNpbmcgYW4gb3B0aW9ucyBvYmplY3QgZm9yIHRoZSBzeW50aCB0eXBlXG4gICAgICogcG9seS5zZXQoe1xuICAgICAqIFx0ZW52ZWxvcGU6IHtcbiAgICAgKiBcdFx0YXR0YWNrOiAwLjI1XG4gICAgICogXHR9XG4gICAgICogfSk7XG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkJiM1wiLCAwLjIpO1xuICAgICAqL1xuICAgIHNldChvcHRpb25zKSB7XG4gICAgICAgIC8vIHJlbW92ZSBvcHRpb25zIHdoaWNoIGFyZSBjb250cm9sbGVkIGJ5IHRoZSBQb2x5U3ludGhcbiAgICAgICAgY29uc3Qgc2FuaXRpemVkT3B0aW9ucyA9IG9taXRGcm9tT2JqZWN0KG9wdGlvbnMsIFtcIm9uc2lsZW5jZVwiLCBcImNvbnRleHRcIl0pO1xuICAgICAgICAvLyBzdG9yZSBhbGwgb2YgdGhlIG9wdGlvbnNcbiAgICAgICAgdGhpcy5vcHRpb25zID0gZGVlcE1lcmdlKHRoaXMub3B0aW9ucywgc2FuaXRpemVkT3B0aW9ucyk7XG4gICAgICAgIHRoaXMuX3ZvaWNlcy5mb3JFYWNoKHZvaWNlID0+IHZvaWNlLnNldChzYW5pdGl6ZWRPcHRpb25zKSk7XG4gICAgICAgIHRoaXMuX2R1bW15Vm9pY2Uuc2V0KHNhbml0aXplZE9wdGlvbnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZHVtbXlWb2ljZS5nZXQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIGFsbCB0aGUgY3VycmVudGx5IGFjdGl2ZSB2b2ljZXMgaW1tZWRpYXRlbHkuXG4gICAgICogVXNlZnVsIGZvciBzaWxlbmNpbmcgdGhlIHN5bnRoLlxuICAgICAqL1xuICAgIHJlbGVhc2VBbGwodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzLmZvckVhY2goKHsgdm9pY2UgfSkgPT4ge1xuICAgICAgICAgICAgdm9pY2UudHJpZ2dlclJlbGVhc2UoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2R1bW15Vm9pY2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2ljZXMuZm9yRWFjaCh2ID0+IHYuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzID0gW107XG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZVZvaWNlcyA9IFtdO1xuICAgICAgICB0aGlzLmNvbnRleHQuY2xlYXJJbnRlcnZhbCh0aGlzLl9nY1RpbWVvdXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Qb2x5U3ludGguanMubWFwIiwiaW1wb3J0IHsgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuaW1wb3J0IHsgZnRvbWYsIGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9GcmVxdWVuY3lcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc05vdGUsIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi4vaW5zdHJ1bWVudC9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9idWZmZXIvVG9uZUJ1ZmZlclNvdXJjZVwiO1xuaW1wb3J0IHsgdGltZVJhbmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWNvcmF0b3JcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogUGFzcyBpbiBhbiBvYmplY3Qgd2hpY2ggbWFwcyB0aGUgbm90ZSdzIHBpdGNoIG9yIG1pZGkgdmFsdWUgdG8gdGhlIHVybCxcbiAqIHRoZW4geW91IGNhbiB0cmlnZ2VyIHRoZSBhdHRhY2sgYW5kIHJlbGVhc2Ugb2YgdGhhdCBub3RlIGxpa2Ugb3RoZXIgaW5zdHJ1bWVudHMuXG4gKiBCeSBhdXRvbWF0aWNhbGx5IHJlcGl0Y2hpbmcgdGhlIHNhbXBsZXMsIGl0IGlzIHBvc3NpYmxlIHRvIHBsYXkgcGl0Y2hlcyB3aGljaFxuICogd2VyZSBub3QgZXhwbGljaXRseSBpbmNsdWRlZCB3aGljaCBjYW4gc2F2ZSBsb2FkaW5nIHRpbWUuXG4gKlxuICogRm9yIHNhbXBsZSBvciBidWZmZXIgcGxheWJhY2sgd2hlcmUgcmVwaXRjaGluZyBpcyBub3QgbmVjZXNzYXJ5LFxuICogdXNlIFtbUGxheWVyXV0uXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc2FtcGxlciA9IG5ldyBUb25lLlNhbXBsZXIoe1xuICogXHR1cmxzOiB7XG4gKiBcdFx0QTE6IFwiQTEubXAzXCIsXG4gKiBcdFx0QTI6IFwiQTIubXAzXCIsXG4gKiBcdH0sXG4gKiBcdGJhc2VVcmw6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL1wiLFxuICogXHRvbmxvYWQ6ICgpID0+IHtcbiAqIFx0XHRzYW1wbGVyLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkMxXCIsIFwiRTFcIiwgXCJHMVwiLCBcIkIxXCJdLCAwLjUpO1xuICogXHR9XG4gKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgU2FtcGxlciBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTYW1wbGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2FtcGxlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9iamVjdCBvZiBhbGwgY3VycmVudGx5IHBsYXlpbmcgQnVmZmVyU291cmNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNhbXBsZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCIsIFwiYmFzZVVybFwiXSwgXCJ1cmxzXCIpO1xuICAgICAgICBjb25zdCB1cmxNYXAgPSB7fTtcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucy51cmxzKS5mb3JFYWNoKChub3RlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3RlTnVtYmVyID0gcGFyc2VJbnQobm90ZSwgMTApO1xuICAgICAgICAgICAgYXNzZXJ0KGlzTm90ZShub3RlKVxuICAgICAgICAgICAgICAgIHx8IChpc051bWJlcihub3RlTnVtYmVyKSAmJiBpc0Zpbml0ZShub3RlTnVtYmVyKSksIGB1cmwga2V5IGlzIG5laXRoZXIgYSBub3RlIG9yIG1pZGkgcGl0Y2g6ICR7bm90ZX1gKTtcbiAgICAgICAgICAgIGlmIChpc05vdGUobm90ZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBjb252ZXJ0IHRoZSBub3RlIG5hbWUgdG8gTUlESVxuICAgICAgICAgICAgICAgIGNvbnN0IG1pZCA9IG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgICAgIHVybE1hcFttaWRdID0gb3B0aW9ucy51cmxzW25vdGVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNOdW1iZXIobm90ZU51bWJlcikgJiYgaXNGaW5pdGUobm90ZU51bWJlcikpIHtcbiAgICAgICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgaXQncyBudW1iZXJzIGFzc3VtZSBpdCdzIG1pZGlcbiAgICAgICAgICAgICAgICB1cmxNYXBbbm90ZU51bWJlcl0gPSBvcHRpb25zLnVybHNbbm90ZU51bWJlcl07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9idWZmZXJzID0gbmV3IFRvbmVBdWRpb0J1ZmZlcnMoe1xuICAgICAgICAgICAgdXJsczogdXJsTWFwLFxuICAgICAgICAgICAgb25sb2FkOiBvcHRpb25zLm9ubG9hZCxcbiAgICAgICAgICAgIGJhc2VVcmw6IG9wdGlvbnMuYmFzZVVybCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG9wdGlvbnMub25lcnJvcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXR0YWNrID0gb3B0aW9ucy5hdHRhY2s7XG4gICAgICAgIHRoaXMucmVsZWFzZSA9IG9wdGlvbnMucmVsZWFzZTtcbiAgICAgICAgdGhpcy5jdXJ2ZSA9IG9wdGlvbnMuY3VydmU7XG4gICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2sgaWYgaXQncyBhbHJlYWR5IGxvYWRlZFxuICAgICAgICBpZiAodGhpcy5fYnVmZmVycy5sb2FkZWQpIHtcbiAgICAgICAgICAgIC8vIGludm9rZSBvbmxvYWQgZGVmZXJyZWRcbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4ob3B0aW9ucy5vbmxvYWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2s6IDAsXG4gICAgICAgICAgICBiYXNlVXJsOiBcIlwiLFxuICAgICAgICAgICAgY3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjEsXG4gICAgICAgICAgICB1cmxzOiB7fSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGRpZmZlcmVuY2UgaW4gc3RlcHMgYmV0d2VlbiB0aGUgZ2l2ZW4gbWlkaSBub3RlIGF0IHRoZSBjbG9zZXRzIHNhbXBsZS5cbiAgICAgKi9cbiAgICBfZmluZENsb3Nlc3QobWlkaSkge1xuICAgICAgICAvLyBzZWFyY2hlcyB3aXRoaW4gOCBvY3RhdmVzIG9mIHRoZSBnaXZlbiBtaWRpIG5vdGVcbiAgICAgICAgY29uc3QgTUFYX0lOVEVSVkFMID0gOTY7XG4gICAgICAgIGxldCBpbnRlcnZhbCA9IDA7XG4gICAgICAgIHdoaWxlIChpbnRlcnZhbCA8IE1BWF9JTlRFUlZBTCkge1xuICAgICAgICAgICAgLy8gY2hlY2sgYWJvdmUgYW5kIGJlbG93XG4gICAgICAgICAgICBpZiAodGhpcy5fYnVmZmVycy5oYXMobWlkaSArIGludGVydmFsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtaW50ZXJ2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9idWZmZXJzLmhhcyhtaWRpIC0gaW50ZXJ2YWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGludGVydmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW50ZXJ2YWwrKztcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGF2YWlsYWJsZSBidWZmZXJzIGZvciBub3RlOiAke21pZGl9YCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwYXJhbSAgbm90ZXNcdFRoZSBub3RlIHRvIHBsYXksIG9yIGFuIGFycmF5IG9mIG5vdGVzLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICAgV2hlbiB0byBwbGF5IHRoZSBub3RlXG4gICAgICogQHBhcmFtICB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgdG8gcGxheSB0aGUgc2FtcGxlIGJhY2suXG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayhub3RlcywgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlcywgdGltZSwgdmVsb2NpdHkpO1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG4gICAgICAgICAgICBub3RlcyA9IFtub3Rlc107XG4gICAgICAgIH1cbiAgICAgICAgbm90ZXMuZm9yRWFjaChub3RlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1pZGlGbG9hdCA9IGZ0b21mKG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvRnJlcXVlbmN5KCkpO1xuICAgICAgICAgICAgY29uc3QgbWlkaSA9IE1hdGgucm91bmQobWlkaUZsb2F0KTtcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpbmRlciA9IG1pZGlGbG9hdCAtIG1pZGk7XG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBjbG9zZXN0IG5vdGUgcGl0Y2hcbiAgICAgICAgICAgIGNvbnN0IGRpZmZlcmVuY2UgPSB0aGlzLl9maW5kQ2xvc2VzdChtaWRpKTtcbiAgICAgICAgICAgIGNvbnN0IGNsb3Nlc3ROb3RlID0gbWlkaSAtIGRpZmZlcmVuY2U7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9idWZmZXJzLmdldChjbG9zZXN0Tm90ZSk7XG4gICAgICAgICAgICBjb25zdCBwbGF5YmFja1JhdGUgPSBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oZGlmZmVyZW5jZSArIHJlbWFpbmRlcik7XG4gICAgICAgICAgICAvLyBwbGF5IHRoYXQgbm90ZVxuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgICAgIHVybDogYnVmZmVyLFxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBjdXJ2ZTogdGhpcy5jdXJ2ZSxcbiAgICAgICAgICAgICAgICBmYWRlSW46IHRoaXMuYXR0YWNrLFxuICAgICAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMucmVsZWFzZSxcbiAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGUsXG4gICAgICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydCh0aW1lLCAwLCBidWZmZXIuZHVyYXRpb24gLyBwbGF5YmFja1JhdGUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgIC8vIGFkZCBpdCB0byB0aGUgYWN0aXZlIHNvdXJjZXNcbiAgICAgICAgICAgIGlmICghaXNBcnJheSh0aGlzLl9hY3RpdmVTb3VyY2VzLmdldChtaWRpKSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnNldChtaWRpLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmdldChtaWRpKS5wdXNoKHNvdXJjZSk7XG4gICAgICAgICAgICAvLyByZW1vdmUgaXQgd2hlbiBpdCdzIGRvbmVcbiAgICAgICAgICAgIHNvdXJjZS5vbmVuZGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9hY3RpdmVTb3VyY2VzICYmIHRoaXMuX2FjdGl2ZVNvdXJjZXMuaGFzKG1pZGkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLl9hY3RpdmVTb3VyY2VzLmdldChtaWRpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBzb3VyY2VzLmluZGV4T2Yoc291cmNlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byByZWxlYXNlLCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgIFx0V2hlbiB0byByZWxlYXNlIHRoZSBub3RlLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlclJlbGVhc2VcIiwgbm90ZXMsIHRpbWUpO1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG4gICAgICAgICAgICBub3RlcyA9IFtub3Rlc107XG4gICAgICAgIH1cbiAgICAgICAgbm90ZXMuZm9yRWFjaChub3RlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG1pZGkgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIC8vIGZpbmQgdGhlIG5vdGVcbiAgICAgICAgICAgIGlmICh0aGlzLl9hY3RpdmVTb3VyY2VzLmhhcyhtaWRpKSAmJiB0aGlzLl9hY3RpdmVTb3VyY2VzLmdldChtaWRpKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSk7XG4gICAgICAgICAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAgICAgICAgIHNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzb3VyY2Uuc3RvcCh0aW1lKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnNldChtaWRpLCBbXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVsZWFzZSBhbGwgY3VycmVudGx5IGFjdGl2ZSBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgIFx0V2hlbiB0byByZWxlYXNlIHRoZSBub3Rlcy5cbiAgICAgKi9cbiAgICByZWxlYXNlQWxsKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2VzID0+IHtcbiAgICAgICAgICAgIHdoaWxlIChzb3VyY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHNvdXJjZXMuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zeW5jU3RhdGUoKSkge1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJBdHRhY2tcIiwgMSk7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlclJlbGVhc2VcIiwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgYXR0YWNrIHBoYXNlLCB0aGVuIGFmdGVyIHRoZSBkdXJhdGlvbiwgaW52b2tlIHRoZSByZWxlYXNlLlxuICAgICAqIEBwYXJhbSAgbm90ZXNcdFRoZSBub3RlIHRvIHBsYXkgYW5kIHJlbGVhc2UsIG9yIGFuIGFycmF5IG9mIG5vdGVzLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gVGhlIHRpbWUgdGhlIG5vdGUgc2hvdWxkIGJlIGhlbGRcbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgIFdoZW4gdG8gc3RhcnQgdGhlIGF0dGFja1xuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBhdHRhY2tcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShub3RlcywgZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKG5vdGVzLCBjb21wdXRlZFRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgaWYgKGlzQXJyYXkoZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBhc3NlcnQoaXNBcnJheShub3RlcyksIFwibm90ZXMgbXVzdCBiZSBhbiBhcnJheSB3aGVuIGR1cmF0aW9uIGlzIGFycmF5XCIpO1xuICAgICAgICAgICAgbm90ZXMuZm9yRWFjaCgobm90ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBkID0gZHVyYXRpb25bTWF0aC5taW4oaW5kZXgsIGR1cmF0aW9uLmxlbmd0aCAtIDEpXTtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGUsIGNvbXB1dGVkVGltZSArIHRoaXMudG9TZWNvbmRzKGQpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3RlcywgY29tcHV0ZWRUaW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgbm90ZSB0byB0aGUgc2FtcGxlci5cbiAgICAgKiBAcGFyYW0gIG5vdGUgICAgICBUaGUgYnVmZmVyJ3MgcGl0Y2guXG4gICAgICogQHBhcmFtICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZmZXIsIG9yIGEgYnVmZmVyIHdoaWNoIHdpbGwgYmUgYWRkZWQgd2l0aCB0aGUgZ2l2ZW4gbmFtZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIHVybCBpcyBsb2FkZWQuXG4gICAgICovXG4gICAgYWRkKG5vdGUsIHVybCwgY2FsbGJhY2spIHtcbiAgICAgICAgYXNzZXJ0KGlzTm90ZShub3RlKSB8fCBpc0Zpbml0ZShub3RlKSwgYG5vdGUgbXVzdCBiZSBhIHBpdGNoIG9yIG1pZGk6ICR7bm90ZX1gKTtcbiAgICAgICAgaWYgKGlzTm90ZShub3RlKSkge1xuICAgICAgICAgICAgLy8gY29udmVydCB0aGUgbm90ZSBuYW1lIHRvIE1JRElcbiAgICAgICAgICAgIGNvbnN0IG1pZCA9IG5ldyBGcmVxdWVuY3lDbGFzcyh0aGlzLmNvbnRleHQsIG5vdGUpLnRvTWlkaSgpO1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5hZGQobWlkLCB1cmwsIGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSBpZiBpdCdzIG51bWJlcnMgYXNzdW1lIGl0J3MgbWlkaVxuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5hZGQobm90ZSwgdXJsLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXJzIGFyZSBsb2FkZWQgb3Igbm90XG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMubG9hZGVkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2VzID0+IHtcbiAgICAgICAgICAgIHNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLmRpc3Bvc2UoKSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgU2FtcGxlci5wcm90b3R5cGUsIFwiYXR0YWNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFNhbXBsZXIucHJvdG90eXBlLCBcInJlbGVhc2VcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNhbXBsZXIuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vQU1TeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vRHVvU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0ZNU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL01ldGFsU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL01lbWJyYW5lU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL01vbm9TeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTm9pc2VTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGx1Y2tTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUG9seVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TYW1wbGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TeW50aFwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IFwiLi4vY29yZS9jbG9jay9UcmFuc3BvcnRcIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vY29yZS91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzQm9vbGVhbiwgaXNOdW1iZXIgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBUb25lRXZlbnQgYWJzdHJhY3RzIGF3YXkgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSBhbmQgcHJvdmlkZXMgYSBzY2hlZHVsYWJsZVxuICogY2FsbGJhY2sgZm9yIGEgc2luZ2xlIG9yIHJlcGVhdGFibGUgZXZlbnRzIGFsb25nIHRoZSB0aW1lbGluZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBjaG9yZEV2ZW50ID0gbmV3IFRvbmUuVG9uZUV2ZW50KCgodGltZSwgY2hvcmQpID0+IHtcbiAqIFx0Ly8gdGhlIGNob3JkIGFzIHdlbGwgYXMgdGhlIGV4YWN0IHRpbWUgb2YgdGhlIGV2ZW50XG4gKiBcdC8vIGFyZSBwYXNzZWQgaW4gYXMgYXJndW1lbnRzIHRvIHRoZSBjYWxsYmFjayBmdW5jdGlvblxuICogXHRzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShjaG9yZCwgMC41LCB0aW1lKTtcbiAqIH0pLCBbXCJENFwiLCBcIkU0XCIsIFwiRjRcIl0pO1xuICogLy8gc3RhcnQgdGhlIGNob3JkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIHRyYW5zcG9ydCB0aW1lbGluZVxuICogY2hvcmRFdmVudC5zdGFydCgpO1xuICogLy8gbG9vcCBpdCBldmVyeSBtZWFzdXJlIGZvciA4IG1lYXN1cmVzXG4gKiBjaG9yZEV2ZW50Lmxvb3AgPSA4O1xuICogY2hvcmRFdmVudC5sb29wRW5kID0gXCIxbVwiO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lRXZlbnQgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lRXZlbnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcInZhbHVlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUV2ZW50XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUcmFja3MgdGhlIHNjaGVkdWxlZCBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQSBkZWxheSB0aW1lIGZyb20gd2hlbiB0aGUgZXZlbnQgaXMgc2NoZWR1bGVkIHRvIHN0YXJ0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGFydE9mZnNldCA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lRXZlbnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcInZhbHVlXCJdKTtcbiAgICAgICAgdGhpcy5fbG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMudmFsdWUgPSBvcHRpb25zLnZhbHVlO1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5sb29wU3RhcnQpO1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKG9wdGlvbnMubG9vcEVuZCk7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLl9wcm9iYWJpbGl0eSA9IG9wdGlvbnMucHJvYmFiaWxpdHk7XG4gICAgICAgIHRoaXMuX2h1bWFuaXplID0gb3B0aW9ucy5odW1hbml6ZTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fc3RhdGUuaW5jcmVhc2luZyA9IHRydWU7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBldmVudHMgZm9yIHRoZSBmaXJzdCB0aW1lXG4gICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgICAgICBodW1hbml6ZTogZmFsc2UsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IFwiMW1cIixcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgcHJvYmFiaWxpdHk6IDEsXG4gICAgICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc2NoZWR1bGUgYWxsIG9mIHRoZSBldmVudHMgYWxvbmcgdGhlIHRpbWVsaW5lXG4gICAgICogd2l0aCB0aGUgdXBkYXRlZCB2YWx1ZXMuXG4gICAgICogQHBhcmFtIGFmdGVyIE9ubHkgcmVzY2hlZHVsZXMgZXZlbnRzIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqL1xuICAgIF9yZXNjaGVkdWxlRXZlbnRzKGFmdGVyID0gLTEpIHtcbiAgICAgICAgLy8gaWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHNjaGVkdWxlcyBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAgICB0aGlzLl9zdGF0ZS5mb3JFYWNoRnJvbShhZnRlciwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgbGV0IGR1cmF0aW9uO1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5pZCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihldmVudC5pZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGljayA9IGV2ZW50LnRpbWUgKyBNYXRoLnJvdW5kKHRoaXMuc3RhcnRPZmZzZXQgLyB0aGlzLl9wbGF5YmFja1JhdGUpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9sb29wID09PSB0cnVlIHx8IGlzTnVtYmVyKHRoaXMuX2xvb3ApICYmIHRoaXMuX2xvb3AgPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gSW5maW5pdHk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc051bWJlcih0aGlzLl9sb29wKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSAodGhpcy5fbG9vcCkgKiB0aGlzLl9nZXRMb29wRHVyYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0RXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXRBZnRlcihzdGFydFRpY2spO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dEV2ZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IE1hdGgubWluKGR1cmF0aW9uLCBuZXh0RXZlbnQudGltZSAtIHN0YXJ0VGljayk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGR1cmF0aW9uICE9PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2NoZWR1bGUgYSBzdG9wIHNpbmNlIGl0J3MgZmluaXRlIGR1cmF0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgc3RhcnRUaWNrICsgZHVyYXRpb24gKyAxLCB7IGlkOiAtMSB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2dldExvb3BEdXJhdGlvbigpKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuaWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KHRoaXMuX3RpY2suYmluZCh0aGlzKSwgaW50ZXJ2YWwsIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaWNrKSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuaWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKHRoaXMuX3RpY2suYmluZCh0aGlzKSwgbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpY2spKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgbm90ZSwgZWl0aGVyIFwic3RhcnRlZFwiIG9yIFwic3RvcHBlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQudGlja3MpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3RhcnQgZnJvbSB0aGUgc2NoZWR1bGVkIHN0YXJ0IHRpbWUuXG4gICAgICovXG4gICAgZ2V0IHN0YXJ0T2Zmc2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnRPZmZzZXQ7XG4gICAgfVxuICAgIHNldCBzdGFydE9mZnNldChvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSBvZmZzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9iYWJpbGl0eSBvZiB0aGUgbm90ZXMgYmVpbmcgdHJpZ2dlcmVkLlxuICAgICAqL1xuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2JhYmlsaXR5O1xuICAgIH1cbiAgICBzZXQgcHJvYmFiaWxpdHkocHJvYikge1xuICAgICAgICB0aGlzLl9wcm9iYWJpbGl0eSA9IHByb2I7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHNldCB0byB0cnVlLCB3aWxsIGFwcGx5IHNtYWxsIHJhbmRvbSB2YXJpYXRpb25cbiAgICAgKiB0byB0aGUgY2FsbGJhY2sgdGltZS4gSWYgdGhlIHZhbHVlIGlzIGdpdmVuIGFzIGEgdGltZSwgaXQgd2lsbCByYW5kb21pemVcbiAgICAgKiBieSB0aGF0IGFtb3VudC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGV2ZW50ID0gbmV3IFRvbmUuVG9uZUV2ZW50KCk7XG4gICAgICogZXZlbnQuaHVtYW5pemUgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2h1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX2h1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgbm90ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdGhlIGV2ZW50IHNob3VsZCBzdGFydC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpID09PSBcInN0b3BwZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHtcbiAgICAgICAgICAgICAgICBpZDogLTEsXG4gICAgICAgICAgICAgICAgc3RhdGU6IFwic3RhcnRlZFwiLFxuICAgICAgICAgICAgICAgIHRpbWU6IHRpY2tzLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKHRpY2tzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgRXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRoZSBldmVudCBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5jYW5jZWwodGltZSk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHRpY2tzLCB7IGlkOiAtMSB9KTtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXRCZWZvcmUodGlja3MpO1xuICAgICAgICAgICAgbGV0IHJlc2NoZWR1bFRpbWUgPSB0aWNrcztcbiAgICAgICAgICAgIGlmIChwcmV2aW91c0V2ZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVzY2hlZHVsVGltZSA9IHByZXZpb3VzRXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMocmVzY2hlZHVsVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBhbGwgc2NoZWR1bGVkIGV2ZW50cyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIGFmdGVyIHdoaWNoIGV2ZW50cyB3aWxsIGJlIGNhbmNlbC5cbiAgICAgKi9cbiAgICBjYW5jZWwodGltZSkge1xuICAgICAgICB0aW1lID0gZGVmYXVsdEFyZyh0aW1lLCAtSW5maW5pdHkpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEZyb20odGlja3MsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoZXZlbnQuaWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpY2tzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjYWxsYmFjayBmdW5jdGlvbiBpbnZva2VyLiBBbHNvXG4gICAgICogY2hlY2tzIGlmIHRoZSBFdmVudCBpcyBkb25lIHBsYXlpbmdcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIG9mIHRoZSBldmVudCBpbiBzZWNvbmRzXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICghdGhpcy5tdXRlICYmIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb2JhYmlsaXR5IDwgMSAmJiBNYXRoLnJhbmRvbSgpID4gdGhpcy5wcm9iYWJpbGl0eSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLmh1bWFuaXplKSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhcmlhdGlvbiA9IDAuMDI7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0Jvb2xlYW4odGhpcy5odW1hbml6ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyaWF0aW9uID0gdGhpcy50b1NlY29uZHModGhpcy5odW1hbml6ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRpbWUgKz0gKE1hdGgucmFuZG9tKCkgKiAyIC0gMSkgKiB2YXJpYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRoaXMudmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZHVyYXRpb24gb2YgdGhlIGxvb3AuXG4gICAgICovXG4gICAgX2dldExvb3BEdXJhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoKHRoaXMuX2xvb3BFbmQgLSB0aGlzLl9sb29wU3RhcnQpIC8gdGhpcy5fcGxheWJhY2tSYXRlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIG5vdGUgc2hvdWxkIGxvb3Agb3Igbm90XG4gICAgICogYmV0d2VlbiBUb25lRXZlbnQubG9vcFN0YXJ0IGFuZFxuICAgICAqIFRvbmVFdmVudC5sb29wRW5kLiBJZiBzZXQgdG8gdHJ1ZSxcbiAgICAgKiB0aGUgZXZlbnQgd2lsbCBsb29wIGluZGVmaW5pdGVseSxcbiAgICAgKiBpZiBzZXQgdG8gYSBudW1iZXIgZ3JlYXRlciB0aGFuIDFcbiAgICAgKiBpdCB3aWxsIHBsYXkgYSBzcGVjaWZpYyBudW1iZXIgb2ZcbiAgICAgKiB0aW1lcywgaWYgc2V0IHRvIGZhbHNlLCAwIG9yIDEsIHRoZVxuICAgICAqIHBhcnQgd2lsbCBvbmx5IHBsYXkgb25jZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fbG9vcCA9IGxvb3A7XG4gICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIG5vdGUuIERlZmF1bHRzIHRvIDEuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBub3RlID0gbmV3IFRvbmUuVG9uZUV2ZW50KCk7XG4gICAgICogbm90ZS5sb29wID0gdHJ1ZTtcbiAgICAgKiAvLyByZXBlYXQgdGhlIG5vdGUgdHdpY2UgYXMgZmFzdFxuICAgICAqIG5vdGUucGxheWJhY2tSYXRlID0gMjtcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG9vcEVuZCBwb2ludCBpcyB0aGUgdGltZSB0aGUgZXZlbnQgd2lsbCBsb29wXG4gICAgICogaWYgVG9uZUV2ZW50Lmxvb3AgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcEVuZCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhsb29wRW5kKTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSB3aGVuIHRoZSBsb29wIHNob3VsZCBzdGFydC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wU3RhcnQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvVGlja3MobG9vcFN0YXJ0KTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCBwcm9ncmVzcyBvZiB0aGUgbG9vcCBpbnRlcnZhbC5cbiAgICAgKiBSZXR1cm5zIDAgaWYgdGhlIGV2ZW50IGlzIG5vdCBzdGFydGVkIHlldCBvclxuICAgICAqIGl0IGlzIG5vdCBzZXQgdG8gbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQudGlja3M7XG4gICAgICAgICAgICBjb25zdCBsYXN0RXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQodGlja3MpO1xuICAgICAgICAgICAgaWYgKGxhc3RFdmVudCAhPT0gbnVsbCAmJiBsYXN0RXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbG9vcER1cmF0aW9uID0gdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSAodGlja3MgLSBsYXN0RXZlbnQudGltZSkgJSBsb29wRHVyYXRpb247XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb2dyZXNzIC8gbG9vcER1cmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY2FuY2VsKCk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUV2ZW50LmpzLm1hcCIsImltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIExvb3AgY3JlYXRlcyBhIGxvb3BlZCBjYWxsYmFjayBhdCB0aGVcbiAqIHNwZWNpZmllZCBpbnRlcnZhbC4gVGhlIGNhbGxiYWNrIGNhbiBiZVxuICogc3RhcnRlZCwgc3RvcHBlZCBhbmQgc2NoZWR1bGVkIGFsb25nXG4gKiB0aGUgVHJhbnNwb3J0J3MgdGltZWxpbmUuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbG9vcCA9IG5ldyBUb25lLkxvb3AoKHRpbWUpID0+IHtcbiAqIFx0Ly8gdHJpZ2dlcmVkIGV2ZXJ5IGVpZ2h0aCBub3RlLlxuICogXHRjb25zb2xlLmxvZyh0aW1lKTtcbiAqIH0sIFwiOG5cIikuc3RhcnQoMCk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBMb29wIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTG9vcC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiaW50ZXJ2YWxcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMb29wXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMb29wLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJpbnRlcnZhbFwiXSk7XG4gICAgICAgIHRoaXMuX2V2ZW50ID0gbmV3IFRvbmVFdmVudCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fdGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IG9wdGlvbnMuaW50ZXJ2YWwsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IG9wdGlvbnMucGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgcHJvYmFiaWxpdHk6IG9wdGlvbnMucHJvYmFiaWxpdHlcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICAvLyBzZXQgdGhlIGl0ZXJhdGlvbnNcbiAgICAgICAgdGhpcy5pdGVyYXRpb25zID0gb3B0aW9ucy5pdGVyYXRpb25zO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBpbnRlcnZhbDogXCI0blwiLFxuICAgICAgICAgICAgY2FsbGJhY2s6IG5vT3AsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgICAgICBpdGVyYXRpb25zOiBJbmZpbml0eSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiAxLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBodW1hbml6ZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBsb29wIGF0IHRoZSBzcGVjaWZpZWQgdGltZSBhbG9uZyB0aGUgVHJhbnNwb3J0J3MgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHN0YXJ0IHRoZSBMb29wLlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBsb29wIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdG9wIHRoZSBMb29wLlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGFsbCBzY2hlZHVsZWQgZXZlbnRzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgYWZ0ZXIgd2hpY2ggZXZlbnRzIHdpbGwgYmUgY2FuY2VsLlxuICAgICAqL1xuICAgIGNhbmNlbCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LmNhbmNlbCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIHRoZSBub3RlcyBzaG91bGQgYmUgY2FsbGVkXG4gICAgICogQHBhcmFtIHRpbWUgIFRoZSB0aW1lIHRoZSBldmVudCBvY2N1cnNcbiAgICAgKi9cbiAgICBfdGljayh0aW1lKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdGF0ZSBvZiB0aGUgTG9vcCwgZWl0aGVyIHN0YXJ0ZWQgb3Igc3RvcHBlZC5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHByb2dyZXNzIG9mIHRoZSBsb29wIGFzIGEgdmFsdWUgYmV0d2VlbiAwLTEuIDAsIHdoZW4gdGhlIGxvb3AgaXMgc3RvcHBlZCBvciBkb25lIGl0ZXJhdGluZy5cbiAgICAgKi9cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5wcm9ncmVzcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgYmV0d2VlbiBzdWNjZXNzaXZlIGNhbGxiYWNrcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGxvb3AgPSBuZXcgVG9uZS5Mb29wKCk7XG4gICAgICogbG9vcC5pbnRlcnZhbCA9IFwiOG5cIjsgLy8gbG9vcCBldmVyeSA4blxuICAgICAqL1xuICAgIGdldCBpbnRlcnZhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmxvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBpbnRlcnZhbChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl9ldmVudC5sb29wRW5kID0gaW50ZXJ2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBsb29wLiBUaGUgbm9ybWFsIHBsYXliYWNrIHJhdGUgaXMgMSAobm8gY2hhbmdlKS5cbiAgICAgKiBBIGBwbGF5YmFja1JhdGVgIG9mIDIgd291bGQgYmUgdHdpY2UgYXMgZmFzdC5cbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQucGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmFuZG9tIHZhcmlhdGlvbiArLy0wLjAxcyB0byB0aGUgc2NoZWR1bGVkIHRpbWUuXG4gICAgICogT3IgZ2l2ZSBpdCBhIHRpbWUgdmFsdWUgd2hpY2ggaXQgd2lsbCByYW5kb21pemUgYnkuXG4gICAgICovXG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQuaHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuaHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9iYWJseSBvZiB0aGUgY2FsbGJhY2sgYmVpbmcgaW52b2tlZC5cbiAgICAgKi9cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQucHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRpbmcgdGhlIExvb3AgbWVhbnMgdGhhdCBubyBjYWxsYmFja3MgYXJlIGludm9rZWQuXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50Lm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgb2YgdGhlIGxvb3AuIFRoZSBkZWZhdWx0IHZhbHVlIGlzIGBJbmZpbml0eWAgKGxvb3AgZm9yZXZlcikuXG4gICAgICovXG4gICAgZ2V0IGl0ZXJhdGlvbnMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9ldmVudC5sb29wID09PSB0cnVlKSB7XG4gICAgICAgICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubG9vcDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXQgaXRlcmF0aW9ucyhpdGVycykge1xuICAgICAgICBpZiAoaXRlcnMgPT09IEluZmluaXR5KSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudC5sb29wID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50Lmxvb3AgPSBpdGVycztcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TG9vcC5qcy5tYXAiLCJpbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vY29yZS91dGlsL1N0YXRlVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRGVmaW5lZCwgaXNPYmplY3QsIGlzVW5kZWYgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVG9uZUV2ZW50IH0gZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG4vKipcbiAqIFBhcnQgaXMgYSBjb2xsZWN0aW9uIFRvbmVFdmVudHMgd2hpY2ggY2FuIGJlIHN0YXJ0ZWQvc3RvcHBlZCBhbmQgbG9vcGVkIGFzIGEgc2luZ2xlIHVuaXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgoKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0Ly8gdGhlIG5vdGVzIGdpdmVuIGFzIHRoZSBzZWNvbmQgZWxlbWVudCBpbiB0aGUgYXJyYXlcbiAqIFx0Ly8gd2lsbCBiZSBwYXNzZWQgaW4gYXMgdGhlIHNlY29uZCBhcmd1bWVudFxuICogXHRzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShub3RlLCBcIjhuXCIsIHRpbWUpO1xuICogfSksIFtbMCwgXCJDMlwiXSwgW1wiMDoyXCIsIFwiQzNcIl0sIFtcIjA6MzoyXCIsIFwiRzJcIl1dKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIHVzZSBhbiBhcnJheSBvZiBvYmplY3RzIGFzIGxvbmcgYXMgdGhlIG9iamVjdCBoYXMgYSBcInRpbWVcIiBhdHRyaWJ1dGVcbiAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCgodGltZSwgdmFsdWUpID0+IHtcbiAqIFx0Ly8gdGhlIHZhbHVlIGlzIGFuIG9iamVjdCB3aGljaCBjb250YWlucyBib3RoIHRoZSBub3RlIGFuZCB0aGUgdmVsb2NpdHlcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UodmFsdWUubm90ZSwgXCI4blwiLCB0aW1lLCB2YWx1ZS52ZWxvY2l0eSk7XG4gKiB9KSwgW3sgdGltZTogMCwgbm90ZTogXCJDM1wiLCB2ZWxvY2l0eTogMC45IH0sXG4gKiBcdHsgdGltZTogXCIwOjJcIiwgbm90ZTogXCJDNFwiLCB2ZWxvY2l0eTogMC41IH1cbiAqIF0pLnN0YXJ0KDApO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgUGFydCBleHRlbmRzIFRvbmVFdmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhcnRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYWNrcyB0aGUgc2NoZWR1bGVkIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZXZlbnRzIHRoYXQgYmVsb25nIHRvIHRoaXMgcGFydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFNldCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFydC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZXZlbnRzXCJdKTtcbiAgICAgICAgLy8gbWFrZSBzdXJlIHRoaW5ncyBhcmUgYXNzaWduZWQgaW4gdGhlIHJpZ2h0IG9yZGVyXG4gICAgICAgIHRoaXMuX3N0YXRlLmluY3JlYXNpbmcgPSB0cnVlO1xuICAgICAgICAvLyBhZGQgdGhlIGV2ZW50c1xuICAgICAgICBvcHRpb25zLmV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGV2ZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkKGV2ZW50WzBdLCBldmVudFsxXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVFdmVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBldmVudHM6IFtdLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgIFdoZW4gdG8gc3RhcnQgdGhlIHBhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgIFRoZSBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHBhcnQgdG8gYmVnaW4gcGxheWluZyBhdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgdGhpcy5fbG9vcCA/IHRoaXMuX2xvb3BTdGFydCA6IDApO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgdGhpcy5fbG9vcFN0YXJ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkT2Zmc2V0ID0gdGhpcy50b1RpY2tzKG9mZnNldCk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5hZGQoe1xuICAgICAgICAgICAgICAgIGlkOiAtMSxcbiAgICAgICAgICAgICAgICBvZmZzZXQ6IGNvbXB1dGVkT2Zmc2V0LFxuICAgICAgICAgICAgICAgIHN0YXRlOiBcInN0YXJ0ZWRcIixcbiAgICAgICAgICAgICAgICB0aW1lOiB0aWNrcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnROb3RlKGV2ZW50LCB0aWNrcywgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBldmVudCBpbiB0aGUgZ2l2ZW4gZXZlbnQgYXQgdGhlIGNvcnJlY3QgdGltZSBnaXZlblxuICAgICAqIHRoZSB0aWNrcyBhbmQgb2Zmc2V0IGFuZCBsb29waW5nLlxuICAgICAqIEBwYXJhbSAgZXZlbnRcbiAgICAgKiBAcGFyYW0gIHRpY2tzXG4gICAgICogQHBhcmFtICBvZmZzZXRcbiAgICAgKi9cbiAgICBfc3RhcnROb3RlKGV2ZW50LCB0aWNrcywgb2Zmc2V0KSB7XG4gICAgICAgIHRpY2tzIC09IG9mZnNldDtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA+PSB0aGlzLl9sb29wU3RhcnQgJiYgZXZlbnQuc3RhcnRPZmZzZXQgPCB0aGlzLl9sb29wRW5kKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0IDwgb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHN0YXJ0IGl0IG9uIHRoZSBuZXh0IGxvb3BcbiAgICAgICAgICAgICAgICAgICAgdGlja3MgKz0gdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGV2ZW50LnN0YXJ0KG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcFN0YXJ0ICYmIGV2ZW50LnN0YXJ0T2Zmc2V0ID49IG9mZnNldCkge1xuICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3AgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBldmVudC5zdGFydChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPj0gb2Zmc2V0KSB7XG4gICAgICAgICAgICBldmVudC5zdGFydChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHN0YXJ0T2Zmc2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhcnRPZmZzZXQ7XG4gICAgfVxuICAgIHNldCBzdGFydE9mZnNldChvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSBvZmZzZXQ7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RhcnRPZmZzZXQgKz0gdGhpcy5fc3RhcnRPZmZzZXQ7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdG9wIHRoZSBwYXJ0LlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRpY2tzKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHRpY2tzKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudC5zdG9wKHRpbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldC9TZXQgYW4gRXZlbnQncyB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBJZiBhIHZhbHVlIGlzIHBhc3NlZCBpbiBhbmQgbm8gZXZlbnQgZXhpc3RzIGF0XG4gICAgICogdGhlIGdpdmVuIHRpbWUsIG9uZSB3aWxsIGJlIGNyZWF0ZWQgd2l0aCB0aGF0IHZhbHVlLlxuICAgICAqIElmIHR3byBldmVudHMgYXJlIGF0IHRoZSBzYW1lIHRpbWUsIHRoZSBmaXJzdCBvbmUgd2lsbFxuICAgICAqIGJlIHJldHVybmVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKTtcbiAgICAgKiBwYXJ0LmF0KFwiMW1cIik7IC8vIHJldHVybnMgdGhlIHBhcnQgYXQgdGhlIGZpcnN0IG1lYXN1cmVcbiAgICAgKiBwYXJ0LmF0KFwiMm1cIiwgXCJDMlwiKTsgLy8gc2V0IHRoZSB2YWx1ZSBhdCBcIjJtXCIgdG8gQzIuXG4gICAgICogLy8gaWYgYW4gZXZlbnQgZGlkbid0IGV4aXN0IGF0IHRoYXQgdGltZSwgaXQgd2lsbCBiZSBjcmVhdGVkLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIG9mIHRoZSBldmVudCB0byBnZXQgb3Igc2V0LlxuICAgICAqIEBwYXJhbSB2YWx1ZSBJZiBhIHZhbHVlIGlzIHBhc3NlZCBpbiwgdGhlIHZhbHVlIG9mIHRoZSBldmVudCBhdCB0aGUgZ2l2ZW4gdGltZSB3aWxsIGJlIHNldCB0byBpdC5cbiAgICAgKi9cbiAgICBhdCh0aW1lLCB2YWx1ZSkge1xuICAgICAgICBjb25zdCB0aW1lSW5UaWNrcyA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1RpY2tzKCk7XG4gICAgICAgIGNvbnN0IHRpY2tUaW1lID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCAxKS50b1NlY29uZHMoKTtcbiAgICAgICAgY29uc3QgaXRlcmF0b3IgPSB0aGlzLl9ldmVudHMudmFsdWVzKCk7XG4gICAgICAgIGxldCByZXN1bHQgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIHdoaWxlICghcmVzdWx0LmRvbmUpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gcmVzdWx0LnZhbHVlO1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKHRpbWVJblRpY2tzIC0gZXZlbnQuc3RhcnRPZmZzZXQpIDwgdGlja1RpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBldmVudC52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQgPSBpdGVyYXRvci5uZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgdGhlcmUgd2FzIG5vIGV2ZW50IGF0IHRoYXQgdGltZSwgY3JlYXRlIG9uZVxuICAgICAgICBpZiAoaXNEZWZpbmVkKHZhbHVlKSkge1xuICAgICAgICAgICAgdGhpcy5hZGQodGltZSwgdmFsdWUpO1xuICAgICAgICAgICAgLy8gcmV0dXJuIHRoZSBuZXcgZXZlbnRcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmF0KHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIC8vIGV4dHJhY3QgdGhlIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKHRpbWUgaW5zdGFuY2VvZiBPYmplY3QgJiYgUmVmbGVjdC5oYXModGltZSwgXCJ0aW1lXCIpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRpbWU7XG4gICAgICAgICAgICB0aW1lID0gdmFsdWUudGltZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgbGV0IGV2ZW50O1xuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBUb25lRXZlbnQpIHtcbiAgICAgICAgICAgIGV2ZW50ID0gdmFsdWU7XG4gICAgICAgICAgICBldmVudC5jYWxsYmFjayA9IHRoaXMuX3RpY2suYmluZCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGV2ZW50ID0gbmV3IFRvbmVFdmVudCh7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0aGUgc3RhcnQgb2Zmc2V0XG4gICAgICAgIGV2ZW50LnN0YXJ0T2Zmc2V0ID0gdGlja3M7XG4gICAgICAgIC8vIGluaXRpYWxpemUgdGhlIHZhbHVlc1xuICAgICAgICBldmVudC5zZXQoe1xuICAgICAgICAgICAgaHVtYW5pemU6IHRoaXMuaHVtYW5pemUsXG4gICAgICAgICAgICBsb29wOiB0aGlzLmxvb3AsXG4gICAgICAgICAgICBsb29wRW5kOiB0aGlzLmxvb3BFbmQsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IHRoaXMubG9vcFN0YXJ0LFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiB0aGlzLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiB0aGlzLnByb2JhYmlsaXR5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmFkZChldmVudCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBub3RlIGlmIGl0IHNob3VsZCBiZSBwbGF5ZWQgcmlnaHQgbm93XG4gICAgICAgIHRoaXMuX3Jlc3RhcnRFdmVudChldmVudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXN0YXJ0IHRoZSBnaXZlbiBldmVudFxuICAgICAqL1xuICAgIF9yZXN0YXJ0RXZlbnQoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaCgoc3RhdGVFdmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKHN0YXRlRXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnROb3RlKGV2ZW50LCBzdGF0ZUV2ZW50LnRpbWUsIHN0YXRlRXZlbnQub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHN0b3AgdGhlIG5vdGVcbiAgICAgICAgICAgICAgICBldmVudC5zdG9wKG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgc3RhdGVFdmVudC50aW1lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZW1vdmUodGltZSwgdmFsdWUpIHtcbiAgICAgICAgLy8gZXh0cmFjdCB0aGUgcGFyYW1ldGVyc1xuICAgICAgICBpZiAoaXNPYmplY3QodGltZSkgJiYgdGltZS5oYXNPd25Qcm9wZXJ0eShcInRpbWVcIikpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGltZTtcbiAgICAgICAgICAgIHRpbWUgPSB2YWx1ZS50aW1lO1xuICAgICAgICB9XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA9PT0gdGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChpc1VuZGVmKHZhbHVlKSB8fCAoaXNEZWZpbmVkKHZhbHVlKSAmJiBldmVudC52YWx1ZSA9PT0gdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5kZWxldGUoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICBldmVudC5kaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSBhbGwgb2YgdGhlIG5vdGVzIGZyb20gdGhlIGdyb3VwLlxuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IGV2ZW50LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIHNjaGVkdWxlZCBzdGF0ZSBjaGFuZ2UgZXZlbnRzOiBpLmUuIFwic3RhcnRcIiBhbmQgXCJzdG9wXCIuXG4gICAgICogQHBhcmFtIGFmdGVyIFRoZSB0aW1lIGFmdGVyIHdoaWNoIHRvIGNhbmNlbCB0aGUgc2NoZWR1bGVkIGV2ZW50cy5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiBldmVudC5jYW5jZWwoYWZ0ZXIpKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHRoaXMudG9UaWNrcyhhZnRlcikpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICovXG4gICAgX2ZvckVhY2goY2FsbGJhY2spIHtcbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cykge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChldmVudCBpbnN0YW5jZW9mIFBhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuX2ZvckVhY2goY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGF0dHJpYnV0ZSBvZiBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqIEBwYXJhbSAgYXR0ciAgdGhlIGF0dHJpYnV0ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHZhbHVlICAgICAgVGhlIHZhbHVlIHRvIHNldCBpdCB0b1xuICAgICAqL1xuICAgIF9zZXRBbGwoYXR0ciwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudFthdHRyXSA9IHZhbHVlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgdGljayBtZXRob2RcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIG9mIHRoZSBldmVudCBpbiBzZWNvbmRzXG4gICAgICovXG4gICAgX3RpY2sodGltZSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCF0aGlzLm11dGUpIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERldGVybWluZSBpZiB0aGUgZXZlbnQgc2hvdWxkIGJlIGN1cnJlbnRseSBsb29waW5nXG4gICAgICogZ2l2ZW4gdGhlIGxvb3AgYm91bmRyaWVzIG9mIHRoaXMgUGFydC5cbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgZXZlbnQgdG8gdGVzdFxuICAgICAqL1xuICAgIF90ZXN0TG9vcEJvdW5kcmllcyhldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fbG9vcCAmJiAoZXZlbnQuc3RhcnRPZmZzZXQgPCB0aGlzLl9sb29wU3RhcnQgfHwgZXZlbnQuc3RhcnRPZmZzZXQgPj0gdGhpcy5fbG9vcEVuZCkpIHtcbiAgICAgICAgICAgIGV2ZW50LmNhbmNlbCgwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldmVudC5zdGF0ZSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIC8vIHJlc2NoZWR1bGUgaXQgaWYgaXQncyBzdG9wcGVkXG4gICAgICAgICAgICB0aGlzLl9yZXN0YXJ0RXZlbnQoZXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2JhYmlsaXR5O1xuICAgIH1cbiAgICBzZXQgcHJvYmFiaWxpdHkocHJvYikge1xuICAgICAgICB0aGlzLl9wcm9iYWJpbGl0eSA9IHByb2I7XG4gICAgICAgIHRoaXMuX3NldEFsbChcInByb2JhYmlsaXR5XCIsIHByb2IpO1xuICAgIH1cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICAgICAgdGhpcy5fc2V0QWxsKFwiaHVtYW5pemVcIiwgdmFyaWF0aW9uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIHBhcnQgc2hvdWxkIGxvb3Agb3Igbm90XG4gICAgICogYmV0d2VlbiBQYXJ0Lmxvb3BTdGFydCBhbmRcbiAgICAgKiBQYXJ0Lmxvb3BFbmQuIElmIHNldCB0byB0cnVlLFxuICAgICAqIHRoZSBwYXJ0IHdpbGwgbG9vcCBpbmRlZmluaXRlbHksXG4gICAgICogaWYgc2V0IHRvIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAxXG4gICAgICogaXQgd2lsbCBwbGF5IGEgc3BlY2lmaWMgbnVtYmVyIG9mXG4gICAgICogdGltZXMsIGlmIHNldCB0byBmYWxzZSwgMCBvciAxLCB0aGVcbiAgICAgKiBwYXJ0IHdpbGwgb25seSBwbGF5IG9uY2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgpO1xuICAgICAqIC8vIGxvb3AgdGhlIHBhcnQgOCB0aW1lc1xuICAgICAqIHBhcnQubG9vcCA9IDg7XG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50Lmxvb3BTdGFydCA9IHRoaXMubG9vcFN0YXJ0O1xuICAgICAgICAgICAgZXZlbnQubG9vcEVuZCA9IHRoaXMubG9vcEVuZDtcbiAgICAgICAgICAgIGV2ZW50Lmxvb3AgPSBsb29wO1xuICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3BFbmQgcG9pbnQgZGV0ZXJtaW5lcyB3aGVuIGl0IHdpbGxcbiAgICAgKiBsb29wIGlmIFBhcnQubG9vcCBpcyB0cnVlLlxuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wRW5kKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQobG9vcEVuZCkge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gdGhpcy50b1RpY2tzKGxvb3BFbmQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQubG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3BTdGFydCBwb2ludCBkZXRlcm1pbmVzIHdoZW4gaXQgd2lsbFxuICAgICAqIGxvb3AgaWYgUGFydC5sb29wIGlzIHRydWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcFN0YXJ0KS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKGxvb3BTdGFydCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBldmVudC5sb29wU3RhcnQgPSB0aGlzLmxvb3BTdGFydDtcbiAgICAgICAgICAgICAgICB0aGlzLl90ZXN0TG9vcEJvdW5kcmllcyhldmVudCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgcGFydFxuICAgICAqL1xuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICB0aGlzLl9zZXRBbGwoXCJwbGF5YmFja1JhdGVcIiwgcmF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2NoZWR1bGVkIG5vdGVzIGluIHRoZSBwYXJ0LlxuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudHMuc2l6ZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhcnQuanMubWFwIiwiaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tIFwiLi4vY29yZS91dGlsL01hdGhcIjtcbi8qKlxuICogU3RhcnQgYXQgdGhlIGZpcnN0IHZhbHVlIGFuZCBnbyB1cCB0byB0aGUgbGFzdFxuICovXG5mdW5jdGlvbiogdXBQYXR0ZXJuR2VuKHZhbHVlcykge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgd2hpbGUgKGluZGV4IDwgdmFsdWVzLmxlbmd0aCkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIGluZGV4Kys7XG4gICAgfVxufVxuLyoqXG4gKiBTdGFydCBhdCB0aGUgbGFzdCB2YWx1ZSBhbmQgZ28gZG93biB0byAwXG4gKi9cbmZ1bmN0aW9uKiBkb3duUGF0dGVybkdlbih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSB2YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICB3aGlsZSAoaW5kZXggPj0gMCkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIGluZGV4LS07XG4gICAgfVxufVxuLyoqXG4gKiBJbmZpbml0ZWx5IHlpZWxkIHRoZSBnZW5lcmF0b3JcbiAqL1xuZnVuY3Rpb24qIGluZmluaXRlR2VuKHZhbHVlcywgZ2VuKSB7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgeWllbGQqIGdlbih2YWx1ZXMpO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGluZGV4IGlzIGluIHRoZSBnaXZlbiByYW5nZVxuICovXG5mdW5jdGlvbiBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpIHtcbiAgICByZXR1cm4gY2xhbXAoaW5kZXgsIDAsIHZhbHVlcy5sZW5ndGggLSAxKTtcbn1cbi8qKlxuICogQWx0ZXJuYXRlIGJldHdlZW4gdHdvIGdlbmVyYXRvcnNcbiAqL1xuZnVuY3Rpb24qIGFsdGVybmF0aW5nR2VuZXJhdG9yKHZhbHVlcywgZGlyZWN0aW9uVXApIHtcbiAgICBsZXQgaW5kZXggPSBkaXJlY3Rpb25VcCA/IDAgOiB2YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIGlmIChkaXJlY3Rpb25VcCkge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIGlmIChpbmRleCA+PSB2YWx1ZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIGRpcmVjdGlvblVwID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbmRleC0tO1xuICAgICAgICAgICAgaWYgKGluZGV4IDw9IDApIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb25VcCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4vKipcbiAqIFN0YXJ0aW5nIGZyb20gdGhlIGJvdHRvbSBtb3ZlIHVwIDIsIGRvd24gMVxuICovXG5mdW5jdGlvbioganVtcFVwKHZhbHVlcykge1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgbGV0IHN0ZXBJbmRleCA9IDA7XG4gICAgd2hpbGUgKGluZGV4IDwgdmFsdWVzLmxlbmd0aCkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIHN0ZXBJbmRleCsrO1xuICAgICAgICBpbmRleCArPSAoc3RlcEluZGV4ICUgMiA/IDIgOiAtMSk7XG4gICAgfVxufVxuLyoqXG4gKiBTdGFydGluZyBmcm9tIHRoZSB0b3AgbW92ZSBkb3duIDIsIHVwIDFcbiAqL1xuZnVuY3Rpb24qIGp1bXBEb3duKHZhbHVlcykge1xuICAgIGxldCBpbmRleCA9IHZhbHVlcy5sZW5ndGggLSAxO1xuICAgIGxldCBzdGVwSW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA+PSAwKSB7XG4gICAgICAgIGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICAgICAgc3RlcEluZGV4Kys7XG4gICAgICAgIGluZGV4ICs9IChzdGVwSW5kZXggJSAyID8gLTIgOiAxKTtcbiAgICB9XG59XG4vKipcbiAqIENob29zZSBhIHJhbmRvbSBpbmRleCBlYWNoIHRpbWVcbiAqL1xuZnVuY3Rpb24qIHJhbmRvbUdlbih2YWx1ZXMpIHtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBjb25zdCByYW5kb21JbmRleCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHZhbHVlcy5sZW5ndGgpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbcmFuZG9tSW5kZXhdO1xuICAgIH1cbn1cbi8qKlxuICogUmFuZG9tbHkgZ28gdGhyb3VnaCBhbGwgb2YgdGhlIHZhbHVlcyBvbmNlIGJlZm9yZSBjaG9vc2luZyBhIG5ldyByYW5kb20gb3JkZXJcbiAqL1xuZnVuY3Rpb24qIHJhbmRvbU9uY2UodmFsdWVzKSB7XG4gICAgLy8gY3JlYXRlIGFuIGFycmF5IG9mIGluZGljZXNcbiAgICBjb25zdCBjb3B5ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29weS5wdXNoKGkpO1xuICAgIH1cbiAgICB3aGlsZSAoY29weS5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHJhbmRvbSBjaG9vc2UgYW4gaW5kZXgsIGFuZCB0aGVuIHJlbW92ZSBpdCBzbyBpdCdzIG5vdCBjaG9zZW4gYWdhaW5cbiAgICAgICAgY29uc3QgcmFuZFZhbCA9IGNvcHkuc3BsaWNlKE1hdGguZmxvb3IoY29weS5sZW5ndGggKiBNYXRoLnJhbmRvbSgpKSwgMSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gY2xhbXBUb0FycmF5U2l6ZShyYW5kVmFsWzBdLCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgIH1cbn1cbi8qKlxuICogUmFuZG9tbHkgY2hvb3NlIHRvIHdhbGsgdXAgb3IgZG93biAxIGluZGV4IGluIHRoZSB2YWx1ZXMgYXJyYXlcbiAqL1xuZnVuY3Rpb24qIHJhbmRvbVdhbGsodmFsdWVzKSB7XG4gICAgLy8gcmFuZG9tbHkgY2hvb3NlIGEgc3RhcnRpbmcgaW5kZXggaW4gdGhlIHZhbHVlcyBhcnJheVxuICAgIGxldCBpbmRleCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHZhbHVlcy5sZW5ndGgpO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgaW5kZXgrKzsgLy8gYXQgYm90dG9tIG9mIGFycmF5LCBzbyBmb3JjZSB1cHdhcmQgc3RlcFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGluZGV4ID09PSB2YWx1ZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgaW5kZXgtLTsgLy8gYXQgdG9wIG9mIGFycmF5LCBzbyBmb3JjZSBkb3dud2FyZCBzdGVwXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoTWF0aC5yYW5kb20oKSA8IDAuNSkgeyAvLyBlbHNlIGNob29zZSByYW5kb20gZG93bndhcmQgb3IgdXB3YXJkIHN0ZXBcbiAgICAgICAgICAgIGluZGV4LS07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgfVxufVxuLyoqXG4gKiBQYXR0ZXJuR2VuZXJhdG9yIHJldHVybnMgYSBnZW5lcmF0b3Igd2hpY2ggd2lsbCBpdGVyYXRlIG92ZXIgdGhlIGdpdmVuIGFycmF5XG4gKiBvZiB2YWx1ZXMgYW5kIHlpZWxkIHRoZSBpdGVtcyBhY2NvcmRpbmcgdG8gdGhlIHBhc3NlZCBpbiBwYXR0ZXJuXG4gKiBAcGFyYW0gdmFsdWVzIEFuIGFycmF5IG9mIHZhbHVlcyB0byBpdGVyYXRlIG92ZXJcbiAqIEBwYXJhbSBwYXR0ZXJuIFRoZSBuYW1lIG9mIHRoZSBwYXR0ZXJuIHVzZSB3aGVuIGl0ZXJhdGluZyBvdmVyXG4gKiBAcGFyYW0gaW5kZXggV2hlcmUgdG8gc3RhcnQgaW4gdGhlIG9mZnNldCBvZiB0aGUgdmFsdWVzIGFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiogUGF0dGVybkdlbmVyYXRvcih2YWx1ZXMsIHBhdHRlcm4gPSBcInVwXCIsIGluZGV4ID0gMCkge1xuICAgIC8vIHNhZmVndWFyZHNcbiAgICBhc3NlcnQodmFsdWVzLmxlbmd0aCA+IDAsIFwiVGhlIGFycmF5IG11c3QgaGF2ZSBtb3JlIHRoYW4gb25lIHZhbHVlIGluIGl0XCIpO1xuICAgIHN3aXRjaCAocGF0dGVybikge1xuICAgICAgICBjYXNlIFwidXBcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIHVwUGF0dGVybkdlbik7XG4gICAgICAgIGNhc2UgXCJkb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCBkb3duUGF0dGVybkdlbik7XG4gICAgICAgIGNhc2UgXCJ1cERvd25cIjpcbiAgICAgICAgICAgIHlpZWxkKiBhbHRlcm5hdGluZ0dlbmVyYXRvcih2YWx1ZXMsIHRydWUpO1xuICAgICAgICBjYXNlIFwiZG93blVwXCI6XG4gICAgICAgICAgICB5aWVsZCogYWx0ZXJuYXRpbmdHZW5lcmF0b3IodmFsdWVzLCBmYWxzZSk7XG4gICAgICAgIGNhc2UgXCJhbHRlcm5hdGVVcFwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywganVtcFVwKTtcbiAgICAgICAgY2FzZSBcImFsdGVybmF0ZURvd25cIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGp1bXBEb3duKTtcbiAgICAgICAgY2FzZSBcInJhbmRvbVwiOlxuICAgICAgICAgICAgeWllbGQqIHJhbmRvbUdlbih2YWx1ZXMpO1xuICAgICAgICBjYXNlIFwicmFuZG9tT25jZVwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywgcmFuZG9tT25jZSk7XG4gICAgICAgIGNhc2UgXCJyYW5kb21XYWxrXCI6XG4gICAgICAgICAgICB5aWVsZCogcmFuZG9tV2Fsayh2YWx1ZXMpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhdHRlcm5HZW5lcmF0b3IuanMubWFwIiwiaW1wb3J0IHsgTG9vcCB9IGZyb20gXCIuL0xvb3BcIjtcbmltcG9ydCB7IFBhdHRlcm5HZW5lcmF0b3IgfSBmcm9tIFwiLi9QYXR0ZXJuR2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBQYXR0ZXJuIGFycGVnZ2lhdGVzIGJldHdlZW4gdGhlIGdpdmVuIG5vdGVzXG4gKiBpbiBhIG51bWJlciBvZiBwYXR0ZXJucy5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwYXR0ZXJuID0gbmV3IFRvbmUuUGF0dGVybigodGltZSwgbm90ZSkgPT4ge1xuICogXHQvLyB0aGUgb3JkZXIgb2YgdGhlIG5vdGVzIHBhc3NlZCBpbiBkZXBlbmRzIG9uIHRoZSBwYXR0ZXJuXG4gKiB9LCBbXCJDMlwiLCBcIkQ0XCIsIFwiRTVcIiwgXCJBNlwiXSwgXCJ1cERvd25cIik7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhdHRlcm4gZXh0ZW5kcyBMb29wIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGF0dGVybi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwidmFsdWVzXCIsIFwicGF0dGVyblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhdHRlcm5cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhdHRlcm4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcInZhbHVlc1wiLCBcInBhdHRlcm5cIl0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy5fdmFsdWVzID0gb3B0aW9ucy52YWx1ZXM7XG4gICAgICAgIHRoaXMuX3BhdHRlcm4gPSBQYXR0ZXJuR2VuZXJhdG9yKG9wdGlvbnMudmFsdWVzLCBvcHRpb25zLnBhdHRlcm4pO1xuICAgICAgICB0aGlzLl90eXBlID0gb3B0aW9ucy5wYXR0ZXJuO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKExvb3AuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcGF0dGVybjogXCJ1cFwiLFxuICAgICAgICAgICAgdmFsdWVzOiBbXSxcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgZnVuY3Rpb24gY2FsbGVkIHdoZW4gdGhlIG5vdGVzIHNob3VsZCBiZSBjYWxsZWRcbiAgICAgKi9cbiAgICBfdGljayh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fcGF0dGVybi5uZXh0KCk7XG4gICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWUudmFsdWU7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGhpcy5fdmFsdWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYXJyYXkgb2YgZXZlbnRzLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZXM7XG4gICAgfVxuICAgIHNldCB2YWx1ZXModmFsKSB7XG4gICAgICAgIHRoaXMuX3ZhbHVlcyA9IHZhbDtcbiAgICAgICAgLy8gcmVzZXQgdGhlIHBhdHRlcm5cbiAgICAgICAgdGhpcy5wYXR0ZXJuID0gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIHBhdHRlcm4uXG4gICAgICovXG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYXR0ZXJuIHR5cGUuIFNlZSBUb25lLkN0cmxQYXR0ZXJuIGZvciB0aGUgZnVsbCBsaXN0IG9mIHBhdHRlcm5zLlxuICAgICAqL1xuICAgIGdldCBwYXR0ZXJuKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHBhdHRlcm4ocGF0dGVybikge1xuICAgICAgICB0aGlzLl90eXBlID0gcGF0dGVybjtcbiAgICAgICAgdGhpcy5fcGF0dGVybiA9IFBhdHRlcm5HZW5lcmF0b3IodGhpcy5fdmFsdWVzLCB0aGlzLl90eXBlKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXR0ZXJuLmpzLm1hcCIsImltcG9ydCB7IFRpY2tzQ2xhc3MgfSBmcm9tIFwiLi4vY29yZS90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc1N0cmluZyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBQYXJ0IH0gZnJvbSBcIi4vUGFydFwiO1xuaW1wb3J0IHsgVG9uZUV2ZW50IH0gZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG4vKipcbiAqIEEgc2VxdWVuY2UgaXMgYW4gYWx0ZXJuYXRlIG5vdGF0aW9uIG9mIGEgcGFydC4gSW5zdGVhZFxuICogb2YgcGFzc2luZyBpbiBhbiBhcnJheSBvZiBbdGltZSwgZXZlbnRdIHBhaXJzLCBwYXNzXG4gKiBpbiBhbiBhcnJheSBvZiBldmVudHMgd2hpY2ggd2lsbCBiZSBzcGFjZWQgYXQgdGhlXG4gKiBnaXZlbiBzdWJkaXZpc2lvbi4gU3ViLWFycmF5cyB3aWxsIHN1YmRpdmlkZSB0aGF0IGJlYXRcbiAqIGJ5IHRoZSBudW1iZXIgb2YgaXRlbXMgYXJlIGluIHRoZSBhcnJheS5cbiAqIFNlcXVlbmNlIG5vdGF0aW9uIGluc3BpcmF0aW9uIGZyb20gW1RpZGFsXShodHRwOi8veWF4dS5vcmcvdGlkYWwvKVxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBzZXEgPSBuZXcgVG9uZS5TZXF1ZW5jZSgodGltZSwgbm90ZSkgPT4ge1xuICogXHRzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShub3RlLCAwLjEsIHRpbWUpO1xuICogXHQvLyBzdWJkaXZpc2lvbnMgYXJlIGdpdmVuIGFzIHN1YmFycmF5c1xuICogfSwgW1wiQzRcIiwgW1wiRTRcIiwgXCJENFwiLCBcIkU0XCJdLCBcIkc0XCIsIFtcIkE0XCIsIFwiRzRcIl1dKS5zdGFydCgwKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNlcXVlbmNlIGV4dGVuZHMgVG9uZUV2ZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2VxdWVuY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiLCBcInN1YmRpdmlzaW9uXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2VxdWVuY2VcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvYmplY3QgcmVzcG9uc2libGUgZm9yIHNjaGVkdWxpbmcgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3BhcnQgPSBuZXcgUGFydCh7XG4gICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fc2VxQ2FsbGJhY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBwcml2YXRlIHJlZmVyZW5jZSB0byBhbGwgb2YgdGhlIHNlcXVlbmNlIHByb3hpZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHByb3hpZWQgYXJyYXlcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50c0FycmF5ID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTZXF1ZW5jZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiZXZlbnRzXCIsIFwic3ViZGl2aXNpb25cIl0pO1xuICAgICAgICB0aGlzLl9zdWJkaXZpc2lvbiA9IHRoaXMudG9UaWNrcyhvcHRpb25zLnN1YmRpdmlzaW9uKTtcbiAgICAgICAgdGhpcy5ldmVudHMgPSBvcHRpb25zLmV2ZW50cztcbiAgICAgICAgLy8gc2V0IGFsbCBvZiB0aGUgdmFsdWVzXG4gICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLnByb2JhYmlsaXR5ID0gb3B0aW9ucy5wcm9iYWJpbGl0eTtcbiAgICAgICAgdGhpcy5odW1hbml6ZSA9IG9wdGlvbnMuaHVtYW5pemU7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChUb25lRXZlbnQuZ2V0RGVmYXVsdHMoKSwgW1widmFsdWVcIl0pLCB7XG4gICAgICAgICAgICBldmVudHM6IFtdLFxuICAgICAgICAgICAgbG9vcDogdHJ1ZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBzdWJkaXZpc2lvbjogXCI4blwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGludGVybmFsIGNhbGxiYWNrIGZvciB3aGVuIGFuIGV2ZW50IGlzIGludm9rZWRcbiAgICAgKi9cbiAgICBfc2VxQ2FsbGJhY2sodGltZSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2VxdWVuY2VcbiAgICAgKi9cbiAgICBnZXQgZXZlbnRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzO1xuICAgIH1cbiAgICBzZXQgZXZlbnRzKHMpIHtcbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICB0aGlzLl9ldmVudHNBcnJheSA9IHM7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IHRoaXMuX2NyZWF0ZVNlcXVlbmNlKHRoaXMuX2V2ZW50c0FycmF5KTtcbiAgICAgICAgdGhpcy5fZXZlbnRzVXBkYXRlZCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgV2hlbiB0byBzdGFydCB0aGUgcGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCAgVGhlIG9mZnNldCBpbmRleCB0byBzdGFydCBhdFxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICB0aGlzLl9wYXJ0LnN0YXJ0KHRpbWUsIG9mZnNldCA/IHRoaXMuX2luZGV4VGltZShvZmZzZXQpIDogb2Zmc2V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIHN0b3AgdGhlIHBhcnQuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzdWJkaXZpc2lvbiBvZiB0aGUgc2VxdWVuY2UuIFRoaXMgY2FuIG9ubHkgYmVcbiAgICAgKiBzZXQgaW4gdGhlIGNvbnN0cnVjdG9yLiBUaGUgc3ViZGl2aXNpb24gaXMgdGhlXG4gICAgICogaW50ZXJ2YWwgYmV0d2VlbiBzdWNjZXNzaXZlIHN0ZXBzLlxuICAgICAqL1xuICAgIGdldCBzdWJkaXZpc2lvbigpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fc3ViZGl2aXNpb24pLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBzZXF1ZW5jZSBwcm94eSB3aGljaCBjYW4gYmUgbW9uaXRvcmVkIHRvIGNyZWF0ZSBzdWJzZXF1ZW5jZXNcbiAgICAgKi9cbiAgICBfY3JlYXRlU2VxdWVuY2UoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm94eShhcnJheSwge1xuICAgICAgICAgICAgZ2V0OiAodGFyZ2V0LCBwcm9wZXJ0eSkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIHByb3BlcnR5IGlzIGluZGV4IGluIHRoaXMgY2FzZVxuICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXRbcHJvcGVydHldO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzU3RyaW5nKHByb3BlcnR5KSAmJiBpc0Zpbml0ZShwYXJzZUludChwcm9wZXJ0eSwgMTApKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcm9wZXJ0eV0gPSB0aGlzLl9jcmVhdGVTZXF1ZW5jZSh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldFtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzVXBkYXRlZCgpO1xuICAgICAgICAgICAgICAgIC8vIHJldHVybiB0cnVlIHRvIGFjY2VwdCB0aGUgY2hhbmdlc1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIHNlcXVlbmNlIGhhcyBjaGFuZ2VkLCBhbGwgb2YgdGhlIGV2ZW50cyBuZWVkIHRvIGJlIHJlY3JlYXRlZFxuICAgICAqL1xuICAgIF9ldmVudHNVcGRhdGVkKCkge1xuICAgICAgICB0aGlzLl9wYXJ0LmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVTZXF1ZW5jZSh0aGlzLl9ldmVudHNBcnJheSwgdGhpcy5fc3ViZGl2aXNpb24sIHRoaXMuc3RhcnRPZmZzZXQpO1xuICAgICAgICAvLyB1cGRhdGUgdGhlIGxvb3BFbmRcbiAgICAgICAgdGhpcy5sb29wRW5kID0gdGhpcy5sb29wRW5kO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiByZXNjaGVkdWxlIGFsbCBvZiB0aGUgZXZlbnRzIHRoYXQgbmVlZCB0byBiZSByZXNjaGVkdWxlZFxuICAgICAqL1xuICAgIF9yZXNjaGVkdWxlU2VxdWVuY2Uoc2VxdWVuY2UsIHN1YmRpdmlzaW9uLCBzdGFydE9mZnNldCkge1xuICAgICAgICBzZXF1ZW5jZS5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50T2Zmc2V0ID0gaW5kZXggKiAoc3ViZGl2aXNpb24pICsgc3RhcnRPZmZzZXQ7XG4gICAgICAgICAgICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlU2VxdWVuY2UodmFsdWUsIHN1YmRpdmlzaW9uIC8gdmFsdWUubGVuZ3RoLCBldmVudE9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIGV2ZW50T2Zmc2V0LCBcImlcIikudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFydC5hZGQoc3RhcnRUaW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGluZGV4IGdpdmVuIHRoZSBTZXF1ZW5jZSdzIHN1YmRpdmlzaW9uXG4gICAgICogQHBhcmFtICBpbmRleFxuICAgICAqIEByZXR1cm4gVGhlIHRpbWUgb2YgdGhhdCBpbmRleFxuICAgICAqL1xuICAgIF9pbmRleFRpbWUoaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgaW5kZXggKiAodGhpcy5fc3ViZGl2aXNpb24pICsgdGhpcy5zdGFydE9mZnNldCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFyIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICovXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFydC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBQUk9YWSBDQUxMU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsKSB7XG4gICAgICAgIHRoaXMuX3BhcnQubG9vcCA9IGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbmRleCBhdCB3aGljaCB0aGUgc2VxdWVuY2Ugc2hvdWxkIHN0YXJ0IGxvb3BpbmdcbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGluZGV4KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IGluZGV4O1xuICAgICAgICB0aGlzLl9wYXJ0Lmxvb3BTdGFydCA9IHRoaXMuX2luZGV4VGltZShpbmRleCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbmRleCBhdCB3aGljaCB0aGUgc2VxdWVuY2Ugc2hvdWxkIGVuZCBsb29waW5nXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChpbmRleCkge1xuICAgICAgICB0aGlzLl9sb29wRW5kID0gaW5kZXg7XG4gICAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fcGFydC5sb29wRW5kID0gdGhpcy5faW5kZXhUaW1lKHRoaXMuX2V2ZW50c0FycmF5Lmxlbmd0aCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0Lmxvb3BFbmQgPSB0aGlzLl9pbmRleFRpbWUoaW5kZXgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQuc3RhcnRPZmZzZXQ7XG4gICAgfVxuICAgIHNldCBzdGFydE9mZnNldChzdGFydCkge1xuICAgICAgICB0aGlzLl9wYXJ0LnN0YXJ0T2Zmc2V0ID0gc3RhcnQ7XG4gICAgfVxuICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnBsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BhcnQucGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICB9XG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcGFydC5wcm9iYWJpbGl0eSA9IHByb2I7XG4gICAgfVxuICAgIGdldCBwcm9ncmVzcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQucHJvZ3Jlc3M7XG4gICAgfVxuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQuaHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5fcGFydC5odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBzY2hlZHVsZWQgZXZlbnRzXG4gICAgICovXG4gICAgZ2V0IGxlbmd0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQubGVuZ3RoO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNlcXVlbmNlLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0xvb3BcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BhcnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BhdHRlcm5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NlcXVlbmNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3QsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgR2FpblRvQXVkaW8gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0dhaW5Ub0F1ZGlvXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuLyoqXG4gKiBUb25lLkNyb3NzZmFkZSBwcm92aWRlcyBlcXVhbCBwb3dlciBmYWRpbmcgYmV0d2VlbiB0d28gaW5wdXRzLlxuICogTW9yZSBvbiBjcm9zc2ZhZGluZyB0ZWNobmlxdWUgW2hlcmVdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ZhZGVfKGF1ZGlvX2VuZ2luZWVyaW5nKSNDcm9zc2ZhZGluZykuXG4gKiBgYGBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0tLStcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArPiBpbnB1dCBhICs+LS0rXG4gKiArLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgICAgIHwgICAgICAgICB8ICAgfFxuICogfCAxcyBzaWduYWwgKz4tLT4gc3RlcmVvUGFubmVyTm9kZSAgTCArPi0tLS0+IGdhaW4gICAgfCAgIHxcbiAqICstLS0tLS0tLS0tLSsgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgKy0tLS0tLS0tLSsgICB8XG4gKiAgICAgICAgICAgICAgICstPiBwYW4gICAgICAgICAgICAgICBSICs+LSsgICAgICAgICAgICAgICAgfCAgICstLS0tLS0tLStcbiAqICAgICAgICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAgfCAgICAgICAgICAgICAgICArLS0tPiBvdXRwdXQgKz5cbiAqICArLS0tLS0tKyAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgKy0tLS0tLS0tLSsgICB8ICAgKy0tLS0tLS0tK1xuICogIHwgZmFkZSArPi0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICB8ICs+IGlucHV0IGIgKz4tLStcbiAqICArLS0tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgfCAgICAgICAgIHxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tPiBnYWluICAgIHxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNyb3NzRmFkZSA9IG5ldyBUb25lLkNyb3NzRmFkZSgpLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIGNvbm5lY3QgdHdvIGlucHV0cyBUb25lLnRvIGEvYlxuICogY29uc3QgaW5wdXRBID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic3F1YXJlXCIpLmNvbm5lY3QoY3Jvc3NGYWRlLmEpLnN0YXJ0KCk7XG4gKiBjb25zdCBpbnB1dEIgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDQ0MCwgXCJzaW5lXCIpLmNvbm5lY3QoY3Jvc3NGYWRlLmIpLnN0YXJ0KCk7XG4gKiAvLyB1c2UgdGhlIGZhZGUgdG8gY29udHJvbCB0aGUgbWl4IGJldHdlZW4gdGhlIHR3b1xuICogY3Jvc3NGYWRlLmZhZGUudmFsdWUgPSAwLjU7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDcm9zc0ZhZGUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhDcm9zc0ZhZGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmYWRlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNyb3NzRmFkZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGNyb3NzZmFkaW5nIGlzIGRvbmUgYnkgYSBTdGVyZW9QYW5uZXJOb2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlU3RlcmVvUGFubmVyKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTcGxpdCB0aGUgb3V0cHV0IG9mIHRoZSBwYW5uZXIgbm9kZSBpbnRvIHR3byB2YWx1ZXMgdXNlZCB0byBjb250cm9sIHRoZSBnYWlucy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NwbGl0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNoYW5uZWxTcGxpdHRlcigyKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZlcnQgdGhlIGZhZGUgdmFsdWUgaW50byBhbiBhdWRpbyByYW5nZSB2YWx1ZSBzbyBpdCBjYW4gYmUgY29ubmVjdGVkXG4gICAgICAgICAqIHRvIHRoZSBwYW5uZXIucGFuIEF1ZGlvUGFyYW1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2cyYSA9IG5ldyBHYWluVG9BdWRpbyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCB3aGljaCBpcyBhdCBmdWxsIGxldmVsIHdoZW4gZmFkZSA9IDBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IHdoaWNoIGlzIGF0IGZ1bGwgbGV2ZWwgd2hlbiBmYWRlID0gMVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5iID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IGlzIGEgbWl4IGJldHdlZW4gYGFgIGFuZCBgYmAgYXQgdGhlIHJhdGlvIG9mIGBmYWRlYFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmEsIHRoaXMuYl07XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDcm9zc0ZhZGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmYWRlXCJdKTtcbiAgICAgICAgdGhpcy5mYWRlID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZmFkZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZmFkZVwiKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmdldENvbnN0YW50KDEpLmNvbm5lY3QodGhpcy5fcGFubmVyKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICAvLyB0aGlzIGlzIG5lY2Vzc2FyeSBmb3Igc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcbiAgICAgICAgLy8gZG9lc24ndCBtYWtlIGFueSBkaWZmZXJlbmNlIGZvciB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dFxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hyaXNndXR0YW5kaW4vc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvaXNzdWVzLzY0N1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50ID0gMTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudE1vZGUgPSBcImV4cGxpY2l0XCI7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc3BsaXQsIHRoaXMuYS5nYWluLCAwKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLl9zcGxpdCwgdGhpcy5iLmdhaW4sIDEpO1xuICAgICAgICB0aGlzLmZhZGUuY2hhaW4odGhpcy5fZzJhLCB0aGlzLl9wYW5uZXIucGFuKTtcbiAgICAgICAgdGhpcy5hLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLmIuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmYWRlOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mYWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZzJhLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Dcm9zc0ZhZGUuanMubWFwIiwiaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBFZmZlY3QgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGVmZmVjdHMuIENvbm5lY3QgdGhlIGVmZmVjdCBiZXR3ZWVuXG4gKiB0aGUgZWZmZWN0U2VuZCBhbmQgZWZmZWN0UmV0dXJuIEdhaW5Ob2RlcywgdGhlbiBjb250cm9sIHRoZSBhbW91bnQgb2ZcbiAqIGVmZmVjdCB3aGljaCBnb2VzIHRvIHRoZSBvdXRwdXQgdXNpbmcgdGhlIHdldCBjb250cm9sLlxuICovXG5leHBvcnQgY2xhc3MgRWZmZWN0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFZmZlY3RcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBkcnl3ZXQga25vYiB0byBjb250cm9sIHRoZSBhbW91bnQgb2YgZWZmZWN0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9kcnlXZXQgPSBuZXcgQ3Jvc3NGYWRlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHdldCBjb250cm9sIGlzIGhvdyBtdWNoIG9mIHRoZSBlZmZlY3RlZFxuICAgICAgICAgKiB3aWxsIHBhc3MgdGhyb3VnaCB0byB0aGUgb3V0cHV0LiAxID0gMTAwJSBlZmZlY3RlZFxuICAgICAgICAgKiBzaWduYWwsIDAgPSAxMDAlIGRyeSBzaWduYWwuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLndldCA9IHRoaXMuX2RyeVdldC5mYWRlO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29ubmVjdCB0aGUgZWZmZWN0U2VuZCB0byB0aGUgaW5wdXQgb2YgaHRlIGVmZmVjdFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBjb25uZWN0IHRoZSBvdXRwdXQgb2YgdGhlIGVmZmVjdCB0byB0aGUgZWZmZWN0UmV0dXJuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmVmZmVjdFJldHVybiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVmZmVjdCBpbnB1dCBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZWZmZWN0IG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9kcnlXZXQ7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuaW5wdXQuZmFuKHRoaXMuX2RyeVdldC5hLCB0aGlzLmVmZmVjdFNlbmQpO1xuICAgICAgICB0aGlzLmVmZmVjdFJldHVybi5jb25uZWN0KHRoaXMuX2RyeVdldC5iKTtcbiAgICAgICAgdGhpcy53ZXQuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy53ZXQsIDApO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMuZWZmZWN0UmV0dXJuLCB0aGlzLmVmZmVjdFNlbmRdO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcIndldFwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHdldDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYWlucyB0aGUgZWZmZWN0IGluIGJldHdlZW4gdGhlIGVmZmVjdFNlbmQgYW5kIGVmZmVjdFJldHVyblxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3QoZWZmZWN0KSB7XG4gICAgICAgIC8vIGFkZCBpdCB0byB0aGUgaW50ZXJuYWwgY2hhbm5lbHNcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscy5wdXNoKGVmZmVjdCk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbihlZmZlY3QsIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHJ5V2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLndldC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi4vZWZmZWN0L0VmZmVjdFwiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBMRk8tYmFzZWQgZWZmZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIExGT0VmZmVjdCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMRk9FZmZlY3RcIjtcbiAgICAgICAgdGhpcy5fbGZvID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgYW1wbGl0dWRlOiBvcHRpb25zLmRlcHRoLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2xmby5hbXBsaXR1ZGU7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgZGVwdGg6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgZWZmZWN0LlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvLnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbGZvXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmby5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZmlsdGVyIHRvIHRoZSB0cmFuc3BvcnQuIFNlZSBbW0xGTy5zeW5jXV1cbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm8uc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBmaWx0ZXIgZnJvbSB0aGUgdHJhbnNwb3J0LlxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvLnVuc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIExGTydzIG9zY2lsbGF0b3I6IFNlZSBbW09zY2lsbGF0b3IudHlwZV1dXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBhdXRvRmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcigpLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG5vaXNlID0gbmV3IFRvbmUuTm9pc2UoKS5zdGFydCgpLmNvbm5lY3QoYXV0b0ZpbHRlcik7XG4gICAgICogYXV0b0ZpbHRlci50eXBlID0gXCJzcXVhcmVcIjtcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmby50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1MRk9FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmlsdGVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGT0VmZmVjdCB9IGZyb20gXCIuL0xGT0VmZmVjdFwiO1xuLyoqXG4gKiBBdXRvRmlsdGVyIGlzIGEgVG9uZS5GaWx0ZXIgd2l0aCBhIFRvbmUuTEZPIGNvbm5lY3RlZCB0byB0aGUgZmlsdGVyIGN1dG9mZiBmcmVxdWVuY3kuXG4gKiBTZXR0aW5nIHRoZSBMRk8gcmF0ZSBhbmQgZGVwdGggYWxsb3dzIGZvciBjb250cm9sIG92ZXIgdGhlIGZpbHRlciBtb2R1bGF0aW9uIHJhdGVcbiAqIGFuZCBkZXB0aC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gY3JlYXRlIGFuIGF1dG9maWx0ZXIgYW5kIHN0YXJ0IGl0J3MgTEZPXG4gKiBjb25zdCBhdXRvRmlsdGVyID0gbmV3IFRvbmUuQXV0b0ZpbHRlcihcIjRuXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gcm91dGUgYW4gb3NjaWxsYXRvciB0aHJvdWdoIHRoZSBmaWx0ZXIgYW5kIHN0YXJ0IGl0XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoYXV0b0ZpbHRlcikuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEF1dG9GaWx0ZXIgZXh0ZW5kcyBMRk9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiYmFzZUZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBdXRvRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiYmFzZUZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIl0pO1xuICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zLmZpbHRlciwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLmZpbHRlcik7XG4gICAgICAgIHRoaXMuX2xmby5jb25uZWN0KHRoaXMuZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5iYXNlRnJlcXVlbmN5ID0gb3B0aW9ucy5iYXNlRnJlcXVlbmN5O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKExGT0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiYXNlRnJlcXVlbmN5OiAyMDAsXG4gICAgICAgICAgICBvY3RhdmVzOiAyLjYsXG4gICAgICAgICAgICBmaWx0ZXI6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIixcbiAgICAgICAgICAgICAgICByb2xsb2ZmOiAtMTIsXG4gICAgICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW5pbXVtIHZhbHVlIG9mIHRoZSBmaWx0ZXIncyBjdXRvZmYgZnJlcXVlbmN5LlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvLm1pbjtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3koZnJlcSkge1xuICAgICAgICB0aGlzLl9sZm8ubWluID0gdGhpcy50b0ZyZXF1ZW5jeShmcmVxKTtcbiAgICAgICAgLy8gYW5kIHNldCB0aGUgbWF4XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBmaWx0ZXIncyBjdXRvZmYgZnJlcXVlbmN5LlxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0KSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3Q7XG4gICAgICAgIHRoaXMuX2xmby5tYXggPSB0aGlzLl9sZm8ubWluICogTWF0aC5wb3coMiwgb2N0KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1dG9GaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogUGFubmVyIGlzIGFuIGVxdWFsIHBvd2VyIExlZnQvUmlnaHQgUGFubmVyLiBJdCBpcyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBTdGVyZW9QYW5uZXJOb2RlLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogLy8gbW92ZSB0aGUgaW5wdXQgc2lnbmFsIGZyb20gcmlnaHQgdG8gbGVmdFxuICogXHRjb25zdCBwYW5uZXIgPSBuZXcgVG9uZS5QYW5uZXIoMSkudG9EZXN0aW5hdGlvbigpO1xuICogXHRwYW5uZXIucGFuLnJhbXBUbygtMSwgMC41KTtcbiAqIFx0Y29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigxMDApLmNvbm5lY3QocGFubmVyKS5zdGFydCgpO1xuICogfSwgMC41LCAyKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhbm5lciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhblwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYW5uZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBwYW5uZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fcGFubmVyO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3Bhbm5lcjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhblwiXSk7XG4gICAgICAgIHRoaXMucGFuID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucGFuLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucGFuLFxuICAgICAgICAgICAgbWluVmFsdWU6IC0xLFxuICAgICAgICAgICAgbWF4VmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyB0aGlzIGlzIG5lY2Vzc2FyeSBmb3Igc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcbiAgICAgICAgLy8gZG9lc24ndCBtYWtlIGFueSBkaWZmZXJlbmNlIGZvciB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dFxuICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vY2hyaXNndXR0YW5kaW4vc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHQvaXNzdWVzLzY0N1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50ID0gb3B0aW9ucy5jaGFubmVsQ291bnQ7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICAvLyBpbml0aWFsIHZhbHVlXG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwicGFuXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLnBhbi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhbm5lci5qcy5tYXAiLCJpbXBvcnQgeyBQYW5uZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvUGFubmVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGT0VmZmVjdCB9IGZyb20gXCIuL0xGT0VmZmVjdFwiO1xuLyoqXG4gKiBBdXRvUGFubmVyIGlzIGEgW1tQYW5uZXJdXSB3aXRoIGFuIFtbTEZPXV0gY29ubmVjdGVkIHRvIHRoZSBwYW4gYW1vdW50LlxuICogW1JlbGF0ZWQgUmVhZGluZ10oaHR0cHM6Ly93d3cuYWJsZXRvbi5jb20vZW4vYmxvZy9hdXRvcGFuLWNob3BwZXItZWZmZWN0LWFuZC1tb3JlLWxpdmVzY2hvb2wvKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gY3JlYXRlIGFuIGF1dG9wYW5uZXIgYW5kIHN0YXJ0IGl0XG4gKiBjb25zdCBhdXRvUGFubmVyID0gbmV3IFRvbmUuQXV0b1Bhbm5lcihcIjRuXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gcm91dGUgYW4gb3NjaWxsYXRvciB0aHJvdWdoIHRoZSBwYW5uZXIgYW5kIHN0YXJ0IGl0XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoYXV0b1Bhbm5lcikuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEF1dG9QYW5uZXIgZXh0ZW5kcyBMRk9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvUGFubmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b1Bhbm5lclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1Bhbm5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IG5ldyBQYW5uZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX3Bhbm5lcik7XG4gICAgICAgIHRoaXMuX2xmby5jb25uZWN0KHRoaXMuX3Bhbm5lci5wYW4pO1xuICAgICAgICB0aGlzLl9sZm8ubWluID0gLTE7XG4gICAgICAgIHRoaXMuX2xmby5tYXggPSAxO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKExGT0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDFcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXV0b1Bhbm5lci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE9uZVBvbGVGaWx0ZXIgfSBmcm9tIFwiLi4vZmlsdGVyL09uZVBvbGVGaWx0ZXJcIjtcbmltcG9ydCB7IEFicyB9IGZyb20gXCIuLi8uLi9zaWduYWwvQWJzXCI7XG4vKipcbiAqIEZvbGxvd2VyIGlzIGEgc2ltcGxlIGVudmVsb3BlIGZvbGxvd2VyLlxuICogSXQncyBpbXBsZW1lbnRlZCBieSBhcHBseWluZyBhIGxvd3Bhc3MgZmlsdGVyIHRvIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICogYGBgXG4gKiAgICAgICAgICArLS0tLS0rICAgICstLS0tLS0tLS0tLS0tLS0rXG4gKiBJbnB1dCArLS0+IEFicyArLS0tLT4gT25lUG9sZUZpbHRlciArLS0+IE91dHB1dFxuICogICAgICAgICAgKy0tLS0tKyAgICArLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGb2xsb3dlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGb2xsb3dlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNtb290aGluZ1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZvbGxvd2VyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGb2xsb3dlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNtb290aGluZ1wiXSk7XG4gICAgICAgIHRoaXMuX2FicyA9IHRoaXMuaW5wdXQgPSBuZXcgQWJzKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9sb3dwYXNzID0gdGhpcy5vdXRwdXQgPSBuZXcgT25lUG9sZUZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEgLyB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLnNtb290aGluZyksXG4gICAgICAgICAgICB0eXBlOiBcImxvd3Bhc3NcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYWJzLmNvbm5lY3QodGhpcy5fbG93cGFzcyk7XG4gICAgICAgIHRoaXMuX3Ntb290aGluZyA9IG9wdGlvbnMuc21vb3RoaW5nO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjA1XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgaXQgdGFrZXMgYSB2YWx1ZSBjaGFuZ2UgdG8gYXJyaXZlIGF0IHRoZSB1cGRhdGVkIHZhbHVlLlxuICAgICAqL1xuICAgIGdldCBzbW9vdGhpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zbW9vdGhpbmc7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcoc21vb3RoaW5nKSB7XG4gICAgICAgIHRoaXMuX3Ntb290aGluZyA9IHNtb290aGluZztcbiAgICAgICAgdGhpcy5fbG93cGFzcy5mcmVxdWVuY3kgPSAxIC8gdGhpcy50b1NlY29uZHModGhpcy5zbW9vdGhpbmcpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Ficy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Gb2xsb3dlci5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZpbHRlclwiO1xuaW1wb3J0IHsgRm9sbG93ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2FuYWx5c2lzL0ZvbGxvd2VyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGRiVG9HYWluLCBnYWluVG9EYiB9IGZyb20gXCIuLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IFNjYWxlRXhwIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZUV4cFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBBdXRvV2FoIGNvbm5lY3RzIGEgW1tGb2xsb3dlcl1dIHRvIGEgW1tGaWx0ZXJdXS5cbiAqIFRoZSBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlciwgZm9sbG93cyB0aGUgaW5wdXQgYW1wbGl0dWRlIGN1cnZlLlxuICogSW5zcGlyYXRpb24gZnJvbSBbVHVuYS5qc10oaHR0cHM6Ly9naXRodWIuY29tL0RpbmFobW9lL3R1bmEpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBhdXRvV2FoID0gbmV3IFRvbmUuQXV0b1dhaCg1MCwgNiwgLTMwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBpbml0aWFsaXplIHRoZSBzeW50aCBhbmQgY29ubmVjdCB0byBhdXRvd2FoXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkuY29ubmVjdChhdXRvV2FoKTtcbiAqIC8vIFEgdmFsdWUgaW5mbHVlbmNlcyB0aGUgZWZmZWN0IG9mIHRoZSB3YWggLSBkZWZhdWx0IGlzIDJcbiAqIGF1dG9XYWguUS52YWx1ZSA9IDY7XG4gKiAvLyBtb3JlIGF1ZGlibGUgb24gaGlnaGVyIG5vdGVzXG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvV2FoIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1dhaC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwic2Vuc2l0aXZpdHlcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBdXRvV2FoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBdXRvV2FoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYmFzZUZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJzZW5zaXRpdml0eVwiXSk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyID0gbmV3IEZvbGxvd2VyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHNtb290aGluZzogb3B0aW9ucy5mb2xsb3dlcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UgPSBuZXcgU2NhbGVFeHAoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgZXhwb25lbnQ6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KG9wdGlvbnMuYmFzZUZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX2lucHV0Qm9vc3QgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fYmFuZHBhc3MgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHJvbGxvZmY6IC00OCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIFE6IG9wdGlvbnMuUSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3BlYWtpbmcgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IFwicGVha2luZ1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wZWFraW5nLmdhaW4udmFsdWUgPSBvcHRpb25zLmdhaW47XG4gICAgICAgIHRoaXMuZ2FpbiA9IHRoaXMuX3BlYWtpbmcuZ2FpbjtcbiAgICAgICAgdGhpcy5RID0gdGhpcy5fYmFuZHBhc3MuUTtcbiAgICAgICAgLy8gdGhlIGNvbnRyb2wgc2lnbmFsIHBhdGhcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2lucHV0Qm9vc3QsIHRoaXMuX2ZvbGxvd2VyLCB0aGlzLl9zd2VlcFJhbmdlKTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5jb25uZWN0KHRoaXMuX2JhbmRwYXNzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuY29ubmVjdCh0aGlzLl9wZWFraW5nLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHRoZSBmaWx0ZXJlZCBwYXRoXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9iYW5kcGFzcywgdGhpcy5fcGVha2luZywgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgICAgICAvLyBzZXQgdGhlIGluaXRpYWwgdmFsdWVcbiAgICAgICAgdGhpcy5fc2V0U3dlZXBSYW5nZSgpO1xuICAgICAgICB0aGlzLnNlbnNpdGl2aXR5ID0gb3B0aW9ucy5zZW5zaXRpdml0eTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZ2FpblwiLCBcIlFcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiYXNlRnJlcXVlbmN5OiAxMDAsXG4gICAgICAgICAgICBvY3RhdmVzOiA2LFxuICAgICAgICAgICAgc2Vuc2l0aXZpdHk6IDAsXG4gICAgICAgICAgICBROiAyLFxuICAgICAgICAgICAgZ2FpbjogMixcbiAgICAgICAgICAgIGZvbGxvd2VyOiAwLjIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgdGhhdCB0aGUgZmlsdGVyIHdpbGwgc3dlZXAgYWJvdmUgdGhlIGJhc2VGcmVxdWVuY3kuXG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyhvY3RhdmVzKSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3RhdmVzO1xuICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmb2xsb3dlcidzIHNtb290aGluZyB0aW1lXG4gICAgICovXG4gICAgZ2V0IGZvbGxvd2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZm9sbG93ZXIuc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgZm9sbG93ZXIoZm9sbG93ZXIpIHtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIuc21vb3RoaW5nID0gZm9sbG93ZXI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlIGZyZXF1ZW5jeSBmcm9tIHdoaWNoIHRoZSBzd2VlcCB3aWxsIHN0YXJ0IGZyb20uXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShiYXNlRnJlcSkge1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShiYXNlRnJlcSk7XG4gICAgICAgIHRoaXMuX3NldFN3ZWVwUmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNlbnNpdGl2aXR5IHRvIGNvbnRyb2wgaG93IHJlc3BvbnNpdmUgdG8gdGhlIGlucHV0IHNpZ25hbCB0aGUgZmlsdGVyIGlzLlxuICAgICAqL1xuICAgIGdldCBzZW5zaXRpdml0eSgpIHtcbiAgICAgICAgcmV0dXJuIGdhaW5Ub0RiKDEgLyB0aGlzLl9pbnB1dEJvb3N0LmdhaW4udmFsdWUpO1xuICAgIH1cbiAgICBzZXQgc2Vuc2l0aXZpdHkoc2Vuc2l0aXZpdHkpIHtcbiAgICAgICAgdGhpcy5faW5wdXRCb29zdC5nYWluLnZhbHVlID0gMSAvIGRiVG9HYWluKHNlbnNpdGl2aXR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc2V0cyB0aGUgc3dlZXAgcmFuZ2Ugb2YgdGhlIHNjYWxlclxuICAgICAqL1xuICAgIF9zZXRTd2VlcFJhbmdlKCkge1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UubWF4ID0gTWF0aC5taW4odGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIHRoaXMuX29jdGF2ZXMpLCB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvIDIpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2JhbmRwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGVha2luZy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2lucHV0Qm9vc3QuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdXRvV2FoLmpzLm1hcCIsImltcG9ydCBcIi4uL2NvcmUvd29ya2xldC9TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgeyByZWdpc3RlclByb2Nlc3NvciB9IGZyb20gXCIuLi9jb3JlL3dvcmtsZXQvV29ya2xldEdsb2JhbFNjb3BlXCI7XG5leHBvcnQgY29uc3Qgd29ya2xldE5hbWUgPSBcImJpdC1jcnVzaGVyXCI7XG5leHBvcnQgY29uc3QgYml0Q3J1c2hlcldvcmtsZXQgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0Y2xhc3MgQml0Q3J1c2hlcldvcmtsZXQgZXh0ZW5kcyBTaW5nbGVJT1Byb2Nlc3NvciB7XG5cblx0XHRzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkge1xuXHRcdFx0cmV0dXJuIFt7XG5cdFx0XHRcdG5hbWU6IFwiYml0c1wiLFxuXHRcdFx0XHRkZWZhdWx0VmFsdWU6IDEyLFxuXHRcdFx0XHRtaW5WYWx1ZTogMSxcblx0XHRcdFx0bWF4VmFsdWU6IDE2LFxuXHRcdFx0XHRhdXRvbWF0aW9uUmF0ZTogJ2stcmF0ZSdcblx0XHRcdH1dO1xuXHRcdH1cblxuXHRcdGdlbmVyYXRlKGlucHV0LCBfY2hhbm5lbCwgcGFyYW1ldGVycykge1xuXHRcdFx0Y29uc3Qgc3RlcCA9IE1hdGgucG93KDAuNSwgcGFyYW1ldGVycy5iaXRzIC0gMSk7XG5cdFx0XHRjb25zdCB2YWwgPSBzdGVwICogTWF0aC5mbG9vcihpbnB1dCAvIHN0ZXAgKyAwLjUpO1xuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9XG5cdH1cbmA7XG5yZWdpc3RlclByb2Nlc3Nvcih3b3JrbGV0TmFtZSwgYml0Q3J1c2hlcldvcmtsZXQpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Qml0Q3J1c2hlci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb1dvcmtsZXQgfSBmcm9tIFwiLi4vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXRcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IHdvcmtsZXROYW1lIH0gZnJvbSBcIi4vQml0Q3J1c2hlci53b3JrbGV0XCI7XG4vKipcbiAqIEJpdENydXNoZXIgZG93bi1zYW1wbGVzIHRoZSBpbmNvbWluZyBzaWduYWwgdG8gYSBkaWZmZXJlbnQgYml0IGRlcHRoLlxuICogTG93ZXJpbmcgdGhlIGJpdCBkZXB0aCBvZiB0aGUgc2lnbmFsIGNyZWF0ZXMgZGlzdG9ydGlvbi4gUmVhZCBtb3JlIGFib3V0IEJpdENydXNoaW5nXG4gKiBvbiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CaXRjcnVzaGVyKS5cbiAqIEBleGFtcGxlXG4gKiAvLyBpbml0aWFsaXplIGNydXNoZXIgYW5kIHJvdXRlIGEgc3ludGggdGhyb3VnaCBpdFxuICogY29uc3QgY3J1c2hlciA9IG5ldyBUb25lLkJpdENydXNoZXIoNCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLmNvbm5lY3QoY3J1c2hlcik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkMyXCIsIDIpO1xuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEJpdENydXNoZXIgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYml0c1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkJpdENydXNoZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiaXRzXCJdKTtcbiAgICAgICAgdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQgPSBuZXcgQml0Q3J1c2hlcldvcmtsZXQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgYml0czogb3B0aW9ucy5iaXRzLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fYml0Q3J1c2hlcldvcmtsZXQpO1xuICAgICAgICB0aGlzLmJpdHMgPSB0aGlzLl9iaXRDcnVzaGVyV29ya2xldC5iaXRzO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiaXRzOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iaXRDcnVzaGVyV29ya2xldC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogSW50ZXJuYWwgY2xhc3Mgd2hpY2ggY3JlYXRlcyBhbiBBdWRpb1dvcmtsZXQgdG8gZG8gdGhlIGJpdCBjcnVzaGluZ1xuICovXG5jbGFzcyBCaXRDcnVzaGVyV29ya2xldCBleHRlbmRzIFRvbmVBdWRpb1dvcmtsZXQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyV29ya2xldC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJCaXRDcnVzaGVyV29ya2xldFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlcldvcmtsZXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmJpdHMgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuYml0cyxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICBtaW5WYWx1ZTogMSxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxNixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9kdW1teVBhcmFtLFxuICAgICAgICAgICAgc3dhcHBhYmxlOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Xb3JrbGV0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJpdHM6IDEyLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX2F1ZGlvV29ya2xldE5hbWUoKSB7XG4gICAgICAgIHJldHVybiB3b3JrbGV0TmFtZTtcbiAgICB9XG4gICAgb25SZWFkeShub2RlKSB7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcy5pbnB1dCwgbm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25zdCBiaXRzID0gbm9kZS5wYXJhbWV0ZXJzLmdldChcImJpdHNcIik7XG4gICAgICAgIHRoaXMuYml0cy5zZXRQYXJhbShiaXRzKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmJpdHMuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1CaXRDcnVzaGVyLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4uL3NpZ25hbC9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIENoZWJ5c2hldiBpcyBhIHdhdmVzaGFwZXIgd2hpY2ggaXMgZ29vZFxuICogZm9yIG1ha2luZyBkaWZmZXJlbnQgdHlwZXMgb2YgZGlzdG9ydGlvbiBzb3VuZHMuXG4gKiBOb3RlIHRoYXQgb2RkIG9yZGVycyBzb3VuZCB2ZXJ5IGRpZmZlcmVudCBmcm9tIGV2ZW4gb25lcyxcbiAqIGFuZCBvcmRlciA9IDEgaXMgbm8gY2hhbmdlLlxuICogUmVhZCBtb3JlIGF0IFttdXNpYy5jb2x1bWJpYS5lZHVdKGh0dHA6Ly9tdXNpYy5jb2x1bWJpYS5lZHUvY21jL211c2ljYW5kY29tcHV0ZXJzL2NoYXB0ZXI0LzA0XzA2LnBocCkuXG4gKiBAZXhhbXBsZVxuICogLy8gY3JlYXRlIGEgbmV3IGNoZWJ5XG4gKiBjb25zdCBjaGVieSA9IG5ldyBUb25lLkNoZWJ5c2hldig1MCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gY3JlYXRlIGEgbW9ub3N5bnRoIGNvbm5lY3RlZCB0byBvdXIgY2hlYnlcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTW9ub1N5bnRoKCkuY29ubmVjdChjaGVieSk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkMyXCIsIDAuNCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDaGVieXNoZXYgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGVieXNoZXYuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvcmRlclwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNoZWJ5c2hldlwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hlYnlzaGV2LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib3JkZXJcIl0pO1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsZW5ndGg6IDQwOTZcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX29yZGVyID0gb3B0aW9ucy5vcmRlcjtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX3NoYXBlcik7XG4gICAgICAgIHRoaXMub3JkZXIgPSBvcHRpb25zLm9yZGVyO1xuICAgICAgICB0aGlzLm92ZXJzYW1wbGUgPSBvcHRpb25zLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG9yZGVyOiAxLFxuICAgICAgICAgICAgb3ZlcnNhbXBsZTogXCJub25lXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGdldCB0aGUgY29lZmZpY2llbnQgZm9yIHRoYXQgZGVncmVlXG4gICAgICogQHBhcmFtICB4IHRoZSB4IHZhbHVlXG4gICAgICogQHBhcmFtICBkZWdyZWVcbiAgICAgKiBAcGFyYW0gIG1lbW8gbWVtb2l6ZSB0aGUgY29tcHV0ZWQgdmFsdWUuIHRoaXMgc3BlZWRzIHVwIGNvbXB1dGF0aW9uIGdyZWF0bHkuXG4gICAgICovXG4gICAgX2dldENvZWZmaWNpZW50KHgsIGRlZ3JlZSwgbWVtbykge1xuICAgICAgICBpZiAobWVtby5oYXMoZGVncmVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIG1lbW8uZ2V0KGRlZ3JlZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZGVncmVlID09PSAwKSB7XG4gICAgICAgICAgICBtZW1vLnNldChkZWdyZWUsIDApO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRlZ3JlZSA9PT0gMSkge1xuICAgICAgICAgICAgbWVtby5zZXQoZGVncmVlLCB4KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG1lbW8uc2V0KGRlZ3JlZSwgMiAqIHggKiB0aGlzLl9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUgLSAxLCBtZW1vKSAtIHRoaXMuX2dldENvZWZmaWNpZW50KHgsIGRlZ3JlZSAtIDIsIG1lbW8pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtby5nZXQoZGVncmVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9yZGVyIG9mIHRoZSBDaGVieXNoZXYgcG9seW5vbWlhbCB3aGljaCBjcmVhdGVzIHRoZSBlcXVhdGlvbiB3aGljaCBpcyBhcHBsaWVkIHRvIHRoZSBpbmNvbWluZ1xuICAgICAqIHNpZ25hbCB0aHJvdWdoIGEgVG9uZS5XYXZlU2hhcGVyLiBUaGUgZXF1YXRpb25zIGFyZSBpbiB0aGUgZm9ybTpcbiAgICAgKiBgYGBcbiAgICAgKiBvcmRlciAyOiAyeF4yICsgMVxuICAgICAqIG9yZGVyIDM6IDR4XjMgKyAzeFxuICAgICAqIGBgYFxuICAgICAqIEBtaW4gMVxuICAgICAqIEBtYXggMTAwXG4gICAgICovXG4gICAgZ2V0IG9yZGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3JkZXI7XG4gICAgfVxuICAgIHNldCBvcmRlcihvcmRlcikge1xuICAgICAgICB0aGlzLl9vcmRlciA9IG9yZGVyO1xuICAgICAgICB0aGlzLl9zaGFwZXIuc2V0TWFwKCh4ID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRDb2VmZmljaWVudCh4LCBvcmRlciwgbmV3IE1hcCgpKTtcbiAgICAgICAgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3ZlcnNhbXBsaW5nIG9mIHRoZSBlZmZlY3QuIENhbiBlaXRoZXIgYmUgXCJub25lXCIsIFwiMnhcIiBvciBcIjR4XCIuXG4gICAgICovXG4gICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZTtcbiAgICB9XG4gICAgc2V0IG92ZXJzYW1wbGUob3ZlcnNhbXBsaW5nKSB7XG4gICAgICAgIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlID0gb3ZlcnNhbXBsaW5nO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NoYXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNoZWJ5c2hldi5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogU3BsaXQgc3BsaXRzIGFuIGluY29taW5nIHNpZ25hbCBpbnRvIHRoZSBudW1iZXIgb2YgZ2l2ZW4gY2hhbm5lbHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNwbGl0ID0gbmV3IFRvbmUuU3BsaXQoKTtcbiAqIC8vIHN0ZXJlb1NpZ25hbC5jb25uZWN0KHNwbGl0KTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNwbGl0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTcGxpdFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNoYW5uZWxTcGxpdHRlcihvcHRpb25zLmNoYW5uZWxzKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9zcGxpdHRlcl07XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TcGxpdC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWVyZ2UgYnJpbmdzIG11bHRpcGxlIG1vbm8gaW5wdXQgY2hhbm5lbHMgaW50byBhIHNpbmdsZSBtdWx0aWNoYW5uZWwgb3V0cHV0IGNoYW5uZWwuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1lcmdlID0gbmV3IFRvbmUuTWVyZ2UoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyByb3V0aW5nIGEgc2luZSB0b25lIGluIHRoZSBsZWZ0IGNoYW5uZWxcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KG1lcmdlLCAwLCAwKS5zdGFydCgpO1xuICogLy8gYW5kIG5vaXNlIGluIHRoZSByaWdodCBjaGFubmVsXG4gKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKCkuY29ubmVjdChtZXJnZSwgMCwgMSkuc3RhcnQoKTs7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXJnZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXJnZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWVyZ2VcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1lcmdlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pO1xuICAgICAgICB0aGlzLl9tZXJnZXIgPSB0aGlzLm91dHB1dCA9IHRoaXMuaW5wdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ2hhbm5lbE1lcmdlcihvcHRpb25zLmNoYW5uZWxzKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tZXJnZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NZXJnZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0LCBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBDcm9zc0ZhZGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvQ3Jvc3NGYWRlXCI7XG5pbXBvcnQgeyBTcGxpdCB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9TcGxpdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWVyZ2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgU3RlcmVvIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9FZmZlY3QgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN0ZXJlb0VmZmVjdFwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8vIGZvcmNlIG1vbm8gc291cmNlcyB0byBiZSBzdGVyZW9cbiAgICAgICAgdGhpcy5pbnB1dC5jaGFubmVsQ291bnQgPSAyO1xuICAgICAgICB0aGlzLmlucHV0LmNoYW5uZWxDb3VudE1vZGUgPSBcImV4cGxpY2l0XCI7XG4gICAgICAgIHRoaXMuX2RyeVdldCA9IHRoaXMub3V0cHV0ID0gbmV3IENyb3NzRmFkZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmYWRlOiBvcHRpb25zLndldFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy53ZXQgPSB0aGlzLl9kcnlXZXQuZmFkZTtcbiAgICAgICAgdGhpcy5fc3BsaXQgPSBuZXcgU3BsaXQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICB0aGlzLl9tZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIC8vIGRyeSB3ZXQgY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX2RyeVdldC5hKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuY29ubmVjdCh0aGlzLl9kcnlXZXQuYik7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIndldFwiXSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIGxlZnQgcGFydCBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdExlZnQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdChub2Rlc1swXSwgMCwgMCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXMoLi4ubm9kZXMpO1xuICAgICAgICBjb25uZWN0KG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdLCB0aGlzLl9tZXJnZSwgMCwgMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIHJpZ2h0IHBhcnQgb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RSaWdodCguLi5ub2Rlcykge1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KG5vZGVzWzBdLCAxLCAwKTtcbiAgICAgICAgY29ubmVjdFNlcmllcyguLi5ub2Rlcyk7XG4gICAgICAgIGNvbm5lY3Qobm9kZXNbbm9kZXMubGVuZ3RoIC0gMV0sIHRoaXMuX21lcmdlLCAwLCAxKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHdldDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHJ5V2V0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9FZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9FZmZlY3RcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTcGxpdCB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9TcGxpdFwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWVyZ2VcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3Igc3RlcmVvIGZlZWRiYWNrIGVmZmVjdHMgd2hlcmUgdGhlIGVmZmVjdFJldHVybiBpcyBmZWQgYmFjayBpbnRvIHRoZSBzYW1lIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9GZWVkYmFja0VmZmVjdCBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5mZWVkYmFjayA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZmVlZGJhY2ssXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tSID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrU3BsaXQgPSBuZXcgU3BsaXQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja01lcmdlID0gbmV3IE1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuY29ubmVjdCh0aGlzLl9mZWVkYmFja1NwbGl0KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZS5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgLy8gdGhlIGxlZnQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgbGVmdCBpbnB1dFxuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0LmNvbm5lY3QodGhpcy5fZmVlZGJhY2tMLCAwLCAwKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tNZXJnZSwgMCwgMCk7XG4gICAgICAgIC8vIHRoZSByaWdodCBvdXRwdXQgY29ubmVjdGVkIHRvIHRoZSByaWdodCBpbnB1dFxuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0LmNvbm5lY3QodGhpcy5fZmVlZGJhY2tSLCAxLCAwKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tSLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tNZXJnZSwgMCwgMSk7XG4gICAgICAgIC8vIHRoZSBmZWVkYmFjayBjb250cm9sXG4gICAgICAgIHRoaXMuZmVlZGJhY2suZmFuKHRoaXMuX2ZlZWRiYWNrTC5nYWluLCB0aGlzLl9mZWVkYmFja1IuZ2Fpbik7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZlZWRiYWNrXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmVlZGJhY2s6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mZWVkYmFjay5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrU3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja01lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvRmVlZGJhY2tFZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi4vZWZmZWN0L1N0ZXJlb0ZlZWRiYWNrRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBDaG9ydXMgaXMgYSBzdGVyZW8gY2hvcnVzIGVmZmVjdCBjb21wb3NlZCBvZiBhIGxlZnQgYW5kIHJpZ2h0IGRlbGF5IHdpdGggYW4gW1tMRk9dXSBhcHBsaWVkIHRvIHRoZSBkZWxheVRpbWUgb2YgZWFjaCBjaGFubmVsLlxuICogV2hlbiBbW2ZlZWRiYWNrXV0gaXMgc2V0IHRvIGEgdmFsdWUgbGFyZ2VyIHRoYW4gMCwgeW91IGFsc28gZ2V0IEZsYW5nZXItdHlwZSBlZmZlY3RzLlxuICogSW5zcGlyYXRpb24gZnJvbSBbVHVuYS5qc10oaHR0cHM6Ly9naXRodWIuY29tL0RpbmFobW9lL3R1bmEvYmxvYi9tYXN0ZXIvdHVuYS5qcykuXG4gKiBSZWFkIG1vcmUgb24gdGhlIGNob3J1cyBlZmZlY3Qgb24gW1NvdW5kT25Tb3VuZF0oaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9qdW4wNC9hcnRpY2xlcy9zeW50aHNlY3JldHMuaHRtKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY2hvcnVzID0gbmV3IFRvbmUuQ2hvcnVzKDQsIDIuNSwgMC41KS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKCkuY29ubmVjdChjaG9ydXMpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoW1wiQzNcIiwgXCJFM1wiLCBcIkczXCJdLCBcIjhuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIENob3J1cyBleHRlbmRzIFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hvcnVzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVsYXlUaW1lXCIsIFwiZGVwdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDaG9ydXNcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENob3J1cy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlbGF5VGltZVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5fZGVwdGggPSBvcHRpb25zLmRlcHRoO1xuICAgICAgICB0aGlzLl9kZWxheVRpbWUgPSBvcHRpb25zLmRlbGF5VGltZSAvIDEwMDA7XG4gICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9SID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgcGhhc2U6IDE4MFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlTCA9IG5ldyBEZWxheSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlUiA9IG5ldyBEZWxheSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm9MLmZyZXF1ZW5jeTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCJdKTtcbiAgICAgICAgLy8gaGF2ZSBvbmUgTEZPIGZyZXF1ZW5jeSBjb250cm9sIHRoZSBvdGhlclxuICAgICAgICB0aGlzLl9sZm9MLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2xmb1IuZnJlcXVlbmN5KTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9kZWxheU5vZGVMKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQodGhpcy5fZGVsYXlOb2RlUik7XG4gICAgICAgIC8vIGxmbyBzZXR1cFxuICAgICAgICB0aGlzLl9sZm9MLmNvbm5lY3QodGhpcy5fZGVsYXlOb2RlTC5kZWxheVRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLmNvbm5lY3QodGhpcy5fZGVsYXlOb2RlUi5kZWxheVRpbWUpO1xuICAgICAgICAvLyBzZXQgdGhlIGluaXRpYWwgdmFsdWVzXG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9kZXB0aDtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLnNwcmVhZCA9IG9wdGlvbnMuc3ByZWFkO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0ZlZWRiYWNrRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMS41LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAzLjUsXG4gICAgICAgICAgICBkZXB0aDogMC43LFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgICAgICBzcHJlYWQ6IDE4MCxcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwLFxuICAgICAgICAgICAgd2V0OiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGVwdGggb2YgdGhlIGVmZmVjdC4gQSBkZXB0aCBvZiAxIG1ha2VzIHRoZSBkZWxheVRpbWVcbiAgICAgKiBtb2R1bGF0ZSBiZXR3ZWVuIDAgYW5kIDIqZGVsYXlUaW1lIChjZW50ZXJlZCBhcm91bmQgdGhlIGRlbGF5VGltZSkuXG4gICAgICovXG4gICAgZ2V0IGRlcHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVwdGg7XG4gICAgfVxuICAgIHNldCBkZXB0aChkZXB0aCkge1xuICAgICAgICB0aGlzLl9kZXB0aCA9IGRlcHRoO1xuICAgICAgICBjb25zdCBkZXZpYXRpb24gPSB0aGlzLl9kZWxheVRpbWUgKiBkZXB0aDtcbiAgICAgICAgdGhpcy5fbGZvTC5taW4gPSBNYXRoLm1heCh0aGlzLl9kZWxheVRpbWUgLSBkZXZpYXRpb24sIDApO1xuICAgICAgICB0aGlzLl9sZm9MLm1heCA9IHRoaXMuX2RlbGF5VGltZSArIGRldmlhdGlvbjtcbiAgICAgICAgdGhpcy5fbGZvUi5taW4gPSBNYXRoLm1heCh0aGlzLl9kZWxheVRpbWUgLSBkZXZpYXRpb24sIDApO1xuICAgICAgICB0aGlzLl9sZm9SLm1heCA9IHRoaXMuX2RlbGF5VGltZSArIGRldmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRlbGF5VGltZSBpbiBtaWxsaXNlY29uZHMgb2YgdGhlIGNob3J1cy4gQSBsYXJnZXIgZGVsYXlUaW1lXG4gICAgICogd2lsbCBnaXZlIGEgbW9yZSBwcm9ub3VuY2VkIGVmZmVjdC4gTm9taW5hbCByYW5nZSBhIGRlbGF5VGltZVxuICAgICAqIGlzIGJldHdlZW4gMiBhbmQgMjBtcy5cbiAgICAgKi9cbiAgICBnZXQgZGVsYXlUaW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVsYXlUaW1lICogMTAwMDtcbiAgICB9XG4gICAgc2V0IGRlbGF5VGltZShkZWxheVRpbWUpIHtcbiAgICAgICAgdGhpcy5fZGVsYXlUaW1lID0gZGVsYXlUaW1lIC8gMTAwMDtcbiAgICAgICAgdGhpcy5kZXB0aCA9IHRoaXMuX2RlcHRoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlIG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9MLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fbGZvUi50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQW1vdW50IG9mIHN0ZXJlbyBzcHJlYWQuIFdoZW4gc2V0IHRvIDAsIGJvdGggTEZPJ3Mgd2lsbCBiZSBwYW5uZWQgY2VudHJhbGx5LlxuICAgICAqIFdoZW4gc2V0IHRvIDE4MCwgTEZPJ3Mgd2lsbCBiZSBwYW5uZWQgaGFyZCBsZWZ0IGFuZCByaWdodCByZXNwZWN0aXZlbHkuXG4gICAgICovXG4gICAgZ2V0IHNwcmVhZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmb1IucGhhc2UgLSB0aGlzLl9sZm9MLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgc3ByZWFkKHNwcmVhZCkge1xuICAgICAgICB0aGlzLl9sZm9MLnBoYXNlID0gOTAgLSAoc3ByZWFkIC8gMik7XG4gICAgICAgIHRoaXMuX2xmb1IucGhhc2UgPSAoc3ByZWFkIC8gMikgKyA5MDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGVmZmVjdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RhcnQodGltZSk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBsZm9cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBmaWx0ZXIgdG8gdGhlIHRyYW5zcG9ydC4gU2VlIFtbTEZPLnN5bmNdXVxuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1IudW5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9SLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZVIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNob3J1cy5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi4vc2lnbmFsL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuLyoqXG4gKiBBIHNpbXBsZSBkaXN0b3J0aW9uIGVmZmVjdCB1c2luZyBUb25lLldhdmVTaGFwZXIuXG4gKiBBbGdvcml0aG0gZnJvbSBbdGhpcyBzdGFja292ZXJmbG93IGFuc3dlcl0oaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjIzMTM0MDgpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkaXN0ID0gbmV3IFRvbmUuRGlzdG9ydGlvbigwLjgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGZtID0gbmV3IFRvbmUuRk1TeW50aCgpLmNvbm5lY3QoZGlzdCk7XG4gKiBmbS50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkExXCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBEaXN0b3J0aW9uIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRGlzdG9ydGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRpc3RvcnRpb25cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEaXN0b3J0aW9uXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEaXN0b3J0aW9uLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGlzdG9ydGlvblwiXSk7XG4gICAgICAgIHRoaXMuX3NoYXBlciA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxlbmd0aDogNDA5NixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Rpc3RvcnRpb24gPSBvcHRpb25zLmRpc3RvcnRpb247XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9zaGFwZXIpO1xuICAgICAgICB0aGlzLmRpc3RvcnRpb24gPSBvcHRpb25zLmRpc3RvcnRpb247XG4gICAgICAgIHRoaXMub3ZlcnNhbXBsZSA9IG9wdGlvbnMub3ZlcnNhbXBsZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGlzdG9ydGlvbjogMC40LFxuICAgICAgICAgICAgb3ZlcnNhbXBsZTogXCJub25lXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IG9mIGRpc3RvcnRpb24uIE5vbWluYWwgcmFuZ2UgaXMgYmV0d2VlbiAwIGFuZCAxLlxuICAgICAqL1xuICAgIGdldCBkaXN0b3J0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGlzdG9ydGlvbjtcbiAgICB9XG4gICAgc2V0IGRpc3RvcnRpb24oYW1vdW50KSB7XG4gICAgICAgIHRoaXMuX2Rpc3RvcnRpb24gPSBhbW91bnQ7XG4gICAgICAgIGNvbnN0IGsgPSBhbW91bnQgKiAxMDA7XG4gICAgICAgIGNvbnN0IGRlZyA9IE1hdGguUEkgLyAxODA7XG4gICAgICAgIHRoaXMuX3NoYXBlci5zZXRNYXAoKHgpID0+IHtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyh4KSA8IDAuMDAxKSB7XG4gICAgICAgICAgICAgICAgLy8gc2hvdWxkIG91dHB1dCAwIHdoZW4gaW5wdXQgaXMgMFxuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuICgzICsgaykgKiB4ICogMjAgKiBkZWcgLyAoTWF0aC5QSSArIGsgKiBNYXRoLmFicyh4KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3ZlcnNhbXBsaW5nIG9mIHRoZSBlZmZlY3QuIENhbiBlaXRoZXIgYmUgXCJub25lXCIsIFwiMnhcIiBvciBcIjR4XCIuXG4gICAgICovXG4gICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZTtcbiAgICB9XG4gICAgc2V0IG92ZXJzYW1wbGUob3ZlcnNhbXBsaW5nKSB7XG4gICAgICAgIHRoaXMuX3NoYXBlci5vdmVyc2FtcGxlID0gb3ZlcnNhbXBsaW5nO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NoYXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURpc3RvcnRpb24uanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG4vKipcbiAqIEZlZWRiYWNrRWZmZWN0IHByb3ZpZGVzIGEgbG9vcCBiZXR3ZWVuIGFuIGF1ZGlvIHNvdXJjZSBhbmQgaXRzIG93biBvdXRwdXQuXG4gKiBUaGlzIGlzIGEgYmFzZS1jbGFzcyBmb3IgZmVlZGJhY2sgZWZmZWN0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIEZlZWRiYWNrRWZmZWN0IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZlZWRiYWNrRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMuZmVlZGJhY2ssXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mZWVkYmFjayA9IHRoaXMuX2ZlZWRiYWNrR2Fpbi5nYWluO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZlZWRiYWNrXCIpO1xuICAgICAgICAvLyB0aGUgZmVlZGJhY2sgbG9vcFxuICAgICAgICB0aGlzLmVmZmVjdFJldHVybi5jaGFpbih0aGlzLl9mZWVkYmFja0dhaW4sIHRoaXMuZWZmZWN0U2VuZCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwLjEyNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tHYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mZWVkYmFjay5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL0ZlZWRiYWNrRWZmZWN0XCI7XG4vKipcbiAqIEZlZWRiYWNrRGVsYXkgaXMgYSBEZWxheU5vZGUgaW4gd2hpY2ggcGFydCBvZiBvdXRwdXQgc2lnbmFsIGlzIGZlZCBiYWNrIGludG8gdGhlIGRlbGF5LlxuICpcbiAqIEBwYXJhbSBkZWxheVRpbWUgVGhlIGRlbGF5IGFwcGxpZWQgdG8gdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIEBwYXJhbSBmZWVkYmFjayBUaGUgYW1vdW50IG9mIHRoZSBlZmZlY3RlZCBzaWduYWwgd2hpY2ggaXMgZmVkIGJhY2sgdGhyb3VnaCB0aGUgZGVsYXkuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmVlZGJhY2tEZWxheSA9IG5ldyBUb25lLkZlZWRiYWNrRGVsYXkoXCI4blwiLCAwLjUpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHRvbSA9IG5ldyBUb25lLk1lbWJyYW5lU3ludGgoe1xuICogXHRvY3RhdmVzOiA0LFxuICogXHRwaXRjaERlY2F5OiAwLjFcbiAqIH0pLmNvbm5lY3QoZmVlZGJhY2tEZWxheSk7XG4gKiB0b20udHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBMlwiLCBcIjMyblwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEZlZWRiYWNrRGVsYXkgZXh0ZW5kcyBGZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJmZWVkYmFja1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZlZWRiYWNrRGVsYXlcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrRGVsYXkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJmZWVkYmFja1wiXSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZWxheVRpbWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IHRoaXMuX2RlbGF5Tm9kZS5kZWxheVRpbWU7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX2RlbGF5Tm9kZSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZGVsYXlUaW1lXCIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEZlZWRiYWNrRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMC4yNSxcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZlZWRiYWNrRGVsYXkuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBQaGFzZVNoaWZ0QWxscGFzcyBpcyBhbiB2ZXJ5IGVmZmljaWVudCBpbXBsZW1lbnRhdGlvbiBvZiBhIEhpbGJlcnQgVHJhbnNmb3JtXG4gKiB1c2luZyB0d28gQWxscGFzcyBmaWx0ZXIgYmFua3Mgd2hvc2Ugb3V0cHV0cyBoYXZlIGEgcGhhc2UgZGlmZmVyZW5jZSBvZiA5MMKwLlxuICogSGVyZSB0aGUgYG9mZnNldDkwYCBwaGFzZSBpcyBvZmZzZXQgYnkgKzkwwrAgaW4gcmVsYXRpb24gdG8gYG91dHB1dGAuXG4gKiBDb2VmZmljaWVudHMgYW5kIHN0cnVjdHVyZSB3YXMgZGV2ZWxvcGVkIGJ5IE9sbGkgTmllbWl0YWxvLlxuICogRm9yIG1vcmUgZGV0YWlscyBzZWU6IGh0dHA6Ly95ZWhhci5jb20vYmxvZy8/cD0zNjhcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBoYXNlU2hpZnRBbGxwYXNzIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQaGFzZVNoaWZ0QWxscGFzc1wiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcGhhc2Ugc2hpZnRlZCBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgUGhhc2VTaGlmdGVkIGFsbHBhc3Mgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9mZnNldDkwID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIGNvbnN0IGFsbHBhc3NCYW5rMVZhbHVlcyA9IFswLjY5MjM4NzgsIDAuOTM2MDY1NDMyMjk1OSwgMC45ODgyMjk1MjI2ODYwLCAwLjk5ODc0ODg0NTI3MzddO1xuICAgICAgICBjb25zdCBhbGxwYXNzQmFuazJWYWx1ZXMgPSBbMC40MDIxOTIxMTYyNDI2LCAwLjg1NjE3MTA4ODI0MjAsIDAuOTcyMjkwOTU0NTY1MSwgMC45OTUyODg0NzkxMjc4XTtcbiAgICAgICAgdGhpcy5fYmFuazAgPSB0aGlzLl9jcmVhdGVBbGxQYXNzRmlsdGVyQmFuayhhbGxwYXNzQmFuazFWYWx1ZXMpO1xuICAgICAgICB0aGlzLl9iYW5rMSA9IHRoaXMuX2NyZWF0ZUFsbFBhc3NGaWx0ZXJCYW5rKGFsbHBhc3NCYW5rMlZhbHVlcyk7XG4gICAgICAgIHRoaXMuX29uZVNhbXBsZURlbGF5ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihbMC4wLCAxLjBdLCBbMS4wLCAwLjBdKTtcbiAgICAgICAgLy8gY29ubmVjdCBBbGxwYXNzIGZpbHRlciBiYW5rc1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIC4uLnRoaXMuX2JhbmswLCB0aGlzLl9vbmVTYW1wbGVEZWxheSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIC4uLnRoaXMuX2JhbmsxLCB0aGlzLm9mZnNldDkwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGFsbCBvZiB0aGUgSUlSIGZpbHRlcnMgZnJvbSBhbiBhcnJheSBvZiB2YWx1ZXMgdXNpbmcgdGhlIGNvZWZmaWNpZW50IGNhbGN1bGF0aW9uLlxuICAgICAqL1xuICAgIF9jcmVhdGVBbGxQYXNzRmlsdGVyQmFuayhiYW5rVmFsdWVzKSB7XG4gICAgICAgIGNvbnN0IG5vZGVzID0gYmFua1ZhbHVlcy5tYXAodmFsdWUgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29lZmZpY2llbnRzID0gW1t2YWx1ZSAqIHZhbHVlLCAwLCAtMV0sIFsxLCAwLCAtKHZhbHVlICogdmFsdWUpXV07XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LmNyZWF0ZUlJUkZpbHRlcihjb2VmZmljaWVudHNbMF0sIGNvZWZmaWNpZW50c1sxXSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbm9kZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vZmZzZXQ5MC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2JhbmswLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2JhbmsxLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX29uZVNhbXBsZURlbGF5LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGhhc2VTaGlmdEFsbHBhc3MuanMubWFwIiwiaW1wb3J0IHsgUGhhc2VTaGlmdEFsbHBhc3MgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9QaGFzZVNoaWZ0QWxscGFzc1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi4vZWZmZWN0L0VmZmVjdFwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgTmVnYXRlIH0gZnJvbSBcIi4uL3NpZ25hbC9OZWdhdGVcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IFRvbmVPc2NpbGxhdG9yTm9kZSB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9Ub25lT3NjaWxsYXRvck5vZGVcIjtcbi8qKlxuICogRnJlcXVlbmN5U2hpZnRlciBjYW4gYmUgdXNlZCB0byBzaGlmdCBhbGwgZnJlcXVlbmNpZXMgb2YgYSBzaWduYWwgYnkgYSBmaXhlZCBhbW91bnQuXG4gKiBUaGUgYW1vdW50IGNhbiBiZSBjaGFuZ2VkIGF0IGF1ZGlvIHJhdGUgYW5kIHRoZSBlZmZlY3QgaXMgYXBwbGllZCBpbiByZWFsIHRpbWUuXG4gKiBUaGUgZnJlcXVlbmN5IHNoaWZ0aW5nIGlzIGltcGxlbWVudGVkIHdpdGggYSB0ZWNobmlxdWUgY2FsbGVkIHNpbmdsZSBzaWRlIGJhbmQgbW9kdWxhdGlvbiB1c2luZyBhIHJpbmcgbW9kdWxhdG9yLlxuICogTm90ZTogQ29udHJhcnkgdG8gcGl0Y2ggc2hpZnRpbmcsIGFsbCBmcmVxdWVuY2llcyBhcmUgc2hpZnRlZCBieSB0aGUgc2FtZSBhbW91bnQsXG4gKiBkZXN0cm95aW5nIHRoZSBoYXJtb25pYyByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGVtLiBUaGlzIGxlYWRzIHRvIHRoZSBjbGFzc2ljIHJpbmcgbW9kdWxhdG9yIHRpbWJyZSBkaXN0b3J0aW9uLlxuICogVGhlIGFsZ29yaXRobSB3aWxsIHByb2R1Y2VzIHNvbWUgYWxpYXNpbmcgdG93YXJkcyB0aGUgaGlnaCBlbmQsIGVzcGVjaWFsbHkgaWYgeW91ciBzb3VyY2UgbWF0ZXJpYWxcbiAqIGNvbnRhaW5zIGEgbG90IG9mIGhpZ2ggZnJlcXVlbmNpZXMuIFVuZm9ydHVuYXRlbGx5IHRoZSB3ZWJhdWRpbyBBUEkgZG9lcyBub3Qgc3VwcG9ydCByZXNhbXBsaW5nXG4gKiBidWZmZXJzIGluIHJlYWwgdGltZSwgc28gaXQgaXMgbm90IHBvc3NpYmxlIHRvIGZpeCBpdCBwcm9wZXJseS4gRGVwZW5kaW5nIG9uIHRoZSB1c2UgY2FzZSBpdCBtaWdodFxuICogYmUgYW4gb3B0aW9uIHRvIGxvdyBwYXNzIGZpbHRlciB5b3VyIGlucHV0IGJlZm9yZSBmcmVxdWVuY3kgc2hpZnRpbmcgaXQgdG8gZ2V0IHJpZGUgb2YgdGhlIGFsaWFzaW5nLlxuICogWW91IGNhbiBmaW5kIGEgdmVyeSBkZXRhaWxlZCBkZXNjcmlwdGlvbiBvZiB0aGUgYWxnb3JpdGhtIGhlcmU6IGh0dHBzOi8vbGFyemVpdGxpbi5naXRodWIuaW8vUk1GUy9cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgaW5wdXQgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKDIzMCwgXCJzYXd0b290aFwiKS5zdGFydCgpO1xuICogY29uc3Qgc2hpZnQgPSBuZXcgVG9uZS5GcmVxdWVuY3lTaGlmdGVyKDQyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBpbnB1dC5jb25uZWN0KHNoaWZ0KTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZXF1ZW5jeVNoaWZ0ZXIgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lTaGlmdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlcXVlbmN5U2hpZnRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5U2hpZnRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pblZhbHVlOiAtdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAyLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpbmUgPSBuZXcgVG9uZU9zY2lsbGF0b3JOb2RlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY29zaW5lID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGhhc2U6IC05MCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2luZU11bHRpcGx5ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9jb3NpbmVNdWx0aXBseSA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbmVnYXRlID0gbmV3IE5lZ2F0ZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fYWRkID0gbmV3IEFkZCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyID0gbmV3IFBoYXNlU2hpZnRBbGxwYXNzKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY29ubmVjdCh0aGlzLl9waGFzZVNoaWZ0ZXIpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBjYXJyaWVyIGZyZXF1ZW5jeSBzaWduYWwgdG8gdGhlIHR3byBvc2NpbGxhdG9yc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5mYW4odGhpcy5fc2luZS5mcmVxdWVuY3ksIHRoaXMuX2Nvc2luZS5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIub2Zmc2V0OTAuY29ubmVjdCh0aGlzLl9jb3NpbmVNdWx0aXBseSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZS5jb25uZWN0KHRoaXMuX2Nvc2luZU11bHRpcGx5LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlci5jb25uZWN0KHRoaXMuX3NpbmVNdWx0aXBseSk7XG4gICAgICAgIHRoaXMuX3NpbmUuY29ubmVjdCh0aGlzLl9zaW5lTXVsdGlwbHkuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5fc2luZU11bHRpcGx5LmNvbm5lY3QodGhpcy5fbmVnYXRlKTtcbiAgICAgICAgdGhpcy5fY29zaW5lTXVsdGlwbHkuY29ubmVjdCh0aGlzLl9hZGQpO1xuICAgICAgICB0aGlzLl9uZWdhdGUuY29ubmVjdCh0aGlzLl9hZGQuYWRkZW5kKTtcbiAgICAgICAgdGhpcy5fYWRkLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgICAgICAvLyBzdGFydCB0aGUgb3NjaWxsYXRvcnMgYXQgdGhlIHNhbWUgdGltZVxuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmltbWVkaWF0ZSgpO1xuICAgICAgICB0aGlzLl9zaW5lLnN0YXJ0KG5vdyk7XG4gICAgICAgIHRoaXMuX2Nvc2luZS5zdGFydChub3cpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWRkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29zaW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29zaW5lTXVsdGlwbHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9uZWdhdGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2luZU11bHRpcGx5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlcXVlbmN5U2hpZnRlci5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9FZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IExvd3Bhc3NDb21iRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXJcIjtcbi8qKlxuICogQW4gYXJyYXkgb2YgY29tYiBmaWx0ZXIgZGVsYXkgdmFsdWVzIGZyb20gRnJlZXZlcmIgaW1wbGVtZW50YXRpb25cbiAqL1xuY29uc3QgY29tYkZpbHRlclR1bmluZ3MgPSBbMTU1NyAvIDQ0MTAwLCAxNjE3IC8gNDQxMDAsIDE0OTEgLyA0NDEwMCwgMTQyMiAvIDQ0MTAwLCAxMjc3IC8gNDQxMDAsIDEzNTYgLyA0NDEwMCwgMTE4OCAvIDQ0MTAwLCAxMTE2IC8gNDQxMDBdO1xuLyoqXG4gKiBBbiBhcnJheSBvZiBhbGxwYXNzIGZpbHRlciBmcmVxdWVuY3kgdmFsdWVzIGZyb20gRnJlZXZlcmIgaW1wbGVtZW50YXRpb25cbiAqL1xuY29uc3QgYWxscGFzc0ZpbHRlckZyZXF1ZW5jaWVzID0gWzIyNSwgNTU2LCA0NDEsIDM0MV07XG4vKipcbiAqIEZyZWV2ZXJiIGlzIGEgcmV2ZXJiIGJhc2VkIG9uIFtGcmVldmVyYl0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL0ZyZWV2ZXJiLmh0bWwpLlxuICogUmVhZCBtb3JlIG9uIHJldmVyYiBvbiBbU291bmQgT24gU291bmRdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwNDA4MzkwMi9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb206ODAvc29zL2ZlYjAxL2FydGljbGVzL3N5bnRoc2VjcmV0cy5hc3ApLlxuICogRnJlZXZlcmIgaXMgbm93IGltcGxlbWVudGVkIHdpdGggYW4gQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBtYXkgcmVzdWx0IG9uIHBlcmZvcm1hbmNlIGRlZ3JhZGF0aW9uIG9uIHNvbWUgcGxhdGZvcm1zLiBDb25zaWRlciB1c2luZyBbW1JldmVyYl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZyZWV2ZXJiID0gbmV3IFRvbmUuRnJlZXZlcmIoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBmcmVldmVyYi5kYW1wZW5pbmcgPSAxMDAwO1xuICogLy8gcm91dGluZyBzeW50aCB0aHJvdWdoIHRoZSByZXZlcmJcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTm9pc2VTeW50aCgpLmNvbm5lY3QoZnJlZXZlcmIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoMC4wNSk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVldmVyYiBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZWV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIiwgXCJkYW1wZW5pbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVldmVyYlwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGNvbWIgZmlsdGVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIGxlZnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTCA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGFsbHBhc3MgZmlsdGVycyBvbiB0aGUgcmlnaHRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzUiA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiLCBcImRhbXBlbmluZ1wiXSk7XG4gICAgICAgIHRoaXMucm9vbVNpemUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnJvb21TaXplLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGFsbHBhc3MgZmlsdGVycyBvbiB0aGUgcmlnaHRcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMID0gYWxscGFzc0ZpbHRlckZyZXF1ZW5jaWVzLm1hcChmcmVxID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFsbHBhc3NMID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzc0wudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgYWxscGFzc0wuZnJlcXVlbmN5LnZhbHVlID0gZnJlcTtcbiAgICAgICAgICAgIHJldHVybiBhbGxwYXNzTDtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGFsbHBhc3MgZmlsdGVycyBvbiB0aGUgbGVmdFxuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1IgPSBhbGxwYXNzRmlsdGVyRnJlcXVlbmNpZXMubWFwKGZyZXEgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWxscGFzc1IgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBhbGxwYXNzUi50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICBhbGxwYXNzUi5mcmVxdWVuY3kudmFsdWUgPSBmcmVxO1xuICAgICAgICAgICAgcmV0dXJuIGFsbHBhc3NSO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gbWFrZSB0aGUgY29tYiBmaWx0ZXJzXG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzID0gY29tYkZpbHRlclR1bmluZ3MubWFwKChkZWxheVRpbWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBsZnBmID0gbmV3IExvd3Bhc3NDb21iRmlsdGVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgZGFtcGVuaW5nOiBvcHRpb25zLmRhbXBlbmluZyxcbiAgICAgICAgICAgICAgICBkZWxheVRpbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8IGNvbWJGaWx0ZXJUdW5pbmdzLmxlbmd0aCAvIDIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KGxmcGYsIC4uLnRoaXMuX2FsbHBhc3NGaWx0ZXJzTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodChsZnBmLCAuLi50aGlzLl9hbGxwYXNzRmlsdGVyc1IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yb29tU2l6ZS5jb25uZWN0KGxmcGYucmVzb25hbmNlKTtcbiAgICAgICAgICAgIHJldHVybiBsZnBmO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicm9vbVNpemVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICByb29tU2l6ZTogMC43LFxuICAgICAgICAgICAgZGFtcGVuaW5nOiAzMDAwXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IG9mIGRhbXBlbmluZyBvZiB0aGUgcmV2ZXJiZXJhbnQgc2lnbmFsLlxuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb21iRmlsdGVyc1swXS5kYW1wZW5pbmc7XG4gICAgfVxuICAgIHNldCBkYW1wZW5pbmcoZCkge1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycy5mb3JFYWNoKGMgPT4gYy5kYW1wZW5pbmcgPSBkKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wuZm9yRWFjaChhbCA9PiBhbC5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1IuZm9yRWFjaChhciA9PiBhci5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycy5mb3JFYWNoKGNmID0+IGNmLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMucm9vbVNpemUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVldmVyYi5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9FZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2NhbGUgfSBmcm9tIFwiLi4vc2lnbmFsL1NjYWxlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgRmVlZGJhY2tDb21iRmlsdGVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIGFuIGFycmF5IG9mIHRoZSBjb21iIGZpbHRlciBkZWxheSB0aW1lIHZhbHVlc1xuICovXG5jb25zdCBjb21iRmlsdGVyRGVsYXlUaW1lcyA9IFsxNjg3IC8gMjUwMDAsIDE2MDEgLyAyNTAwMCwgMjA1MyAvIDI1MDAwLCAyMjUxIC8gMjUwMDBdO1xuLyoqXG4gKiB0aGUgcmVzb25hbmNlcyBvZiBlYWNoIG9mIHRoZSBjb21iIGZpbHRlcnNcbiAqL1xuY29uc3QgY29tYkZpbHRlclJlc29uYW5jZXMgPSBbMC43NzMsIDAuODAyLCAwLjc1MywgMC43MzNdO1xuLyoqXG4gKiB0aGUgYWxscGFzcyBmaWx0ZXIgZnJlcXVlbmNpZXNcbiAqL1xuY29uc3QgYWxscGFzc0ZpbHRlckZyZXFzID0gWzM0NywgMTEzLCAzN107XG4vKipcbiAqIEpDUmV2ZXJiIGlzIGEgc2ltcGxlIFtTY2hyb2VkZXIgUmV2ZXJiZXJhdG9yXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvU2Nocm9lZGVyX1JldmVyYmVyYXRvcnMuaHRtbClcbiAqIHR1bmVkIGJ5IEpvaG4gQ2hvd25pbmcgaW4gMTk3MC5cbiAqIEl0IGlzIG1hZGUgdXAgb2YgdGhyZWUgYWxscGFzcyBmaWx0ZXJzIGFuZCBmb3VyIFtbRmVlZGJhY2tDb21iRmlsdGVyXV0uXG4gKiBKQ1JldmVyYiBpcyBub3cgaW1wbGVtZW50ZWQgd2l0aCBhbiBBdWRpb1dvcmtsZXROb2RlIHdoaWNoIG1heSByZXN1bHQgb24gcGVyZm9ybWFuY2UgZGVncmFkYXRpb24gb24gc29tZSBwbGF0Zm9ybXMuIENvbnNpZGVyIHVzaW5nIFtbUmV2ZXJiXV0uXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcmV2ZXJiID0gbmV3IFRvbmUuSkNSZXZlcmIoMC40KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBkZWxheSA9IG5ldyBUb25lLkZlZWRiYWNrRGVsYXkoMC41KTtcbiAqIC8vIGNvbm5lY3RpbmcgdGhlIHN5bnRoIHRvIHJldmVyYiB0aHJvdWdoIGRlbGF5XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLkR1b1N5bnRoKCkuY2hhaW4oZGVsYXksIHJldmVyYik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkE0XCIsIFwiOG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgSkNSZXZlcmIgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhKQ1JldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiSkNSZXZlcmJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGEgc2VyaWVzIG9mIGFsbHBhc3MgZmlsdGVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHBhcmFsbGVsIGZlZWRiYWNrIGNvbWIgZmlsdGVyc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZmVlZGJhY2tDb21iRmlsdGVycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoSkNSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiXSk7XG4gICAgICAgIHRoaXMucm9vbVNpemUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnJvb21TaXplLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NjYWxlUm9vbVNpemUgPSBuZXcgU2NhbGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAtMC43MzMsXG4gICAgICAgICAgICBtYXg6IDAuMTk3LFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gbWFrZSB0aGUgYWxscGFzcyBmaWx0ZXJzXG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzID0gYWxscGFzc0ZpbHRlckZyZXFzLm1hcChmcmVxID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFsbHBhc3MgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBhbGxwYXNzLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIGFsbHBhc3MuZnJlcXVlbmN5LnZhbHVlID0gZnJlcTtcbiAgICAgICAgICAgIHJldHVybiBhbGxwYXNzO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gYW5kIHRoZSBjb21iIGZpbHRlcnNcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tDb21iRmlsdGVycyA9IGNvbWJGaWx0ZXJEZWxheVRpbWVzLm1hcCgoZGVsYXlUaW1lLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZmJjZiA9IG5ldyBGZWVkYmFja0NvbWJGaWx0ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICBkZWxheVRpbWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3NjYWxlUm9vbVNpemUuY29ubmVjdChmYmNmLnJlc29uYW5jZSk7XG4gICAgICAgICAgICBmYmNmLnJlc29uYW5jZS52YWx1ZSA9IGNvbWJGaWx0ZXJSZXNvbmFuY2VzW2luZGV4XTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8IGNvbWJGaWx0ZXJEZWxheVRpbWVzLmxlbmd0aCAvIDIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KC4uLnRoaXMuX2FsbHBhc3NGaWx0ZXJzLCBmYmNmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KC4uLnRoaXMuX2FsbHBhc3NGaWx0ZXJzLCBmYmNmKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYmNmO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gY2hhaW4gdGhlIGFsbHBhc3MgZmlsdGVycyB0b2dldGhlclxuICAgICAgICB0aGlzLnJvb21TaXplLmNvbm5lY3QodGhpcy5fc2NhbGVSb29tU2l6ZSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInJvb21TaXplXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcm9vbVNpemU6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnMuZm9yRWFjaChhcGYgPT4gYXBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMuZm9yRWFjaChmYmNmID0+IGZiY2YuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5yb29tU2l6ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NjYWxlUm9vbVNpemUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1KQ1JldmVyYi5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9GZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0ZlZWRiYWNrRWZmZWN0XCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEp1c3QgbGlrZSBhIFtbU3RlcmVvRmVlZGJhY2tFZmZlY3RdXSwgYnV0IHRoZSBmZWVkYmFjayBpcyByb3V0ZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0XG4gKiBhbmQgcmlnaHQgdG8gbGVmdCBpbnN0ZWFkIG9mIG9uIHRoZSBzYW1lIGNoYW5uZWwuXG4gKiBgYGBcbiAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgZmVlZGJhY2tMIDwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICstLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLT4gICAgICAgICstLS0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tK1xuICogICAgICBmZWVkYmFja01lcmdlICstLT4gc3BsaXQgICAgICAgIChFRkZFQ1QpICAgICAgIG1lcmdlICstLT4gZmVlZGJhY2tTcGxpdCAgICAgfCB8XG4gKiArLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0+ICAgICAgICArLS0tLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0rIHxcbiAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyBmZWVkYmFja1IgPC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFN0ZXJlb1hGZWVkYmFja0VmZmVjdCBleHRlbmRzIFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICAvLyB0aGUgbGVmdCBvdXRwdXQgY29ubmVjdGVkIHRvIHRoZSByaWdodCBpbnB1dFxuICAgICAgICB0aGlzLl9mZWVkYmFja0wuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuY29ubmVjdCh0aGlzLl9mZWVkYmFja01lcmdlLCAwLCAxKTtcbiAgICAgICAgLy8gdGhlIGxlZnQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tSLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tSLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tNZXJnZSwgMCwgMCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZlZWRiYWNrXCJdKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9YRmVlZGJhY2tFZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvWEZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvWEZlZWRiYWNrRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogUGluZ1BvbmdEZWxheSBpcyBhIGZlZWRiYWNrIGRlbGF5IGVmZmVjdCB3aGVyZSB0aGUgZWNobyBpcyBoZWFyZFxuICogZmlyc3QgaW4gb25lIGNoYW5uZWwgYW5kIG5leHQgaW4gdGhlIG9wcG9zaXRlIGNoYW5uZWwuIEluIGEgc3RlcmVvXG4gKiBzeXN0ZW0gdGhlc2UgYXJlIHRoZSByaWdodCBhbmQgbGVmdCBjaGFubmVscy5cbiAqIFBpbmdQb25nRGVsYXkgaW4gbW9yZSBzaW1wbGlmaWVkIHRlcm1zIGlzIHR3byBUb25lLkZlZWRiYWNrRGVsYXlzXG4gKiB3aXRoIGluZGVwZW5kZW50IGRlbGF5IHZhbHVlcy4gRWFjaCBkZWxheSBpcyByb3V0ZWQgdG8gb25lIGNoYW5uZWxcbiAqIChsZWZ0IG9yIHJpZ2h0KSwgYW5kIHRoZSBjaGFubmVsIHRyaWdnZXJlZCBzZWNvbmQgd2lsbCBhbHdheXNcbiAqIHRyaWdnZXIgYXQgdGhlIHNhbWUgaW50ZXJ2YWwgYWZ0ZXIgdGhlIGZpcnN0LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBpbmdQb25nID0gbmV3IFRvbmUuUGluZ1BvbmdEZWxheShcIjRuXCIsIDAuMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgZHJ1bSA9IG5ldyBUb25lLk1lbWJyYW5lU3ludGgoKS5jb25uZWN0KHBpbmdQb25nKTtcbiAqIGRydW0udHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjMyblwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFBpbmdQb25nRGVsYXkgZXh0ZW5kcyBTdGVyZW9YRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQaW5nUG9uZ0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQaW5nUG9uZ0RlbGF5XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaW5nUG9uZ0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pO1xuICAgICAgICB0aGlzLl9sZWZ0RGVsYXkgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9yaWdodERlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9yaWdodFByZURlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGVsYXlUaW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KHRoaXMuX2xlZnREZWxheSk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KHRoaXMuX3JpZ2h0UHJlRGVsYXksIHRoaXMuX3JpZ2h0RGVsYXkpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZS5mYW4odGhpcy5fbGVmdERlbGF5LmRlbGF5VGltZSwgdGhpcy5fcmlnaHREZWxheS5kZWxheVRpbWUsIHRoaXMuX3JpZ2h0UHJlRGVsYXkuZGVsYXlUaW1lKTtcbiAgICAgICAgLy8gcmVhcnJhbmdlZCB0aGUgZmVlZGJhY2sgdG8gYmUgYWZ0ZXIgdGhlIHJpZ2h0UHJlRGVsYXlcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmNvbm5lY3QodGhpcy5fcmlnaHREZWxheSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImRlbGF5VGltZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvWEZlZWRiYWNrRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMC4yNSxcbiAgICAgICAgICAgIG1heERlbGF5OiAxXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xlZnREZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0RGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodFByZURlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QaW5nUG9uZ0RlbGF5LmpzLm1hcCIsImltcG9ydCB7IEZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4vRmVlZGJhY2tFZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgRGVsYXkgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0RlbGF5XCI7XG5pbXBvcnQgeyBDcm9zc0ZhZGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvQ3Jvc3NGYWRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuLyoqXG4gKiBQaXRjaFNoaWZ0IGRvZXMgbmVhci1yZWFsdGltZSBwaXRjaCBzaGlmdGluZyB0byB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICogVGhlIGVmZmVjdCBpcyBhY2hpZXZlZCBieSBzcGVlZGluZyB1cCBvciBzbG93aW5nIGRvd24gdGhlIGRlbGF5VGltZVxuICogb2YgYSBEZWxheU5vZGUgdXNpbmcgYSBzYXd0b290aCB3YXZlLlxuICogQWxnb3JpdGhtIGZvdW5kIGluIFt0aGlzIHBkZl0oaHR0cDovL2RzcC1ib29rLm5hcm9kLnJ1L3NvdW5kcHJvYy5wZGYpLlxuICogQWRkaXRpb25hbCByZWZlcmVuY2UgYnkgW01pbGxlciBQdWNrZXRdKGh0dHA6Ly9tc3AudWNzZC5lZHUvdGVjaG5pcXVlcy92MC4xMS9ib29rLWh0bWwvbm9kZTExNS5odG1sKS5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFBpdGNoU2hpZnQgZXh0ZW5kcyBGZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBpdGNoU2hpZnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwaXRjaFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBpdGNoU2hpZnRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBpdGNoU2hpZnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwaXRjaFwiXSk7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5QSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvQSA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAwLjEsXG4gICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCJcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLl9kZWxheUEuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5fZGVsYXlCID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9CID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDAuMSxcbiAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIixcbiAgICAgICAgICAgIHBoYXNlOiAxODBcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLl9kZWxheUIuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlID0gbmV3IENyb3NzRmFkZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICB0eXBlOiBcInRyaWFuZ2xlXCIsXG4gICAgICAgICAgICBwaGFzZTogOTBcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLl9jcm9zc0ZhZGUuZmFkZSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrRGVsYXkgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgZGVsYXlUaW1lOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lID0gdGhpcy5fZmVlZGJhY2tEZWxheS5kZWxheVRpbWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiZGVsYXlUaW1lXCIpO1xuICAgICAgICB0aGlzLl9waXRjaCA9IG9wdGlvbnMucGl0Y2g7XG4gICAgICAgIHRoaXMuX3dpbmRvd1NpemUgPSBvcHRpb25zLndpbmRvd1NpemU7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIHR3byBkZWxheSBsaW5lcyB1cFxuICAgICAgICB0aGlzLl9kZWxheUEuY29ubmVjdCh0aGlzLl9jcm9zc0ZhZGUuYSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Qi5jb25uZWN0KHRoaXMuX2Nyb3NzRmFkZS5iKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS5mYW4odGhpcy5fbGZvQS5mcmVxdWVuY3ksIHRoaXMuX2xmb0IuZnJlcXVlbmN5LCB0aGlzLl9jcm9zc0ZhZGVMRk8uZnJlcXVlbmN5KTtcbiAgICAgICAgLy8gcm91dGUgdGhlIGlucHV0XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5mYW4odGhpcy5fZGVsYXlBLCB0aGlzLl9kZWxheUIpO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGUuY2hhaW4odGhpcy5fZmVlZGJhY2tEZWxheSwgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgICAgICAvLyBzdGFydCB0aGUgTEZPcyBhdCB0aGUgc2FtZSB0aW1lXG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX2xmb0Euc3RhcnQobm93KTtcbiAgICAgICAgdGhpcy5fbGZvQi5zdGFydChub3cpO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGVMRk8uc3RhcnQobm93KTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlXG4gICAgICAgIHRoaXMud2luZG93U2l6ZSA9IHRoaXMuX3dpbmRvd1NpemU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRmVlZGJhY2tFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcGl0Y2g6IDAsXG4gICAgICAgICAgICB3aW5kb3dTaXplOiAwLjEsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDAsXG4gICAgICAgICAgICBmZWVkYmFjazogMFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVwaXRjaCB0aGUgaW5jb21pbmcgc2lnbmFsIGJ5IHNvbWUgaW50ZXJ2YWwgKG1lYXN1cmVkIGluIHNlbWktdG9uZXMpLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGl0Y2hTaGlmdCA9IG5ldyBUb25lLlBpdGNoU2hpZnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QocGl0Y2hTaGlmdCkuc3RhcnQoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcGl0Y2hTaGlmdC5waXRjaCA9IC0xMjsgLy8gZG93biBvbmUgb2N0YXZlXG4gICAgICogcGl0Y2hTaGlmdC5waXRjaCA9IDc7IC8vIHVwIGEgZmlmdGhcbiAgICAgKi9cbiAgICBnZXQgcGl0Y2goKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9waXRjaDtcbiAgICB9XG4gICAgc2V0IHBpdGNoKGludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX3BpdGNoID0gaW50ZXJ2YWw7XG4gICAgICAgIGxldCBmYWN0b3IgPSAwO1xuICAgICAgICBpZiAoaW50ZXJ2YWwgPCAwKSB7XG4gICAgICAgICAgICB0aGlzLl9sZm9BLm1pbiA9IDA7XG4gICAgICAgICAgICB0aGlzLl9sZm9BLm1heCA9IHRoaXMuX3dpbmRvd1NpemU7XG4gICAgICAgICAgICB0aGlzLl9sZm9CLm1pbiA9IDA7XG4gICAgICAgICAgICB0aGlzLl9sZm9CLm1heCA9IHRoaXMuX3dpbmRvd1NpemU7XG4gICAgICAgICAgICBmYWN0b3IgPSBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwgLSAxKSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9sZm9BLm1pbiA9IHRoaXMuX3dpbmRvd1NpemU7XG4gICAgICAgICAgICB0aGlzLl9sZm9BLm1heCA9IDA7XG4gICAgICAgICAgICB0aGlzLl9sZm9CLm1pbiA9IHRoaXMuX3dpbmRvd1NpemU7XG4gICAgICAgICAgICB0aGlzLl9sZm9CLm1heCA9IDA7XG4gICAgICAgICAgICBmYWN0b3IgPSBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwpIC0gMTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9mcmVxdWVuY3kudmFsdWUgPSBmYWN0b3IgKiAoMS4yIC8gdGhpcy5fd2luZG93U2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB3aW5kb3cgc2l6ZSBjb3JyZXNwb25kcyByb3VnaGx5IHRvIHRoZSBzYW1wbGUgbGVuZ3RoIGluIGEgbG9vcGluZyBzYW1wbGVyLlxuICAgICAqIFNtYWxsZXIgdmFsdWVzIGFyZSBkZXNpcmFibGUgZm9yIGEgbGVzcyBub3RpY2VhYmxlIGRlbGF5IHRpbWUgb2YgdGhlIHBpdGNoIHNoaWZ0ZWRcbiAgICAgKiBzaWduYWwsIGJ1dCBsYXJnZXIgdmFsdWVzIHdpbGwgcmVzdWx0IGluIHNtb290aGVyIHBpdGNoIHNoaWZ0aW5nIGZvciBsYXJnZXIgaW50ZXJ2YWxzLlxuICAgICAqIEEgbm9taW5hbCByYW5nZSBvZiAwLjAzIHRvIDAuMSBpcyByZWNvbW1lbmRlZC5cbiAgICAgKi9cbiAgICBnZXQgd2luZG93U2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3dpbmRvd1NpemU7XG4gICAgfVxuICAgIHNldCB3aW5kb3dTaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fd2luZG93U2l6ZSA9IHRoaXMudG9TZWNvbmRzKHNpemUpO1xuICAgICAgICB0aGlzLnBpdGNoID0gdGhpcy5fcGl0Y2g7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlBLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlCLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvQS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jcm9zc0ZhZGVMRk8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0RlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGl0Y2hTaGlmdC5qcy5tYXAiLCJpbXBvcnQgeyBTdGVyZW9FZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogUGhhc2VyIGlzIGEgcGhhc2VyIGVmZmVjdC4gUGhhc2VycyB3b3JrIGJ5IGNoYW5naW5nIHRoZSBwaGFzZVxuICogb2YgZGlmZmVyZW50IGZyZXF1ZW5jeSBjb21wb25lbnRzIG9mIGFuIGluY29taW5nIHNpZ25hbC4gUmVhZCBtb3JlIG9uXG4gKiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9QaGFzZXJfKGVmZmVjdCkpLlxuICogSW5zcGlyYXRpb24gZm9yIHRoaXMgcGhhc2VyIGNvbWVzIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hLykuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGhhc2VyID0gbmV3IFRvbmUuUGhhc2VyKHtcbiAqIFx0ZnJlcXVlbmN5OiAxNSxcbiAqIFx0b2N0YXZlczogNSxcbiAqIFx0YmFzZUZyZXF1ZW5jeTogMTAwMFxuICogfSkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5GTVN5bnRoKCkuY29ubmVjdChwaGFzZXIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJFM1wiLCBcIjJuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgUGhhc2VyIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGhhc2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcImJhc2VGcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQaGFzZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBoYXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJiYXNlRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIHBoYXNlOiAxODAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLlEgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZmlsdGVyc0wgPSB0aGlzLl9tYWtlRmlsdGVycyhvcHRpb25zLnN0YWdlcywgdGhpcy5fbGZvTCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNSID0gdGhpcy5fbWFrZUZpbHRlcnMob3B0aW9ucy5zdGFnZXMsIHRoaXMuX2xmb1IpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmb0wuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS52YWx1ZSA9IG9wdGlvbnMuZnJlcXVlbmN5O1xuICAgICAgICAvLyBjb25uZWN0IHRoZW0gdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCguLi50aGlzLl9maWx0ZXJzTCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KC4uLnRoaXMuX2ZpbHRlcnNSKTtcbiAgICAgICAgLy8gY29udHJvbCB0aGUgZnJlcXVlbmN5IHdpdGggb25lIExGT1xuICAgICAgICB0aGlzLl9sZm9MLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2xmb1IuZnJlcXVlbmN5KTtcbiAgICAgICAgLy8gc2V0IHRoZSBvcHRpb25zXG4gICAgICAgIHRoaXMuYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICAvLyBzdGFydCB0aGUgbGZvXG4gICAgICAgIHRoaXMuX2xmb0wuc3RhcnQoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdGFydCgpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJRXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLjUsXG4gICAgICAgICAgICBvY3RhdmVzOiAzLFxuICAgICAgICAgICAgc3RhZ2VzOiAxMCxcbiAgICAgICAgICAgIFE6IDEwLFxuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMzUwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgX21ha2VGaWx0ZXJzKHN0YWdlcywgY29ubmVjdFRvRnJlcSkge1xuICAgICAgICBjb25zdCBmaWx0ZXJzID0gW107XG4gICAgICAgIC8vIG1ha2UgYWxsIHRoZSBmaWx0ZXJzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhZ2VzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGZpbHRlci50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICB0aGlzLlEuY29ubmVjdChmaWx0ZXIuUSk7XG4gICAgICAgICAgICBjb25uZWN0VG9GcmVxLmNvbm5lY3QoZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICBmaWx0ZXJzLnB1c2goZmlsdGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmlsdGVycztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIHRoZSBwaGFzZSBnb2VzIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5XG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyhvY3RhdmVzKSB7XG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvY3RhdmVzO1xuICAgICAgICBjb25zdCBtYXggPSB0aGlzLl9iYXNlRnJlcXVlbmN5ICogTWF0aC5wb3coMiwgb2N0YXZlcyk7XG4gICAgICAgIHRoaXMuX2xmb0wubWF4ID0gbWF4O1xuICAgICAgICB0aGlzLl9sZm9SLm1heCA9IG1heDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRoZSBiYXNlIGZyZXF1ZW5jeSBvZiB0aGUgZmlsdGVycy5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KGZyZXEpIHtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3koZnJlcSk7XG4gICAgICAgIHRoaXMuX2xmb0wubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5fbGZvUi5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9SLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyc0wuZm9yRWFjaChmID0+IGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyc1IuZm9yRWFjaChmID0+IGYuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QaGFzZXIuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NZXJnZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBTaW1wbGUgY29udm9sdXRpb24gY3JlYXRlZCB3aXRoIGRlY2F5aW5nIG5vaXNlLlxuICogR2VuZXJhdGVzIGFuIEltcHVsc2UgUmVzcG9uc2UgQnVmZmVyXG4gKiB3aXRoIFRvbmUuT2ZmbGluZSB0aGVuIGZlZWRzIHRoZSBJUiBpbnRvIENvbnZvbHZlck5vZGUuXG4gKiBUaGUgaW1wdWxzZSByZXNwb25zZSBnZW5lcmF0aW9uIGlzIGFzeW5jLCBzbyB5b3UgaGF2ZVxuICogdG8gd2FpdCB1bnRpbCBbW3JlYWR5XV0gcmVzb2x2ZXMgYmVmb3JlIGl0IHdpbGwgbWFrZSBhIHNvdW5kLlxuICpcbiAqIEluc3BpcmF0aW9uIGZyb20gW1JldmVyYkdlbl0oaHR0cHM6Ly9naXRodWIuY29tL2FkZWxlc3BpbmFzc2UvcmV2ZXJiR2VuKS5cbiAqIENvcHlyaWdodCAoYykgMjAxNCBBbGFuIGRlTGVzcGluYXNzZSBBcGFjaGUgMi4wIExpY2Vuc2UuXG4gKlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgUmV2ZXJiIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVjYXlcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJSZXZlcmJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIENvbnZvbHZlciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXNvbHZlcyB3aGVuIHRoZSByZXZlcmIgYnVmZmVyIGlzIGdlbmVyYXRlZC4gV2hlbmV2ZXIgZWl0aGVyIFtbZGVjYXldXVxuICAgICAgICAgKiBvciBbW3ByZURlbGF5XV0gYXJlIHNldCwgeW91IGhhdmUgdG8gd2FpdCB1bnRpbCBbW3JlYWR5XV0gcmVzb2x2ZXNcbiAgICAgICAgICogYmVmb3JlIHRoZSBJUiBpcyBnZW5lcmF0ZWQgd2l0aCB0aGUgbGF0ZXN0IHZhbHVlcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucmVhZHkgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFJldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlY2F5XCJdKTtcbiAgICAgICAgdGhpcy5fZGVjYXkgPSBvcHRpb25zLmRlY2F5O1xuICAgICAgICB0aGlzLl9wcmVEZWxheSA9IG9wdGlvbnMucHJlRGVsYXk7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGUoKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX2NvbnZvbHZlcik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlY2F5OiAxLjUsXG4gICAgICAgICAgICBwcmVEZWxheTogMC4wMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBvZiB0aGUgcmV2ZXJiLlxuICAgICAqL1xuICAgIGdldCBkZWNheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY2F5O1xuICAgIH1cbiAgICBzZXQgZGVjYXkodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDAuMDAxKTtcbiAgICAgICAgdGhpcy5fZGVjYXkgPSB0aW1lO1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhbW91bnQgb2YgdGltZSBiZWZvcmUgdGhlIHJldmVyYiBpcyBmdWxseSByYW1wZWQgaW4uXG4gICAgICovXG4gICAgZ2V0IHByZURlbGF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJlRGVsYXk7XG4gICAgfVxuICAgIHNldCBwcmVEZWxheSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0UmFuZ2UodGltZSwgMCk7XG4gICAgICAgIHRoaXMuX3ByZURlbGF5ID0gdGltZTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSB0aGUgSW1wdWxzZSBSZXNwb25zZS4gUmV0dXJucyBhIHByb21pc2Ugd2hpbGUgdGhlIElSIGlzIGJlaW5nIGdlbmVyYXRlZC5cbiAgICAgKiBAcmV0dXJuIFByb21pc2Ugd2hpY2ggcmV0dXJucyB0aGlzIG9iamVjdC5cbiAgICAgKi9cbiAgICBnZW5lcmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzUmVhZHkgPSB0aGlzLnJlYWR5O1xuICAgICAgICAgICAgLy8gY3JlYXRlIGEgbm9pc2UgYnVyc3Qgd2hpY2ggZGVjYXlzIG92ZXIgdGhlIGR1cmF0aW9uIGluIGVhY2ggY2hhbm5lbFxuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IG5ldyBPZmZsaW5lQ29udGV4dCgyLCB0aGlzLl9kZWNheSArIHRoaXMuX3ByZURlbGF5LCB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBub2lzZUwgPSBuZXcgTm9pc2UoeyBjb250ZXh0IH0pO1xuICAgICAgICAgICAgY29uc3Qgbm9pc2VSID0gbmV3IE5vaXNlKHsgY29udGV4dCB9KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlID0gbmV3IE1lcmdlKHsgY29udGV4dCB9KTtcbiAgICAgICAgICAgIG5vaXNlTC5jb25uZWN0KG1lcmdlLCAwLCAwKTtcbiAgICAgICAgICAgIG5vaXNlUi5jb25uZWN0KG1lcmdlLCAwLCAxKTtcbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gbmV3IEdhaW4oeyBjb250ZXh0IH0pLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgICAgIG1lcmdlLmNvbm5lY3QoZ2Fpbk5vZGUpO1xuICAgICAgICAgICAgbm9pc2VMLnN0YXJ0KDApO1xuICAgICAgICAgICAgbm9pc2VSLnN0YXJ0KDApO1xuICAgICAgICAgICAgLy8gcHJlZGVsYXlcbiAgICAgICAgICAgIGdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgMCk7XG4gICAgICAgICAgICBnYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDEsIHRoaXMuX3ByZURlbGF5KTtcbiAgICAgICAgICAgIC8vIGRlY2F5XG4gICAgICAgICAgICBnYWluTm9kZS5nYWluLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSgwLCB0aGlzLl9wcmVEZWxheSwgdGhpcy5kZWNheSk7XG4gICAgICAgICAgICAvLyByZW5kZXIgdGhlIGJ1ZmZlclxuICAgICAgICAgICAgY29uc3QgcmVuZGVyUHJvbWlzZSA9IGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgICAgICB0aGlzLnJlYWR5ID0gcmVuZGVyUHJvbWlzZS50aGVuKG5vT3ApO1xuICAgICAgICAgICAgLy8gd2FpdCBmb3IgdGhlIHByZXZpb3VzIGByZWFkeWAgdG8gcmVzb2x2ZVxuICAgICAgICAgICAgeWllbGQgcHJldmlvdXNSZWFkeTtcbiAgICAgICAgICAgIC8vIHNldCB0aGUgYnVmZmVyXG4gICAgICAgICAgICB0aGlzLl9jb252b2x2ZXIuYnVmZmVyID0gKHlpZWxkIHJlbmRlclByb21pc2UpLmdldCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVJldmVyYi5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBTcGxpdCB9IGZyb20gXCIuL1NwbGl0XCI7XG5pbXBvcnQgeyBBZGQgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0FkZFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU3VidHJhY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBNaWQvU2lkZSBwcm9jZXNzaW5nIHNlcGFyYXRlcyB0aGUgdGhlICdtaWQnIHNpZ25hbCAod2hpY2ggY29tZXMgb3V0IG9mIGJvdGggdGhlIGxlZnQgYW5kIHRoZSByaWdodCBjaGFubmVsKVxuICogYW5kIHRoZSAnc2lkZScgKHdoaWNoIG9ubHkgY29tZXMgb3V0IG9mIHRoZSB0aGUgc2lkZSBjaGFubmVscykuXG4gKiBgYGBcbiAqIE1pZCA9IChMZWZ0K1JpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBtaWQtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIFNpZGUgPSAoTGVmdC1SaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gc2lkZS1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNaWRTaWRlU3BsaXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZVNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVTcGxpdFwiO1xuICAgICAgICB0aGlzLl9zcGxpdCA9IHRoaXMuaW5wdXQgPSBuZXcgU3BsaXQoe1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21pZEFkZCA9IG5ldyBBZGQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBNYXRoLlNRUlQxXzIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaWRlU3VidHJhY3QgPSBuZXcgU3VidHJhY3QoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuc2lkZSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9taWRBZGQsIDApO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX21pZEFkZC5hZGRlbmQsIDEpO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX3NpZGVTdWJ0cmFjdCwgMCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fc2lkZVN1YnRyYWN0LnN1YnRyYWhlbmQsIDEpO1xuICAgICAgICB0aGlzLl9taWRBZGQuY29ubmVjdCh0aGlzLm1pZCk7XG4gICAgICAgIHRoaXMuX3NpZGVTdWJ0cmFjdC5jb25uZWN0KHRoaXMuc2lkZSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRBZGQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlU3VidHJhY3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVTcGxpdC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuL01lcmdlXCI7XG5pbXBvcnQgeyBBZGQgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0FkZFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU3VidHJhY3RcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBNaWRTaWRlTWVyZ2UgbWVyZ2VzIHRoZSBtaWQgYW5kIHNpZGUgc2lnbmFsIGFmdGVyIHRoZXkndmUgYmVlbiBzZXBhcmF0ZWQgYnkgW1tNaWRTaWRlU3BsaXRdXVxuICogYGBgXG4gKiBNaWQgPSAoTGVmdCtSaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gbWlkLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBTaWRlID0gKExlZnQtUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIHNpZGUtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWlkU2lkZU1lcmdlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVNZXJnZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlTWVyZ2VcIjtcbiAgICAgICAgdGhpcy5taWQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5zaWRlID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2xlZnQgPSBuZXcgQWRkKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9sZWZ0TXVsdCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9yaWdodCA9IG5ldyBTdWJ0cmFjdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHRNdWx0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBNYXRoLlNRUlQxXzJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlID0gdGhpcy5vdXRwdXQgPSBuZXcgTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMubWlkLmZhbih0aGlzLl9sZWZ0KTtcbiAgICAgICAgdGhpcy5zaWRlLmNvbm5lY3QodGhpcy5fbGVmdC5hZGRlbmQpO1xuICAgICAgICB0aGlzLm1pZC5jb25uZWN0KHRoaXMuX3JpZ2h0KTtcbiAgICAgICAgdGhpcy5zaWRlLmNvbm5lY3QodGhpcy5fcmlnaHQuc3VidHJhaGVuZCk7XG4gICAgICAgIHRoaXMuX2xlZnQuY29ubmVjdCh0aGlzLl9sZWZ0TXVsdCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0LmNvbm5lY3QodGhpcy5fcmlnaHRNdWx0KTtcbiAgICAgICAgdGhpcy5fbGVmdE11bHQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAxKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuc2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xlZnRNdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHRNdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGVmdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZU1lcmdlLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgTWlkU2lkZVNwbGl0IH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01pZFNpZGVTcGxpdFwiO1xuaW1wb3J0IHsgTWlkU2lkZU1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01pZFNpZGVNZXJnZVwiO1xuLyoqXG4gKiBNaWQvU2lkZSBwcm9jZXNzaW5nIHNlcGFyYXRlcyB0aGUgdGhlICdtaWQnIHNpZ25hbFxuICogKHdoaWNoIGNvbWVzIG91dCBvZiBib3RoIHRoZSBsZWZ0IGFuZCB0aGUgcmlnaHQgY2hhbm5lbClcbiAqIGFuZCB0aGUgJ3NpZGUnICh3aGljaCBvbmx5IGNvbWVzIG91dCBvZiB0aGUgdGhlIHNpZGUgY2hhbm5lbHMpXG4gKiBhbmQgZWZmZWN0cyB0aGVtIHNlcGFyYXRlbHkgYmVmb3JlIGJlaW5nIHJlY29tYmluZWQuXG4gKiBBcHBsaWVzIGEgTWlkL1NpZGUgc2VwZXJhdGlvbiBhbmQgcmVjb21iaW5hdGlvbi5cbiAqIEFsZ29yaXRobSBmb3VuZCBpbiBba3ZyYXVkaW8gZm9ydW1zXShodHRwOi8vd3d3Lmt2cmF1ZGlvLmNvbS9mb3J1bS92aWV3dG9waWMucGhwP3Q9MjEyNTg3KS5cbiAqIFRoaXMgaXMgYSBiYXNlLWNsYXNzIGZvciBNaWQvU2lkZSBFZmZlY3RzLlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgTWlkU2lkZUVmZmVjdCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZSA9IG5ldyBNaWRTaWRlTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdCA9IG5ldyBNaWRTaWRlU3BsaXQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX21pZFNlbmQgPSB0aGlzLl9taWRTaWRlU3BsaXQubWlkO1xuICAgICAgICB0aGlzLl9zaWRlU2VuZCA9IHRoaXMuX21pZFNpZGVTcGxpdC5zaWRlO1xuICAgICAgICB0aGlzLl9taWRSZXR1cm4gPSB0aGlzLl9taWRTaWRlTWVyZ2UubWlkO1xuICAgICAgICB0aGlzLl9zaWRlUmV0dXJuID0gdGhpcy5fbWlkU2lkZU1lcmdlLnNpZGU7XG4gICAgICAgIC8vIHRoZSBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY29ubmVjdCh0aGlzLl9taWRTaWRlU3BsaXQpO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UuY29ubmVjdCh0aGlzLmVmZmVjdFJldHVybik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG1pZCBjaGFpbiBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdE1pZCguLi5ub2Rlcykge1xuICAgICAgICB0aGlzLl9taWRTZW5kLmNoYWluKC4uLm5vZGVzLCB0aGlzLl9taWRSZXR1cm4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBzaWRlIGNoYWluIG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0U2lkZSguLi5ub2Rlcykge1xuICAgICAgICB0aGlzLl9zaWRlU2VuZC5jaGFpbiguLi5ub2RlcywgdGhpcy5fc2lkZVJldHVybik7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVTZW5kLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkUmV0dXJuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZVJldHVybi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVFZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgTWlkU2lkZUVmZmVjdCB9IGZyb20gXCIuLi9lZmZlY3QvTWlkU2lkZUVmZmVjdFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogQXBwbGllcyBhIHdpZHRoIGZhY3RvciB0byB0aGUgbWlkL3NpZGUgc2VwZXJhdGlvbi5cbiAqIDAgaXMgYWxsIG1pZCBhbmQgMSBpcyBhbGwgc2lkZS5cbiAqIEFsZ29yaXRobSBmb3VuZCBpbiBba3ZyYXVkaW8gZm9ydW1zXShodHRwOi8vd3d3Lmt2cmF1ZGlvLmNvbS9mb3J1bS92aWV3dG9waWMucGhwP3Q9MjEyNTg3KS5cbiAqIGBgYFxuICogTWlkICo9IDIqKDEtd2lkdGgpPGJyPlxuICogU2lkZSAqPSAyKndpZHRoXG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFN0ZXJlb1dpZGVuZXIgZXh0ZW5kcyBNaWRTaWRlRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU3RlcmVvV2lkZW5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIndpZHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3RlcmVvV2lkZW5lclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU3RlcmVvV2lkZW5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIndpZHRoXCJdKTtcbiAgICAgICAgdGhpcy53aWR0aCA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMud2lkdGgsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wid2lkdGhcIl0pO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoTWlkID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aFNpZGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taWRNdWx0ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoTWlkLmNvbm5lY3QodGhpcy5fbWlkTXVsdC5mYWN0b3IpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RNaWQodGhpcy5fbWlkTXVsdCk7XG4gICAgICAgIHRoaXMuX29uZU1pbnVzV2lkdGggPSBuZXcgU3VidHJhY3QoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX29uZU1pbnVzV2lkdGguY29ubmVjdCh0aGlzLl90d29UaW1lc1dpZHRoTWlkKTtcbiAgICAgICAgY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMSksIHRoaXMuX29uZU1pbnVzV2lkdGgpO1xuICAgICAgICB0aGlzLndpZHRoLmNvbm5lY3QodGhpcy5fb25lTWludXNXaWR0aC5zdWJ0cmFoZW5kKTtcbiAgICAgICAgdGhpcy5fc2lkZU11bHQgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMud2lkdGguY29ubmVjdCh0aGlzLl90d29UaW1lc1dpZHRoU2lkZSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlLmNvbm5lY3QodGhpcy5fc2lkZU11bHQuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0U2lkZSh0aGlzLl9zaWRlTXVsdCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTWlkU2lkZUVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3aWR0aDogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLndpZHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkTXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVNdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb25lTWludXNXaWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb1dpZGVuZXIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFRyZW1vbG8gbW9kdWxhdGVzIHRoZSBhbXBsaXR1ZGUgb2YgYW4gaW5jb21pbmcgc2lnbmFsIHVzaW5nIGFuIFtbTEZPXV0uXG4gKiBUaGUgZWZmZWN0IGlzIGEgc3RlcmVvIGVmZmVjdCB3aGVyZSB0aGUgbW9kdWxhdGlvbiBwaGFzZSBpcyBpbnZlcnRlZCBpbiBlYWNoIGNoYW5uZWwuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhIHRyZW1vbG8gYW5kIHN0YXJ0IGl0J3MgTEZPXG4gKiBjb25zdCB0cmVtb2xvID0gbmV3IFRvbmUuVHJlbW9sbyg5LCAwLjc1KS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgdHJlbW9sbyBhbmQgc3RhcnQgaXRcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdCh0cmVtb2xvKS5zdGFydCgpO1xuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFRyZW1vbG8gZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUcmVtb2xvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUcmVtb2xvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUcmVtb2xvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLl9sZm9MID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgICAgICBtaW46IDEsXG4gICAgICAgICAgICBtYXg6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm9SID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgICAgICBtaW46IDEsXG4gICAgICAgICAgICBtYXg6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVMID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZVIgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXB0aCA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGVwdGgsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RMZWZ0KHRoaXMuX2FtcGxpdHVkZUwpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCh0aGlzLl9hbXBsaXR1ZGVSKTtcbiAgICAgICAgdGhpcy5fbGZvTC5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZUwuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2xmb1IuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGVSLmdhaW4pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5mYW4odGhpcy5fbGZvTC5mcmVxdWVuY3ksIHRoaXMuX2xmb1IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXB0aC5mYW4odGhpcy5fbGZvUi5hbXBsaXR1ZGUsIHRoaXMuX2xmb0wuYW1wbGl0dWRlKTtcbiAgICAgICAgdGhpcy5zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAxMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgZGVwdGg6IDAuNSxcbiAgICAgICAgICAgIHNwcmVhZDogMTgwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHRyZW1vbG8uXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgdHJlbW9sby5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBlZmZlY3QgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zeW5jKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnRcbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1IudW5zeW5jKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQudW5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yIHR5cGUuXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9MLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fbGZvUi50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQW1vdW50IG9mIHN0ZXJlbyBzcHJlYWQuIFdoZW4gc2V0IHRvIDAsIGJvdGggTEZPJ3Mgd2lsbCBiZSBwYW5uZWQgY2VudHJhbGx5LlxuICAgICAqIFdoZW4gc2V0IHRvIDE4MCwgTEZPJ3Mgd2lsbCBiZSBwYW5uZWQgaGFyZCBsZWZ0IGFuZCByaWdodCByZXNwZWN0aXZlbHkuXG4gICAgICovXG4gICAgZ2V0IHNwcmVhZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmb1IucGhhc2UgLSB0aGlzLl9sZm9MLnBoYXNlOyAvLyAxODBcbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5waGFzZSA9IDkwIC0gKHNwcmVhZCAvIDIpO1xuICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gKHNwcmVhZCAvIDIpICsgOTA7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVMLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXB0aC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyZW1vbG8uanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBBIFZpYnJhdG8gZWZmZWN0IGNvbXBvc2VkIG9mIGEgVG9uZS5EZWxheSBhbmQgYSBUb25lLkxGTy4gVGhlIExGT1xuICogbW9kdWxhdGVzIHRoZSBkZWxheVRpbWUgb2YgdGhlIGRlbGF5LCBjYXVzaW5nIHRoZSBwaXRjaCB0byByaXNlIGFuZCBmYWxsLlxuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgVmlicmF0byBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFZpYnJhdG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlZpYnJhdG9cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFZpYnJhdG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDAsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmbyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHBoYXNlOiAtOTAgLy8gb2Zmc2UgdGhlIHBoYXNlIHNvIHRoZSByZXN0aW5nIHBvc2l0aW9uIGlzIGluIHRoZSBjZW50ZXJcbiAgICAgICAgfSkuc3RhcnQoKS5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmby5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9sZm8uYW1wbGl0dWRlO1xuICAgICAgICB0aGlzLmRlcHRoLnZhbHVlID0gb3B0aW9ucy5kZXB0aDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5fZGVsYXlOb2RlLCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1heERlbGF5OiAwLjAwNSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNSxcbiAgICAgICAgICAgIGRlcHRoOiAwLjEsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHlwZSBvZiBvc2NpbGxhdG9yIGF0dGFjaGVkIHRvIHRoZSBWaWJyYXRvLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbGZvLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmby5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXB0aC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVZpYnJhdG8uanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vQXV0b0ZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQXV0b1Bhbm5lclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQXV0b1dhaFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQml0Q3J1c2hlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQ2hlYnlzaGV2XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9DaG9ydXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Rpc3RvcnRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0ZlZWRiYWNrRGVsYXlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0ZyZXF1ZW5jeVNoaWZ0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0ZyZWV2ZXJiXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9KQ1JldmVyYlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGluZ1BvbmdEZWxheVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGl0Y2hTaGlmdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUGhhc2VyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9SZXZlcmJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1N0ZXJlb1dpZGVuZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1RyZW1vbG9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL1ZpYnJhdG9cIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY2hhbm5lbC9TcGxpdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgYXNzZXJ0LCBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBXZWIgQXVkaW8ncyBbQW5hbHlzZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI2lkbC1kZWYtQW5hbHlzZXJOb2RlKS5cbiAqIEV4dHJhY3RzIEZGVCBvciBXYXZlZm9ybSBkYXRhIGZyb20gdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFuYWx5c2VyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFuYWx5c2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiLCBcInNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBbmFseXNlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFuYWx5c2VyIG5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBidWZmZXIgdGhhdCB0aGUgRkZUIGRhdGEgaXMgd3JpdHRlbiB0b1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQW5hbHlzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0eXBlXCIsIFwic2l6ZVwiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW4gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fc3BsaXQgPSBuZXcgU3BsaXQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2hhbm5lbHM6IG9wdGlvbnMuY2hhbm5lbHMsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICBhc3NlcnRSYW5nZShvcHRpb25zLmNoYW5uZWxzLCAxKTtcbiAgICAgICAgLy8gY3JlYXRlIHRoZSBhbmFseXNlcnNcbiAgICAgICAgZm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBvcHRpb25zLmNoYW5uZWxzOyBjaGFubmVsKyspIHtcbiAgICAgICAgICAgIHRoaXMuX2FuYWx5c2Vyc1tjaGFubmVsXSA9IHRoaXMuY29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgICAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9hbmFseXNlcnNbY2hhbm5lbF0sIGNoYW5uZWwsIDApO1xuICAgICAgICB9XG4gICAgICAgIC8vIHNldCB0aGUgdmFsdWVzIGluaXRpYWxseVxuICAgICAgICB0aGlzLnNpemUgPSBvcHRpb25zLnNpemU7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNpemU6IDEwMjQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuOCxcbiAgICAgICAgICAgIHR5cGU6IFwiZmZ0XCIsXG4gICAgICAgICAgICBjaGFubmVsczogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJ1biB0aGUgYW5hbHlzaXMgZ2l2ZW4gdGhlIGN1cnJlbnQgc2V0dGluZ3MuIElmIFtbY2hhbm5lbHNdXSA9IDEsXG4gICAgICogaXQgd2lsbCByZXR1cm4gYSBGbG9hdDMyQXJyYXkuIElmIFtbY2hhbm5lbHNdXSA+IDEsIGl0IHdpbGxcbiAgICAgKiByZXR1cm4gYW4gYXJyYXkgb2YgRmxvYXQzMkFycmF5cyB3aGVyZSBlYWNoIGluZGV4IGluIHRoZSBhcnJheVxuICAgICAqIHJlcHJlc2VudHMgdGhlIGFuYWx5c2lzIGRvbmUgb24gYSBjaGFubmVsLlxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMuZm9yRWFjaCgoYW5hbHlzZXIsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9idWZmZXJzW2luZGV4XTtcbiAgICAgICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImZmdFwiKSB7XG4gICAgICAgICAgICAgICAgYW5hbHlzZXIuZ2V0RmxvYXRGcmVxdWVuY3lEYXRhKGJ1ZmZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl90eXBlID09PSBcIndhdmVmb3JtXCIpIHtcbiAgICAgICAgICAgICAgICBhbmFseXNlci5nZXRGbG9hdFRpbWVEb21haW5EYXRhKGJ1ZmZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5jaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnNbMF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVycztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2l6ZSBvZiBhbmFseXNpcy4gVGhpcyBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGluIHRoZSByYW5nZSAxNiB0byAxNjM4NC5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2Vyc1swXS5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICB9XG4gICAgc2V0IHNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9hbmFseXNlcnMuZm9yRWFjaCgoYW5hbHlzZXIsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBhbmFseXNlci5mZnRTaXplID0gc2l6ZSAqIDI7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzW2luZGV4XSA9IG5ldyBGbG9hdDMyQXJyYXkoc2l6ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIHRoZSBhbmFseXNlciBkb2VzIHRoZSBhbmFseXNpcyBvbi4gQ2hhbm5lbFxuICAgICAqIHNlcGFyYXRpb24gaXMgZG9uZSB1c2luZyBbW1NwbGl0XV1cbiAgICAgKi9cbiAgICBnZXQgY2hhbm5lbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlcnMubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW5hbHlzaXMgZnVuY3Rpb24gcmV0dXJuZWQgYnkgYW5hbHlzZXIuZ2V0VmFsdWUoKSwgZWl0aGVyIFwiZmZ0XCIgb3IgXCJ3YXZlZm9ybVwiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBhc3NlcnQodHlwZSA9PT0gXCJ3YXZlZm9ybVwiIHx8IHR5cGUgPT09IFwiZmZ0XCIsIGBBbmFseXNlcjogaW52YWxpZCB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAwIHJlcHJlc2VudHMgbm8gdGltZSBhdmVyYWdpbmcgd2l0aCB0aGUgbGFzdCBhbmFseXNpcyBmcmFtZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXJzWzBdLnNtb290aGluZ1RpbWVDb25zdGFudDtcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyh2YWwpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goYSA9PiBhLnNtb290aGluZ1RpbWVDb25zdGFudCA9IHZhbCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goYSA9PiBhLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFuYWx5c2VyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQW5hbHlzZXIgfSBmcm9tIFwiLi9BbmFseXNlclwiO1xuLyoqXG4gKiBUaGUgYmFzZSBjbGFzcyBmb3IgTWV0ZXJpbmcgY2xhc3Nlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1ldGVyQmFzZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRlckJhc2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0ZXJCYXNlXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuX2FuYWx5c2VyID0gbmV3IEFuYWx5c2VyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHNpemU6IDI1NixcbiAgICAgICAgICAgIHR5cGU6IFwid2F2ZWZvcm1cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NZXRlckJhc2UuanMubWFwIiwiaW1wb3J0IHsgZ2FpblRvRGIgfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuaW1wb3J0IHsgd2FybiB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IEFuYWx5c2VyIH0gZnJvbSBcIi4vQW5hbHlzZXJcIjtcbi8qKlxuICogTWV0ZXIgZ2V0cyB0aGUgW1JNU10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUm9vdF9tZWFuX3NxdWFyZSlcbiAqIG9mIGFuIGlucHV0IHNpZ25hbC4gSXQgY2FuIGFsc28gZ2V0IHRoZSByYXcgdmFsdWUgb2YgdGhlIGlucHV0IHNpZ25hbC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWV0ZXIgPSBuZXcgVG9uZS5NZXRlcigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCk7XG4gKiBtaWMub3BlbigpO1xuICogLy8gY29ubmVjdCBtaWMgdG8gdGhlIG1ldGVyXG4gKiBtaWMuY29ubmVjdChtZXRlcik7XG4gKiAvLyB0aGUgY3VycmVudCBsZXZlbCBvZiB0aGUgbWljXG4gKiBzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhtZXRlci5nZXRWYWx1ZSgpKSwgMTAwKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1ldGVyIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNZXRlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHByZXZpb3VzIGZyYW1lJ3MgdmFsdWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3JtcyA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNtb290aGluZ1wiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuX2FuYWx5c2VyID0gbmV3IEFuYWx5c2VyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHNpemU6IDI1NixcbiAgICAgICAgICAgIHR5cGU6IFwid2F2ZWZvcm1cIixcbiAgICAgICAgICAgIGNoYW5uZWxzOiBvcHRpb25zLmNoYW5uZWxzLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zbW9vdGhpbmcgPSBvcHRpb25zLnNtb290aGluZyxcbiAgICAgICAgICAgIHRoaXMubm9ybWFsUmFuZ2UgPSBvcHRpb25zLm5vcm1hbFJhbmdlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1ldGVyQmFzZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzbW9vdGhpbmc6IDAuOCxcbiAgICAgICAgICAgIG5vcm1hbFJhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgIGNoYW5uZWxzOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXNlIFtbZ2V0VmFsdWVdXSBpbnN0ZWFkLiBGb3IgdGhlIHByZXZpb3VzIGdldFZhbHVlIGJlaGF2aW9yLCB1c2UgRENNZXRlci5cbiAgICAgKiBAZGVwcmVjYXRlZFxuICAgICAqL1xuICAgIGdldExldmVsKCkge1xuICAgICAgICB3YXJuKFwiJ2dldExldmVsJyBoYXMgYmVlbiBjaGFuZ2VkIHRvICdnZXRWYWx1ZSdcIik7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgaW5jb21pbmcgc2lnbmFsLlxuICAgICAqIE91dHB1dCBpcyBpbiBkZWNpYmVscyB3aGVuIFtbbm9ybWFsUmFuZ2VdXSBpcyBgZmFsc2VgLlxuICAgICAqIElmIFtbY2hhbm5lbHNdXSA9IDEsIHRoZW4gdGhlIG91dHB1dCBpcyBhIHNpbmdsZSBudW1iZXJcbiAgICAgKiByZXByZXNlbnRpbmcgdGhlIHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwuIFdoZW4gW1tjaGFubmVsc11dID4gMSxcbiAgICAgKiB0aGVuIGVhY2ggY2hhbm5lbCBpcyByZXR1cm5lZCBhcyBhIHZhbHVlIGluIGEgbnVtYmVyIGFycmF5LlxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBjb25zdCBhVmFsdWVzID0gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICAgICAgY29uc3QgY2hhbm5lbFZhbHVlcyA9IHRoaXMuY2hhbm5lbHMgPT09IDEgPyBbYVZhbHVlc10gOiBhVmFsdWVzO1xuICAgICAgICBjb25zdCB2YWxzID0gY2hhbm5lbFZhbHVlcy5tYXAodmFsdWVzID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRvdGFsU3F1YXJlZCA9IHZhbHVlcy5yZWR1Y2UoKHRvdGFsLCBjdXJyZW50KSA9PiB0b3RhbCArIGN1cnJlbnQgKiBjdXJyZW50LCAwKTtcbiAgICAgICAgICAgIGNvbnN0IHJtcyA9IE1hdGguc3FydCh0b3RhbFNxdWFyZWQgLyB2YWx1ZXMubGVuZ3RoKTtcbiAgICAgICAgICAgIC8vIHRoZSBybXMgY2FuIG9ubHkgZmFsbCBhdCB0aGUgcmF0ZSBvZiB0aGUgc21vb3RoaW5nXG4gICAgICAgICAgICAvLyBidXQgY2FuIGp1bXAgdXAgaW5zdGFudGx5XG4gICAgICAgICAgICB0aGlzLl9ybXMgPSBNYXRoLm1heChybXMsIHRoaXMuX3JtcyAqIHRoaXMuc21vb3RoaW5nKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5vcm1hbFJhbmdlID8gdGhpcy5fcm1zIDogZ2FpblRvRGIodGhpcy5fcm1zKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLmNoYW5uZWxzID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsc1swXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWxzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgb2YgYW5hbHlzaXMuXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuY2hhbm5lbHM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NZXRlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEdldCB0aGUgY3VycmVudCBmcmVxdWVuY3kgZGF0YSBvZiB0aGUgY29ubmVjdGVkIGF1ZGlvIHNvdXJjZSB1c2luZyBhIGZhc3QgRm91cmllciB0cmFuc2Zvcm0uXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGRlQgZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGRlQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRkZUXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGRlQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKTtcbiAgICAgICAgdGhpcy5ub3JtYWxSYW5nZSA9IG9wdGlvbnMubm9ybWFsUmFuZ2U7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnR5cGUgPSBcImZmdFwiO1xuICAgICAgICB0aGlzLnNpemUgPSBvcHRpb25zLnNpemU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBub3JtYWxSYW5nZTogZmFsc2UsXG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBjdXJyZW50IGZyZXF1ZW5jeSBkYXRhIGZyb20gdGhlIGNvbm5lY3RlZCBhdWRpbyBzb3VyY2UuXG4gICAgICogUmV0dXJucyB0aGUgZnJlcXVlbmN5IGRhdGEgb2YgbGVuZ3RoIFtbc2l6ZV1dIGFzIGEgRmxvYXQzMkFycmF5IG9mIGRlY2liZWwgdmFsdWVzLlxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuICAgICAgICByZXR1cm4gdmFsdWVzLm1hcCh2ID0+IHRoaXMubm9ybWFsUmFuZ2UgPyBkYlRvR2Fpbih2KSA6IHYpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2l6ZSBvZiBhbmFseXNpcy4gVGhpcyBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGluIHRoZSByYW5nZSAxNiB0byAxNjM4NC5cbiAgICAgKiBEZXRlcm1pbmVzIHRoZSBzaXplIG9mIHRoZSBhcnJheSByZXR1cm5lZCBieSBbW2dldFZhbHVlXV0gKGkuZS4gdGhlIG51bWJlciBvZlxuICAgICAqIGZyZXF1ZW5jeSBiaW5zKS4gTGFyZ2UgRkZUIHNpemVzIG1heSBiZSBjb3N0bHkgdG8gY29tcHV0ZS5cbiAgICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLnNpemU7XG4gICAgfVxuICAgIHNldCBzaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc2l6ZSA9IHNpemU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIDAgcmVwcmVzZW50cyBubyB0aW1lIGF2ZXJhZ2luZyB3aXRoIHRoZSBsYXN0IGFuYWx5c2lzIGZyYW1lLlxuICAgICAqL1xuICAgIGdldCBzbW9vdGhpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5zbW9vdGhpbmc7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcodmFsKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNtb290aGluZyA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgZnJlcXVlbmN5IHZhbHVlIGluIGhlcnR6IG9mIGVhY2ggb2YgdGhlIGluZGljZXMgb2YgdGhlIEZGVCdzIFtbZ2V0VmFsdWVdXSByZXNwb25zZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZmdCA9IG5ldyBUb25lLkZGVCgzMik7XG4gICAgICogY29uc29sZS5sb2coWzAsIDEsIDIsIDMsIDRdLm1hcChpbmRleCA9PiBmZnQuZ2V0RnJlcXVlbmN5T2ZJbmRleChpbmRleCkpKTtcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lPZkluZGV4KGluZGV4KSB7XG4gICAgICAgIGFzc2VydCgwIDw9IGluZGV4ICYmIGluZGV4IDwgdGhpcy5zaXplLCBgaW5kZXggbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMCBhbmQgbGVzcyB0aGFuICR7dGhpcy5zaXplfWApO1xuICAgICAgICByZXR1cm4gaW5kZXggKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvICh0aGlzLnNpemUgKiAyKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GRlQuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbi8qKlxuICogRENNZXRlciBnZXRzIHRoZSByYXcgdmFsdWUgb2YgdGhlIGlucHV0IHNpZ25hbCBhdCB0aGUgY3VycmVudCB0aW1lLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXRlciA9IG5ldyBUb25lLkRDTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpO1xuICogbWljLm9wZW4oKTtcbiAqIC8vIGNvbm5lY3QgbWljIHRvIHRoZSBtZXRlclxuICogbWljLmNvbm5lY3QobWV0ZXIpO1xuICogLy8gdGhlIGN1cnJlbnQgbGV2ZWwgb2YgdGhlIG1pY1xuICogY29uc3QgbGV2ZWwgPSBtZXRlci5nZXRWYWx1ZSgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRENNZXRlciBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKERDTWV0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRENNZXRlclwiO1xuICAgICAgICB0aGlzLl9hbmFseXNlci50eXBlID0gXCJ3YXZlZm9ybVwiO1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gMjU2O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHNpZ25hbCB2YWx1ZSBvZiB0aGUgaW5jb21pbmcgc2lnbmFsXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlWzBdO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURDTWV0ZXIuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IHdhdmVmb3JtIGRhdGEgb2YgdGhlIGNvbm5lY3RlZCBhdWRpbyBzb3VyY2UuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBXYXZlZm9ybSBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFdhdmVmb3JtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIldhdmVmb3JtXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlZm9ybS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pO1xuICAgICAgICB0aGlzLl9hbmFseXNlci50eXBlID0gXCJ3YXZlZm9ybVwiO1xuICAgICAgICB0aGlzLnNpemUgPSBvcHRpb25zLnNpemU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oTWV0ZXJCYXNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNpemU6IDEwMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHdhdmVmb3JtIGZvciB0aGUgY3VycmVudCB0aW1lIGFzIGEgRmxvYXQzMkFycmF5IHdoZXJlIGVhY2ggdmFsdWUgaW4gdGhlIGFycmF5XG4gICAgICogcmVwcmVzZW50cyBhIHNhbXBsZSBpbiB0aGUgd2F2ZWZvcm0uXG4gICAgICovXG4gICAgZ2V0VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5nZXRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2l6ZSBvZiBhbmFseXNpcy4gVGhpcyBtdXN0IGJlIGEgcG93ZXIgb2YgdHdvIGluIHRoZSByYW5nZSAxNiB0byAxNjM4NC5cbiAgICAgKiBEZXRlcm1pbmVzIHRoZSBzaXplIG9mIHRoZSBhcnJheSByZXR1cm5lZCBieSBbW2dldFZhbHVlXV0uXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5zaXplO1xuICAgIH1cbiAgICBzZXQgc2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSBzaXplO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVdhdmVmb3JtLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBTb2xvIGxldHMgeW91IGlzb2xhdGUgYSBzcGVjaWZpYyBhdWRpbyBzdHJlYW0uIFdoZW4gYW4gaW5zdGFuY2UgaXMgc2V0IHRvIGBzb2xvPXRydWVgLFxuICogaXQgd2lsbCBtdXRlIGFsbCBvdGhlciBpbnN0YW5jZXMgb2YgU29sby5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzb2xvQSA9IG5ldyBUb25lLlNvbG8oKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2NBID0gbmV3IFRvbmUuT3NjaWxsYXRvcihcIkM0XCIsIFwic2F3dG9vdGhcIikuY29ubmVjdChzb2xvQSk7XG4gKiBjb25zdCBzb2xvQiA9IG5ldyBUb25lLlNvbG8oKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2NCID0gbmV3IFRvbmUuT3NjaWxsYXRvcihcIkU0XCIsIFwic3F1YXJlXCIpLmNvbm5lY3Qoc29sb0IpO1xuICogc29sb0Euc29sbyA9IHRydWU7XG4gKiAvLyBubyBhdWRpbyB3aWxsIHBhc3MgdGhyb3VnaCBzb2xvQlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgU29sbyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTb2xvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic29sb1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNvbG9cIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNvbG8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzb2xvXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFTb2xvLl9hbGxTb2xvcy5oYXModGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgU29sby5fYWxsU29sb3Muc2V0KHRoaXMuY29udGV4dCwgbmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBTb2xvLl9hbGxTb2xvcy5nZXQodGhpcy5jb250ZXh0KS5hZGQodGhpcyk7XG4gICAgICAgIC8vIHNldCBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5zb2xvID0gb3B0aW9ucy5zb2xvO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc29sbzogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJc29sYXRlcyB0aGlzIGluc3RhbmNlIGFuZCBtdXRlcyBhbGwgb3RoZXIgaW5zdGFuY2VzIG9mIFNvbG8uXG4gICAgICogT25seSBvbmUgaW5zdGFuY2UgY2FuIGJlIHNvbG9lZCBhdCBhIHRpbWUuIEEgc29sb2VkXG4gICAgICogaW5zdGFuY2Ugd2lsbCByZXBvcnQgYHNvbG89ZmFsc2VgIHdoZW4gYW5vdGhlciBpbnN0YW5jZSBpcyBzb2xvZWQuXG4gICAgICovXG4gICAgZ2V0IHNvbG8oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc1NvbG9lZCgpO1xuICAgIH1cbiAgICBzZXQgc29sbyhzb2xvKSB7XG4gICAgICAgIGlmIChzb2xvKSB7XG4gICAgICAgICAgICB0aGlzLl9hZGRTb2xvKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVTb2xvKCk7XG4gICAgICAgIH1cbiAgICAgICAgU29sby5fYWxsU29sb3MuZ2V0KHRoaXMuY29udGV4dCkuZm9yRWFjaChpbnN0YW5jZSA9PiBpbnN0YW5jZS5fdXBkYXRlU29sbygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGN1cnJlbnQgaW5zdGFuY2UgaXMgbXV0ZWQsIGkuZS4gYW5vdGhlciBpbnN0YW5jZSBpcyBzb2xvZWRcbiAgICAgKi9cbiAgICBnZXQgbXV0ZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlucHV0LmdhaW4udmFsdWUgPT09IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCB0aGlzIHRvIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfYWRkU29sbygpIHtcbiAgICAgICAgaWYgKCFTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkpIHtcbiAgICAgICAgICAgIFNvbG8uX3NvbG9lZC5zZXQodGhpcy5jb250ZXh0LCBuZXcgU2V0KCkpO1xuICAgICAgICB9XG4gICAgICAgIFNvbG8uX3NvbG9lZC5nZXQodGhpcy5jb250ZXh0KS5hZGQodGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGlzIGZyb20gdGhlIHNvbG9lZCBhcnJheVxuICAgICAqL1xuICAgIF9yZW1vdmVTb2xvKCkge1xuICAgICAgICBpZiAoU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICBTb2xvLl9zb2xvZWQuZ2V0KHRoaXMuY29udGV4dCkuZGVsZXRlKHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElzIHRoaXMgb24gdGhlIHNvbG9lZCBhcnJheVxuICAgICAqL1xuICAgIF9pc1NvbG9lZCgpIHtcbiAgICAgICAgcmV0dXJuIFNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSAmJiBTb2xvLl9zb2xvZWQuZ2V0KHRoaXMuY29udGV4dCkuaGFzKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRydWUgaWYgbm8gb25lIGlzIHNvbG9lZFxuICAgICAqL1xuICAgIF9ub1NvbG9zKCkge1xuICAgICAgICAvLyBlaXRoZXIgZG9lcyBub3QgaGF2ZSBhbnkgc29sb2VkIGFkZGVkXG4gICAgICAgIHJldHVybiAhU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpIHx8XG4gICAgICAgICAgICAvLyBvciBoYXMgYSBzb2xvIHNldCBidXQgZG9lc24ndCBpbmNsdWRlIGFueSBpdGVtc1xuICAgICAgICAgICAgKFNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSAmJiBTb2xvLl9zb2xvZWQuZ2V0KHRoaXMuY29udGV4dCkuc2l6ZSA9PT0gMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNvbG8gdGhlIGN1cnJlbnQgaW5zdGFuY2UgYW5kIHVuc29sbyBhbGwgb3RoZXIgaW5zdGFuY2VzLlxuICAgICAqL1xuICAgIF91cGRhdGVTb2xvKCkge1xuICAgICAgICBpZiAodGhpcy5faXNTb2xvZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5nYWluLnZhbHVlID0gMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9ub1NvbG9zKCkpIHtcbiAgICAgICAgICAgIC8vIG5vIG9uZSBpcyBzb2xvZWRcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgU29sby5fYWxsU29sb3MuZ2V0KHRoaXMuY29udGV4dCkuZGVsZXRlKHRoaXMpO1xuICAgICAgICB0aGlzLl9yZW1vdmVTb2xvKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogSG9sZCBhbGwgb2YgdGhlIHNvbG8nZWQgdHJhY2tzIGJlbG9uZ2luZyB0byBhIHNwZWNpZmljIGNvbnRleHRcbiAqL1xuU29sby5fYWxsU29sb3MgPSBuZXcgTWFwKCk7XG4vKipcbiAqIEhvbGQgdGhlIGN1cnJlbnRseSBzb2xvJ2VkIGluc3RhbmNlKHMpXG4gKi9cblNvbG8uX3NvbG9lZCA9IG5ldyBNYXAoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNvbG8uanMubWFwIiwiaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBQYW5uZXIgfSBmcm9tIFwiLi9QYW5uZXJcIjtcbmltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuL1ZvbHVtZVwiO1xuLyoqXG4gKiBQYW5Wb2wgaXMgYSBUb25lLlBhbm5lciBhbmQgVG9uZS5Wb2x1bWUgaW4gb25lLlxuICogQGV4YW1wbGVcbiAqIC8vIHBhbiB0aGUgaW5jb21pbmcgc2lnbmFsIGxlZnQgYW5kIGRyb3AgdGhlIHZvbHVtZVxuICogY29uc3QgcGFuVm9sID0gbmV3IFRvbmUuUGFuVm9sKC0wLjI1LCAtMTIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHBhblZvbCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhblZvbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5Wb2wuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYW5Wb2xcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhblZvbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInBhblwiLCBcInZvbHVtZVwiXSk7XG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuaW5wdXQgPSBuZXcgUGFubmVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhbjogb3B0aW9ucy5wYW4sXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wYW4gPSB0aGlzLl9wYW5uZXIucGFuO1xuICAgICAgICB0aGlzLl92b2x1bWUgPSB0aGlzLm91dHB1dCA9IG5ldyBWb2x1bWUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdm9sdW1lOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fdm9sdW1lLnZvbHVtZTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbm5lY3QodGhpcy5fdm9sdW1lKTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBwYW46IDAsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlL3VubXV0ZSB0aGUgdm9sdW1lXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhblZvbC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNvbG8gfSBmcm9tIFwiLi9Tb2xvXCI7XG5pbXBvcnQgeyBQYW5Wb2wgfSBmcm9tIFwiLi9QYW5Wb2xcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbi8qKlxuICogQ2hhbm5lbCBwcm92aWRlcyBhIGNoYW5uZWwgc3RyaXAgaW50ZXJmYWNlIHdpdGggdm9sdW1lLCBwYW4sIHNvbG8gYW5kIG11dGUgY29udHJvbHMuXG4gKiBTZWUgW1tQYW5Wb2xdXSBhbmQgW1tTb2xvXV1cbiAqIEBleGFtcGxlXG4gKiAvLyBwYW4gdGhlIGluY29taW5nIHNpZ25hbCBsZWZ0IGFuZCBkcm9wIHRoZSB2b2x1bWUgMTJkYlxuICogY29uc3QgY2hhbm5lbCA9IG5ldyBUb25lLkNoYW5uZWwoLTAuMjUsIC0xMik7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDaGFubmVsIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENoYW5uZWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIiwgXCJwYW5cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDaGFubmVsXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGFubmVsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCIsIFwicGFuXCJdKTtcbiAgICAgICAgdGhpcy5fc29sbyA9IHRoaXMuaW5wdXQgPSBuZXcgU29sbyh7XG4gICAgICAgICAgICBzb2xvOiBvcHRpb25zLnNvbG8sXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wYW5Wb2wgPSB0aGlzLm91dHB1dCA9IG5ldyBQYW5Wb2woe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFuOiBvcHRpb25zLnBhbixcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgICAgICBtdXRlOiBvcHRpb25zLm11dGUsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBhbiA9IHRoaXMuX3BhblZvbC5wYW47XG4gICAgICAgIHRoaXMudm9sdW1lID0gdGhpcy5fcGFuVm9sLnZvbHVtZTtcbiAgICAgICAgdGhpcy5fc29sby5jb25uZWN0KHRoaXMuX3BhblZvbCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInBhblwiLCBcInZvbHVtZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwYW46IDAsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHNvbG86IGZhbHNlLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU29sby91bnNvbG8gdGhlIGNoYW5uZWwuIFNvbG9pbmcgaXMgb25seSByZWxhdGl2ZSB0byBvdGhlciBbW0NoYW5uZWxzXV0gYW5kIFtbU29sb11dIGluc3RhbmNlc1xuICAgICAqL1xuICAgIGdldCBzb2xvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc29sby5zb2xvO1xuICAgIH1cbiAgICBzZXQgc29sbyhzb2xvKSB7XG4gICAgICAgIHRoaXMuX3NvbG8uc29sbyA9IHNvbG87XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBjdXJyZW50IGluc3RhbmNlIGlzIG11dGVkLCBpLmUuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkLFxuICAgICAqIG9yIHRoZSBjaGFubmVsIGlzIG11dGVkXG4gICAgICovXG4gICAgZ2V0IG11dGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc29sby5tdXRlZCB8fCB0aGlzLm11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE11dGUvdW5tdXRlIHRoZSB2b2x1bWVcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhblZvbC5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3BhblZvbC5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBnYWluIG5vZGUgYmVsb25naW5nIHRvIHRoZSBidXMgbmFtZS4gQ3JlYXRlIGl0IGlmXG4gICAgICogaXQgZG9lc24ndCBleGlzdFxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBidXMgbmFtZVxuICAgICAqL1xuICAgIF9nZXRCdXMobmFtZSkge1xuICAgICAgICBpZiAoIUNoYW5uZWwuYnVzZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICBDaGFubmVsLmJ1c2VzLnNldChuYW1lLCBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIENoYW5uZWwuYnVzZXMuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZW5kIGF1ZGlvIHRvIGFub3RoZXIgY2hhbm5lbCB1c2luZyBhIHN0cmluZy4gYHNlbmRgIGlzIGEgbG90IGxpa2VcbiAgICAgKiBbW2Nvbm5lY3RdXSwgZXhjZXB0IGl0IHVzZXMgYSBzdHJpbmcgaW5zdGVhZCBvZiBhbiBvYmplY3QuIFRoaXMgY2FuXG4gICAgICogYmUgdXNlZnVsIGluIGxhcmdlIGFwcGxpY2F0aW9ucyB0byBkZWNvdXBsZSBzZWN0aW9ucyBzaW5jZSBbW3NlbmRdXVxuICAgICAqIGFuZCBbW3JlY2VpdmVdXSBjYW4gYmUgaW52b2tlZCBzZXBhcmF0ZWx5IGluIG9yZGVyIHRvIGNvbm5lY3QgYW4gb2JqZWN0XG4gICAgICogQHBhcmFtIG5hbWUgVGhlIGNoYW5uZWwgbmFtZSB0byBzZW5kIHRoZSBhdWRpb1xuICAgICAqIEBwYXJhbSB2b2x1bWUgVGhlIGFtb3VudCBvZiB0aGUgc2lnbmFsIHRvIHNlbmQuXG4gICAgICogXHREZWZhdWx0cyB0byAwZGIsIGkuZS4gc2VuZCB0aGUgZW50aXJlIHNpZ25hbFxuICAgICAqIEByZXR1cm5zIFJldHVybnMgdGhlIGdhaW4gbm9kZSBvZiB0aGlzIGNvbm5lY3Rpb24uXG4gICAgICovXG4gICAgc2VuZChuYW1lLCB2b2x1bWUgPSAwKSB7XG4gICAgICAgIGNvbnN0IGJ1cyA9IHRoaXMuX2dldEJ1cyhuYW1lKTtcbiAgICAgICAgY29uc3Qgc2VuZEtub2IgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICAgICAgZ2Fpbjogdm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jb25uZWN0KHNlbmRLbm9iKTtcbiAgICAgICAgc2VuZEtub2IuY29ubmVjdChidXMpO1xuICAgICAgICByZXR1cm4gc2VuZEtub2I7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlY2VpdmUgYXVkaW8gZnJvbSBhIGNoYW5uZWwgd2hpY2ggd2FzIGNvbm5lY3RlZCB3aXRoIFtbc2VuZF1dLlxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBjaGFubmVsIG5hbWUgdG8gcmVjZWl2ZSBhdWRpbyBmcm9tLlxuICAgICAqL1xuICAgIHJlY2VpdmUobmFtZSkge1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLl9nZXRCdXMobmFtZSk7XG4gICAgICAgIGJ1cy5jb25uZWN0KHRoaXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5Wb2wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBhbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc29sby5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogU3RvcmUgdGhlIHNlbmQvcmVjZWl2ZSBjaGFubmVscyBieSBuYW1lLlxuICovXG5DaGFubmVsLmJ1c2VzID0gbmV3IE1hcCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2hhbm5lbC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4vTWVyZ2VcIjtcbi8qKlxuICogTW9ubyBjb2VyY2VzIHRoZSBpbmNvbWluZyBtb25vIG9yIHN0ZXJlbyBzaWduYWwgaW50byBhIG1vbm8gc2lnbmFsXG4gKiB3aGVyZSBib3RoIGxlZnQgYW5kIHJpZ2h0IGNoYW5uZWxzIGhhdmUgdGhlIHNhbWUgdmFsdWUuIFRoaXMgY2FuIGJlIHVzZWZ1bFxuICogZm9yIFtzdGVyZW8gaW1hZ2luZ10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3RlcmVvX2ltYWdpbmcpLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTW9ubyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1vbm9cIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9tZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IE1lcmdlKHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAwKTtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX21lcmdlLCAwLCAxKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb25vLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vZmlsdGVyL0ZpbHRlclwiO1xuLyoqXG4gKiBTcGxpdCB0aGUgaW5jb21pbmcgc2lnbmFsIGludG8gdGhyZWUgYmFuZHMgKGxvdywgbWlkLCBoaWdoKVxuICogd2l0aCB0d28gY3Jvc3NvdmVyIGZyZXF1ZW5jeSBjb250cm9scy5cbiAqIGBgYFxuICogICAgICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgICstPiBpbnB1dCA8IGxvd0ZyZXF1ZW5jeSArLS0tLS0tLS0tLS0tLS0tLS0tPiBsb3dcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICB8XG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqIGlucHV0IC0tLSstPiBsb3dGcmVxdWVuY3kgPCBpbnB1dCA8IGhpZ2hGcmVxdWVuY3kgKy0tPiBtaWRcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgfFxuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICArLT4gaGlnaEZyZXF1ZW5jeSA8IGlucHV0ICstLS0tLS0tLS0tLS0tLS0tLT4gaGlnaFxuICogICAgICAgICAgICArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpYmFuZFNwbGl0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpYmFuZFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk11bHRpYmFuZFNwbGl0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgaW5wdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5vIG91dHB1dCBub2RlLCB1c2UgZWl0aGVyIGxvdywgbWlkIG9yIGhpZ2ggb3V0cHV0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbG93IGJhbmQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmxvdyA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGxvd2VyIGZpbHRlciBvZiB0aGUgbWlkIGJhbmRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvd01pZEZpbHRlciA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgdHlwZTogXCJoaWdocGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtaWQgYmFuZCBvdXRwdXQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGhpZ2ggYmFuZCBvdXRwdXQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmhpZ2ggPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwiaGlnaHBhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5sb3csIHRoaXMubWlkLCB0aGlzLmhpZ2hdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGliYW5kU3BsaXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dGcmVxdWVuY3lcIiwgXCJoaWdoRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhpZ2hGcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLlEgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dC5mYW4odGhpcy5sb3csIHRoaXMuaGlnaCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fbG93TWlkRmlsdGVyLCB0aGlzLm1pZCk7XG4gICAgICAgIC8vIHRoZSBmcmVxdWVuY3kgY29udHJvbCBzaWduYWxcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kuZmFuKHRoaXMubG93LmZyZXF1ZW5jeSwgdGhpcy5fbG93TWlkRmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeS5mYW4odGhpcy5taWQuZnJlcXVlbmN5LCB0aGlzLmhpZ2guZnJlcXVlbmN5KTtcbiAgICAgICAgLy8gdGhlIFEgdmFsdWVcbiAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5sb3cuUSk7XG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMuX2xvd01pZEZpbHRlci5RKTtcbiAgICAgICAgdGhpcy5RLmNvbm5lY3QodGhpcy5taWQuUSk7XG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMuaGlnaC5RKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiaGlnaFwiLCBcIm1pZFwiLCBcImxvd1wiLCBcImhpZ2hGcmVxdWVuY3lcIiwgXCJsb3dGcmVxdWVuY3lcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IDI1MDAsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IDQwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgW1wiaGlnaFwiLCBcIm1pZFwiLCBcImxvd1wiLCBcImhpZ2hGcmVxdWVuY3lcIiwgXCJsb3dGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmxvdy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xvd01pZEZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NdWx0aWJhbmRTcGxpdC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi9QYXJhbVwiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbi8qKlxuICogVG9uZS5MaXN0ZW5lciBpcyBhIHRoaW4gd3JhcHBlciBhcm91bmQgdGhlIEF1ZGlvTGlzdGVuZXIuIExpc3RlbmVyIGNvbWJpbmVkXG4gKiB3aXRoIFtbUGFubmVyM0RdXSBtYWtlcyB1cCB0aGUgV2ViIEF1ZGlvIEFQSSdzIDNEIHBhbm5pbmcgc3lzdGVtLiBQYW5uZXIzRCBhbGxvd3MgeW91XG4gKiB0byBwbGFjZSBzb3VuZHMgaW4gM0QgYW5kIExpc3RlbmVyIGFsbG93cyB5b3UgdG8gbmF2aWdhdGUgdGhlIDNEIHNvdW5kIGVudmlyb25tZW50IGZyb21cbiAqIGEgZmlyc3QtcGVyc29uIHBlcnNwZWN0aXZlLiBUaGVyZSBpcyBvbmx5IG9uZSBsaXN0ZW5lciBwZXIgYXVkaW8gY29udGV4dC5cbiAqL1xuZXhwb3J0IGNsYXNzIExpc3RlbmVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTGlzdGVuZXJcIjtcbiAgICAgICAgdGhpcy5wb3NpdGlvblggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5wb3NpdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIucG9zaXRpb25aLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIuZm9yd2FyZFgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcndhcmRZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5mb3J3YXJkWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRaLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cFggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnVwWCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBZID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci51cFksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIudXBaLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBvc2l0aW9uWDogMCxcbiAgICAgICAgICAgIHBvc2l0aW9uWTogMCxcbiAgICAgICAgICAgIHBvc2l0aW9uWjogMCxcbiAgICAgICAgICAgIGZvcndhcmRYOiAwLFxuICAgICAgICAgICAgZm9yd2FyZFk6IDAsXG4gICAgICAgICAgICBmb3J3YXJkWjogLTEsXG4gICAgICAgICAgICB1cFg6IDAsXG4gICAgICAgICAgICB1cFk6IDEsXG4gICAgICAgICAgICB1cFo6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25YLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFguZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZvcndhcmRZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudXBYLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51cFkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVwWi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQubGlzdGVuZXIgPSBuZXcgTGlzdGVuZXIoeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0Lmxpc3RlbmVyLmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TGlzdGVuZXIuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCBcIi4uLy4uL2NvcmUvY29udGV4dC9MaXN0ZW5lclwiO1xuLyoqXG4gKiBBIHNwYXRpYWxpemVkIHBhbm5lciBub2RlIHdoaWNoIHN1cHBvcnRzIGVxdWFscG93ZXIgb3IgSFJURiBwYW5uaW5nLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUGFubmVyM0QgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFubmVyM0QuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwb3NpdGlvblhcIiwgXCJwb3NpdGlvbllcIiwgXCJwb3NpdGlvblpcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYW5uZXIzRFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFubmVyM0QuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwb3NpdGlvblhcIiwgXCJwb3NpdGlvbllcIiwgXCJwb3NpdGlvblpcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgICAgIC8vIHNldCBzb21lIHZhbHVlc1xuICAgICAgICB0aGlzLnBhbm5pbmdNb2RlbCA9IG9wdGlvbnMucGFubmluZ01vZGVsO1xuICAgICAgICB0aGlzLm1heERpc3RhbmNlID0gb3B0aW9ucy5tYXhEaXN0YW5jZTtcbiAgICAgICAgdGhpcy5kaXN0YW5jZU1vZGVsID0gb3B0aW9ucy5kaXN0YW5jZU1vZGVsO1xuICAgICAgICB0aGlzLmNvbmVPdXRlckdhaW4gPSBvcHRpb25zLmNvbmVPdXRlckdhaW47XG4gICAgICAgIHRoaXMuY29uZU91dGVyQW5nbGUgPSBvcHRpb25zLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB0aGlzLmNvbmVJbm5lckFuZ2xlID0gb3B0aW9ucy5jb25lSW5uZXJBbmdsZTtcbiAgICAgICAgdGhpcy5yZWZEaXN0YW5jZSA9IG9wdGlvbnMucmVmRGlzdGFuY2U7XG4gICAgICAgIHRoaXMucm9sbG9mZkZhY3RvciA9IG9wdGlvbnMucm9sbG9mZkZhY3RvcjtcbiAgICAgICAgdGhpcy5wb3NpdGlvblggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wb3NpdGlvblgsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wb3NpdGlvblgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBvc2l0aW9uWSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBvc2l0aW9uWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucG9zaXRpb25aLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucG9zaXRpb25aLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblgsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vcmllbnRhdGlvblgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLm9yaWVudGF0aW9uWSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9yaWVudGF0aW9uWSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25aID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIub3JpZW50YXRpb25aLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub3JpZW50YXRpb25aLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvbmVJbm5lckFuZ2xlOiAzNjAsXG4gICAgICAgICAgICBjb25lT3V0ZXJBbmdsZTogMzYwLFxuICAgICAgICAgICAgY29uZU91dGVyR2FpbjogMCxcbiAgICAgICAgICAgIGRpc3RhbmNlTW9kZWw6IFwiaW52ZXJzZVwiLFxuICAgICAgICAgICAgbWF4RGlzdGFuY2U6IDEwMDAwLFxuICAgICAgICAgICAgb3JpZW50YXRpb25YOiAwLFxuICAgICAgICAgICAgb3JpZW50YXRpb25ZOiAwLFxuICAgICAgICAgICAgb3JpZW50YXRpb25aOiAwLFxuICAgICAgICAgICAgcGFubmluZ01vZGVsOiBcImVxdWFscG93ZXJcIixcbiAgICAgICAgICAgIHBvc2l0aW9uWDogMCxcbiAgICAgICAgICAgIHBvc2l0aW9uWTogMCxcbiAgICAgICAgICAgIHBvc2l0aW9uWjogMCxcbiAgICAgICAgICAgIHJlZkRpc3RhbmNlOiAxLFxuICAgICAgICAgICAgcm9sbG9mZkZhY3RvcjogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIHBvc2l0aW9uIG9mIHRoZSBzb3VyY2UgaW4gM2Qgc3BhY2UuXG4gICAgICovXG4gICAgc2V0UG9zaXRpb24oeCwgeSwgeikge1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC52YWx1ZSA9IHg7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLnZhbHVlID0geTtcbiAgICAgICAgdGhpcy5wb3NpdGlvbloudmFsdWUgPSB6O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0cyB0aGUgb3JpZW50YXRpb24gb2YgdGhlIHNvdXJjZSBpbiAzZCBzcGFjZS5cbiAgICAgKi9cbiAgICBzZXRPcmllbnRhdGlvbih4LCB5LCB6KSB7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25YLnZhbHVlID0geDtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblkudmFsdWUgPSB5O1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWi52YWx1ZSA9IHo7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGFubmluZyBtb2RlbC4gRWl0aGVyIFwiZXF1YWxwb3dlclwiIG9yIFwiSFJURlwiLlxuICAgICAqL1xuICAgIGdldCBwYW5uaW5nTW9kZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIucGFubmluZ01vZGVsO1xuICAgIH1cbiAgICBzZXQgcGFubmluZ01vZGVsKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIucGFubmluZ01vZGVsID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlZmVyZW5jZSBkaXN0YW5jZSBmb3IgcmVkdWNpbmcgdm9sdW1lIGFzIHNvdXJjZSBtb3ZlIGZ1cnRoZXIgZnJvbSB0aGUgbGlzdGVuZXJcbiAgICAgKi9cbiAgICBnZXQgcmVmRGlzdGFuY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIucmVmRGlzdGFuY2U7XG4gICAgfVxuICAgIHNldCByZWZEaXN0YW5jZSh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLnJlZkRpc3RhbmNlID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXNjcmliZXMgaG93IHF1aWNrbHkgdGhlIHZvbHVtZSBpcyByZWR1Y2VkIGFzIHNvdXJjZSBtb3ZlcyBhd2F5IGZyb20gbGlzdGVuZXIuXG4gICAgICovXG4gICAgZ2V0IHJvbGxvZmZGYWN0b3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIucm9sbG9mZkZhY3RvcjtcbiAgICB9XG4gICAgc2V0IHJvbGxvZmZGYWN0b3IodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5yb2xsb2ZmRmFjdG9yID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGlzdGFuY2UgbW9kZWwgdXNlZCBieSwgIFwibGluZWFyXCIsIFwiaW52ZXJzZVwiLCBvciBcImV4cG9uZW50aWFsXCIuXG4gICAgICovXG4gICAgZ2V0IGRpc3RhbmNlTW9kZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIuZGlzdGFuY2VNb2RlbDtcbiAgICB9XG4gICAgc2V0IGRpc3RhbmNlTW9kZWwodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXN0YW5jZU1vZGVsID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW5nbGUsIGluIGRlZ3JlZXMsIGluc2lkZSBvZiB3aGljaCB0aGVyZSB3aWxsIGJlIG5vIHZvbHVtZSByZWR1Y3Rpb25cbiAgICAgKi9cbiAgICBnZXQgY29uZUlubmVyQW5nbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIuY29uZUlubmVyQW5nbGU7XG4gICAgfVxuICAgIHNldCBjb25lSW5uZXJBbmdsZSh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVJbm5lckFuZ2xlID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW5nbGUsIGluIGRlZ3JlZXMsIG91dHNpZGUgb2Ygd2hpY2ggdGhlIHZvbHVtZSB3aWxsIGJlIHJlZHVjZWRcbiAgICAgKiB0byBhIGNvbnN0YW50IHZhbHVlIG9mIGNvbmVPdXRlckdhaW5cbiAgICAgKi9cbiAgICBnZXQgY29uZU91dGVyQW5nbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIuY29uZU91dGVyQW5nbGU7XG4gICAgfVxuICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVPdXRlckFuZ2xlID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZ2FpbiBvdXRzaWRlIG9mIHRoZSBjb25lT3V0ZXJBbmdsZVxuICAgICAqL1xuICAgIGdldCBjb25lT3V0ZXJHYWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVPdXRlckdhaW47XG4gICAgfVxuICAgIHNldCBjb25lT3V0ZXJHYWluKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuY29uZU91dGVyR2FpbiA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gZGlzdGFuY2UgYmV0d2VlbiBzb3VyY2UgYW5kIGxpc3RlbmVyLFxuICAgICAqIGFmdGVyIHdoaWNoIHRoZSB2b2x1bWUgd2lsbCBub3QgYmUgcmVkdWNlZCBhbnkgZnVydGhlci5cbiAgICAgKi9cbiAgICBnZXQgbWF4RGlzdGFuY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5uZXIubWF4RGlzdGFuY2U7XG4gICAgfVxuICAgIHNldCBtYXhEaXN0YW5jZSh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLm1heERpc3RhbmNlID0gdmFsO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25YLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25YLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhbm5lcjNELmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgdGhlV2luZG93IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBBIHdyYXBwZXIgYXJvdW5kIHRoZSBNZWRpYVJlY29yZGVyIEFQSS4gVW5saWtlIHRoZSByZXN0IG9mIFRvbmUuanMsIHRoaXMgbW9kdWxlIGRvZXMgbm90IG9mZmVyXG4gKiBhbnkgc2FtcGxlLWFjY3VyYXRlIHNjaGVkdWxpbmcgYmVjYXVzZSBpdCBpcyBub3QgYSBmZWF0dXJlIG9mIHRoZSBNZWRpYVJlY29yZGVyIEFQSS5cbiAqIFRoaXMgaXMgb25seSBuYXRpdmVseSBzdXBwb3J0ZWQgaW4gQ2hyb21lIGFuZCBGaXJlZm94LlxuICogRm9yIGEgY3Jvc3MtYnJvd3NlciBzaGltLCBpbnN0YWxsIChhdWRpby1yZWNvcmRlci1wb2x5ZmlsbClbaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvYXVkaW8tcmVjb3JkZXItcG9seWZpbGxdLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJlY29yZGVyID0gbmV3IFRvbmUuUmVjb3JkZXIoKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS5jb25uZWN0KHJlY29yZGVyKTtcbiAqIC8vIHN0YXJ0IHJlY29yZGluZ1xuICogcmVjb3JkZXIuc3RhcnQoKTtcbiAqIC8vIGdlbmVyYXRlIGEgZmV3IG5vdGVzXG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkMzXCIsIDAuNSk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIDAuNSwgXCIrMVwiKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzVcIiwgMC41LCBcIisyXCIpO1xuICogLy8gd2FpdCBmb3IgdGhlIG5vdGVzIHRvIGVuZCBhbmQgc3RvcCB0aGUgcmVjb3JkaW5nXG4gKiBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcbiAqIFx0Ly8gdGhlIHJlY29yZGVkIGF1ZGlvIGlzIHJldHVybmVkIGFzIGEgYmxvYlxuICogXHRjb25zdCByZWNvcmRpbmcgPSBhd2FpdCByZWNvcmRlci5zdG9wKCk7XG4gKiBcdC8vIGRvd25sb2FkIHRoZSByZWNvcmRpbmcgYnkgY3JlYXRpbmcgYW4gYW5jaG9yIGVsZW1lbnQgYW5kIGJsb2IgdXJsXG4gKiBcdGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwocmVjb3JkaW5nKTtcbiAqIFx0Y29uc3QgYW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7XG4gKiBcdGFuY2hvci5kb3dubG9hZCA9IFwicmVjb3JkaW5nLndlYm1cIjtcbiAqIFx0YW5jaG9yLmhyZWYgPSB1cmw7XG4gKiBcdGFuY2hvci5jbGljaygpO1xuICogfSwgNDAwMCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBSZWNvcmRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhSZWNvcmRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJSZWNvcmRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUmVjb3JkZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0KFJlY29yZGVyLnN1cHBvcnRlZCwgXCJNZWRpYSBSZWNvcmRlciBBUEkgaXMgbm90IGF2YWlsYWJsZVwiKTtcbiAgICAgICAgdGhpcy5fc3RyZWFtID0gdGhpcy5jb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKTtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3N0cmVhbSk7XG4gICAgICAgIHRoaXMuX3JlY29yZGVyID0gbmV3IE1lZGlhUmVjb3JkZXIodGhpcy5fc3RyZWFtLnN0cmVhbSwge1xuICAgICAgICAgICAgbWltZVR5cGU6IG9wdGlvbnMubWltZVR5cGVcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbWUgdHlwZSBpcyB0aGUgZm9ybWF0IHRoYXQgdGhlIGF1ZGlvIGlzIGVuY29kZWQgaW4uIEZvciBDaHJvbWVcbiAgICAgKiB0aGF0IGlzIHR5cGljYWxseSB3ZWJtIGVuY29kZWQgYXMgXCJ2b3JiaXNcIi5cbiAgICAgKi9cbiAgICBnZXQgbWltZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZWNvcmRlci5taW1lVHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGVzdCBpZiB5b3VyIHBsYXRmb3JtIHN1cHBvcnRzIHRoZSBNZWRpYSBSZWNvcmRlciBBUEkuIElmIGl0J3Mgbm90IGF2YWlsYWJsZSxcbiAgICAgKiB0cnkgaW5zdGFsbGluZyB0aGlzIChwb2x5ZmlsbClbaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvYXVkaW8tcmVjb3JkZXItcG9seWZpbGxdLlxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQgc3VwcG9ydGVkKCkge1xuICAgICAgICByZXR1cm4gdGhlV2luZG93ICE9PSBudWxsICYmIFJlZmxlY3QuaGFzKHRoZVdpbmRvdywgXCJNZWRpYVJlY29yZGVyXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBSZWNvcmRlciwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICBpZiAodGhpcy5fcmVjb3JkZXIuc3RhdGUgPT09IFwiaW5hY3RpdmVcIikge1xuICAgICAgICAgICAgcmV0dXJuIFwic3RvcHBlZFwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX3JlY29yZGVyLnN0YXRlID09PSBcInBhdXNlZFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJwYXVzZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBcInN0YXJ0ZWRcIjtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgUmVjb3JkZXIuIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzXG4gICAgICogd2hlbiB0aGUgcmVjb3JkZXIgaGFzIHN0YXJ0ZWQuXG4gICAgICovXG4gICAgc3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQodGhpcy5zdGF0ZSAhPT0gXCJzdGFydGVkXCIsIFwiUmVjb3JkZXIgaXMgYWxyZWFkeSBzdGFydGVkXCIpO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRQcm9taXNlID0gbmV3IFByb21pc2UoZG9uZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlU3RhcnQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzdGFydFwiLCBoYW5kbGVTdGFydCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5hZGRFdmVudExpc3RlbmVyKFwic3RhcnRcIiwgaGFuZGxlU3RhcnQsIGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuc3RhcnQoKTtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBzdGFydFByb21pc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSByZWNvcmRlci4gUmV0dXJucyBhIHByb21pc2Ugd2l0aCB0aGUgcmVjb3JkZWQgY29udGVudCB1bnRpbCB0aGlzIHBvaW50XG4gICAgICogZW5jb2RlZCBhcyBbW21pbWVUeXBlXV1cbiAgICAgKi9cbiAgICBzdG9wKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgIT09IFwic3RvcHBlZFwiLCBcIlJlY29yZGVyIGlzIG5vdCBzdGFydGVkXCIpO1xuICAgICAgICAgICAgY29uc3QgZGF0YVByb21pc2UgPSBuZXcgUHJvbWlzZShkb25lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGVEYXRhID0gKGUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImRhdGFhdmFpbGFibGVcIiwgaGFuZGxlRGF0YSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBkb25lKGUuZGF0YSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5hZGRFdmVudExpc3RlbmVyKFwiZGF0YWF2YWlsYWJsZVwiLCBoYW5kbGVEYXRhLCBmYWxzZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnN0b3AoKTtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBkYXRhUHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhdXNlIHRoZSByZWNvcmRlclxuICAgICAqL1xuICAgIHBhdXNlKCkge1xuICAgICAgICBhc3NlcnQodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIsIFwiUmVjb3JkZXIgbXVzdCBiZSBzdGFydGVkXCIpO1xuICAgICAgICB0aGlzLl9yZWNvcmRlci5wYXVzZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RyZWFtLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UmVjb3JkZXIuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ29tcHJlc3NvciBpcyBhIHRoaW4gd3JhcHBlciBhcm91bmQgdGhlIFdlYiBBdWRpb1xuICogW0R5bmFtaWNzQ29tcHJlc3Nvck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWR5bmFtaWNzY29tcHJlc3Nvcm5vZGUtaW50ZXJmYWNlKS5cbiAqIENvbXByZXNzaW9uIHJlZHVjZXMgdGhlIHZvbHVtZSBvZiBsb3VkIHNvdW5kcyBvciBhbXBsaWZpZXMgcXVpZXQgc291bmRzXG4gKiBieSBuYXJyb3dpbmcgb3IgXCJjb21wcmVzc2luZ1wiIGFuIGF1ZGlvIHNpZ25hbCdzIGR5bmFtaWMgcmFuZ2UuXG4gKiBSZWFkIG1vcmUgb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRHluYW1pY19yYW5nZV9jb21wcmVzc2lvbikuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY29tcCA9IG5ldyBUb25lLkNvbXByZXNzb3IoLTMwLCAzKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENvbXByZXNzb3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInJhdGlvXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ29tcHJlc3NvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGNvbXByZXNzb3Igbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29tcHJlc3NvciA9IHRoaXMuY29udGV4dC5jcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2NvbXByZXNzb3I7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fY29tcHJlc3NvcjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJyYXRpb1wiXSk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIG1pblZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZC5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZC5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3IudGhyZXNob2xkLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnRocmVzaG9sZCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXR0YWNrID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIG1pblZhbHVlOiB0aGlzLl9jb21wcmVzc29yLmF0dGFjay5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLmF0dGFjay5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLmF0dGFjayxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmF0dGFjayxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucmVsZWFzZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmVsZWFzZS5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLnJlbGVhc2UsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yZWxlYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5rbmVlID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIG1pblZhbHVlOiB0aGlzLl9jb21wcmVzc29yLmtuZWUubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5rbmVlLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5rbmVlLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmtuZWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJhdGlvID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIG1pblZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJhdGlvLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmF0aW8ubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLnJhdGlvLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnJhdGlvLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gc2V0IHRoZSBkZWZhdWx0c1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJrbmVlXCIsIFwicmVsZWFzZVwiLCBcImF0dGFja1wiLCBcInJhdGlvXCIsIFwidGhyZXNob2xkXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGF0dGFjazogMC4wMDMsXG4gICAgICAgICAgICBrbmVlOiAzMCxcbiAgICAgICAgICAgIHJhdGlvOiAxMixcbiAgICAgICAgICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgcmVhZC1vbmx5IGRlY2liZWwgdmFsdWUgZm9yIG1ldGVyaW5nIHB1cnBvc2VzLCByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgYW1vdW50IG9mIGdhaW5cbiAgICAgKiByZWR1Y3Rpb24gdGhhdCB0aGUgY29tcHJlc3NvciBpcyBhcHBseWluZyB0byB0aGUgc2lnbmFsLiBJZiBmZWQgbm8gc2lnbmFsIHRoZSB2YWx1ZSB3aWxsIGJlIDAgKG5vIGdhaW4gcmVkdWN0aW9uKS5cbiAgICAgKi9cbiAgICBnZXQgcmVkdWN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tcHJlc3Nvci5yZWR1Y3Rpb247XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29tcHJlc3Nvci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuYXR0YWNrLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yZWxlYXNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnJhdGlvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5rbmVlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29tcHJlc3Nvci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHcmVhdGVyVGhhbiB9IGZyb20gXCIuLi8uLi9zaWduYWwvR3JlYXRlclRoYW5cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IEZvbGxvd2VyIH0gZnJvbSBcIi4uL2FuYWx5c2lzL0ZvbGxvd2VyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGRiVG9HYWluLCBnYWluVG9EYiB9IGZyb20gXCIuLi8uLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbi8qKlxuICogR2F0ZSBvbmx5IHBhc3NlcyBhIHNpZ25hbCB0aHJvdWdoIHdoZW4gdGhlIGluY29taW5nXG4gKiBzaWduYWwgZXhjZWVkcyBhIHNwZWNpZmllZCB0aHJlc2hvbGQuIEl0IHVzZXMgW1tGb2xsb3dlcl1dIHRvIGZvbGxvdyB0aGUgYW1wbHRpdWRlXG4gKiBvZiB0aGUgaW5jb21pbmcgc2lnbmFsIGFuZCBjb21wYXJlcyBpdCB0byB0aGUgW1t0aHJlc2hvbGRdXSB2YWx1ZSB1c2luZyBbW0dyZWF0ZXJUaGFuXV0uXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGdhdGUgPSBuZXcgVG9uZS5HYXRlKC0zMCwgMC4yKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKS5jb25uZWN0KGdhdGUpO1xuICogLy8gdGhlIGdhdGUgd2lsbCBvbmx5IHBhc3MgdGhyb3VnaCB0aGUgaW5jb21pbmdcbiAqIC8vIHNpZ25hbCB3aGVuIGl0J3MgbG91ZGVyIHRoYW4gLTMwZGJcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEdhdGUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHYXRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwic21vb3RoaW5nXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdhdGVcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhdGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLl9mb2xsb3dlciA9IG5ldyBGb2xsb3dlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IG9wdGlvbnMuc21vb3RoaW5nLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZ3QgPSBuZXcgR3JlYXRlclRoYW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IGRiVG9HYWluKG9wdGlvbnMudGhyZXNob2xkKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZ2F0ZSA9IHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9nYXRlKTtcbiAgICAgICAgLy8gdGhlIGNvbnRyb2wgc2lnbmFsXG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fZm9sbG93ZXIsIHRoaXMuX2d0LCB0aGlzLl9nYXRlLmdhaW4pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjEsXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IC00MFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRocmVzaG9sZCBvZiB0aGUgZ2F0ZSBpbiBkZWNpYmVsc1xuICAgICAqL1xuICAgIGdldCB0aHJlc2hvbGQoKSB7XG4gICAgICAgIHJldHVybiBnYWluVG9EYih0aGlzLl9ndC52YWx1ZSk7XG4gICAgfVxuICAgIHNldCB0aHJlc2hvbGQodGhyZXNoKSB7XG4gICAgICAgIHRoaXMuX2d0LnZhbHVlID0gZGJUb0dhaW4odGhyZXNoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGF0dGFjay9kZWNheSBzcGVlZCBvZiB0aGUgZ2F0ZS4gU2VlIFtbRm9sbG93ZXIuc21vb3RoaW5nXV1cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZm9sbG93ZXIuc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHNtb290aGluZ1RpbWUpIHtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIuc21vb3RoaW5nID0gc21vb3RoaW5nVGltZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ndC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhdGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYXRlLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbjtcbi8qKlxuICogTGltaXRlciB3aWxsIGxpbWl0IHRoZSBsb3VkbmVzcyBvZiBhbiBpbmNvbWluZyBzaWduYWwuXG4gKiBVbmRlciB0aGUgaG9vZCBpdCdzIGNvbXBvc2VkIG9mIGEgW1tDb21wcmVzc29yXV0gd2l0aCBhIGZhc3QgYXR0YWNrXG4gKiBhbmQgcmVsZWFzZSBhbmQgbWF4IGNvbXByZXNzaW9uIHJhdGlvLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBsaW1pdGVyID0gbmV3IFRvbmUuTGltaXRlcigtMjApLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChsaW1pdGVyKTtcbiAqIG9zY2lsbGF0b3Iuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIExpbWl0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhMaW1pdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxpbWl0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKExpbWl0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIl0pO1xuICAgICAgICB0aGlzLl9jb21wcmVzc29yID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gbmV3IENvbXByZXNzb3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcmF0aW86IDIwLFxuICAgICAgICAgICAgYXR0YWNrOiAwLjAwMyxcbiAgICAgICAgICAgIHJlbGVhc2U6IDAuMDEsXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IG9wdGlvbnMudGhyZXNob2xkXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnRocmVzaG9sZCA9IHRoaXMuX2NvbXByZXNzb3IudGhyZXNob2xkO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInRocmVzaG9sZFwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHRocmVzaG9sZDogLTEyXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlYWQtb25seSBkZWNpYmVsIHZhbHVlIGZvciBtZXRlcmluZyBwdXJwb3NlcywgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGFtb3VudCBvZiBnYWluXG4gICAgICogcmVkdWN0aW9uIHRoYXQgdGhlIGNvbXByZXNzb3IgaXMgYXBwbHlpbmcgdG8gdGhlIHNpZ25hbC5cbiAgICAgKi9cbiAgICBnZXQgcmVkdWN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tcHJlc3Nvci5yZWR1Y3Rpb247XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29tcHJlc3Nvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TGltaXRlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBDb21wcmVzc29yIH0gZnJvbSBcIi4vQ29tcHJlc3NvclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNaWRTaWRlU3BsaXQgfSBmcm9tIFwiLi4vY2hhbm5lbC9NaWRTaWRlU3BsaXRcIjtcbmltcG9ydCB7IE1pZFNpZGVNZXJnZSB9IGZyb20gXCIuLi9jaGFubmVsL01pZFNpZGVNZXJnZVwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBNaWRTaWRlQ29tcHJlc3NvciBhcHBsaWVzIHR3byBkaWZmZXJlbnQgY29tcHJlc3NvcnMgdG8gdGhlIFtbbWlkXV1cbiAqIGFuZCBbW3NpZGVdXSBzaWduYWwgY29tcG9uZW50cyBvZiB0aGUgaW5wdXQuIFNlZSBbW01pZFNpZGVTcGxpdF1dIGFuZCBbW01pZFNpZGVNZXJnZV1dLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWlkU2lkZUNvbXByZXNzb3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZUNvbXByZXNzb3JcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdCA9IHRoaXMuaW5wdXQgPSBuZXcgTWlkU2lkZVNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBNaWRTaWRlTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm1pZCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLnNpZGUgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMuc2lkZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQubWlkLmNoYWluKHRoaXMubWlkLCB0aGlzLl9taWRTaWRlTWVyZ2UubWlkKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0LnNpZGUuY2hhaW4odGhpcy5zaWRlLCB0aGlzLl9taWRTaWRlTWVyZ2Uuc2lkZSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm1pZFwiLCBcInNpZGVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWlkOiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDMsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4wMyxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDIsXG4gICAgICAgICAgICAgICAga25lZTogMTZcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzaWRlOiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDYsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMzAsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yNSxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDMsXG4gICAgICAgICAgICAgICAga25lZTogMTBcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlQ29tcHJlc3Nvci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBDb21wcmVzc29yIH0gZnJvbSBcIi4vQ29tcHJlc3NvclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aWJhbmRTcGxpdCB9IGZyb20gXCIuLi9jaGFubmVsL011bHRpYmFuZFNwbGl0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIEEgY29tcHJlc3NvciB3aXRoIHNlcGFyYXRlIGNvbnRyb2xzIG92ZXIgbG93L21pZC9oaWdoIGR5bmFtaWNzLiBTZWUgW1tDb21wcmVzc29yXV0gYW5kIFtbTXVsdGliYW5kU3BsaXRdXVxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtdWx0aWJhbmQgPSBuZXcgVG9uZS5NdWx0aWJhbmRDb21wcmVzc29yKHtcbiAqIFx0bG93RnJlcXVlbmN5OiAyMDAsXG4gKiBcdGhpZ2hGcmVxdWVuY3k6IDEzMDAsXG4gKiBcdGxvdzoge1xuICogXHRcdHRocmVzaG9sZDogLTEyXG4gKiBcdH1cbiAqIH0pO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTXVsdGliYW5kQ29tcHJlc3NvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpYmFuZENvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk11bHRpYmFuZENvbXByZXNzb3JcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpYmFuZENvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIgPSB0aGlzLmlucHV0ID0gbmV3IE11bHRpYmFuZFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogb3B0aW9ucy5sb3dGcmVxdWVuY3ksXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiBvcHRpb25zLmhpZ2hGcmVxdWVuY3lcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gdGhpcy5fc3BsaXR0ZXIubG93RnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kgPSB0aGlzLl9zcGxpdHRlci5oaWdoRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmxvdyA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5sb3csIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5taWQgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMubWlkLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMuaGlnaCA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5oaWdoLCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGNvbXByZXNzb3JcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIubG93LmNoYWluKHRoaXMubG93LCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLm1pZC5jaGFpbih0aGlzLm1pZCwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5oaWdoLmNoYWluKHRoaXMuaGlnaCwgdGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJoaWdoXCIsIFwibWlkXCIsIFwibG93XCIsIFwiaGlnaEZyZXF1ZW5jeVwiLCBcImxvd0ZyZXF1ZW5jeVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IDI1MCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IDIwMDAsXG4gICAgICAgICAgICBsb3c6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogNixcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0zMCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjI1LFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMyxcbiAgICAgICAgICAgICAgICBrbmVlOiAxMFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1pZDoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiAzLFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMDMsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAyLFxuICAgICAgICAgICAgICAgIGtuZWU6IDE2XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGlnaDoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiAzLFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMDMsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAyLFxuICAgICAgICAgICAgICAgIGtuZWU6IDE2XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2guZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU11bHRpYmFuZENvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSwgd3JpdGFibGUgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGliYW5kU3BsaXQgfSBmcm9tIFwiLi4vY2hhbm5lbC9NdWx0aWJhbmRTcGxpdFwiO1xuLyoqXG4gKiBFUTMgcHJvdmlkZXMgMyBlcXVhbGl6ZXIgYmluczogTG93L01pZC9IaWdoLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRVEzIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEVRMy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd1wiLCBcIm1pZFwiLCBcImhpZ2hcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJFUTNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEVRMy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd1wiLCBcIm1pZFwiLCBcImhpZ2hcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbXVsdGliYW5kU3BsaXQgPSBuZXcgTXVsdGliYW5kU3BsaXQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5LFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiBvcHRpb25zLmxvd0ZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xvd0dhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmxvdyxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taWRHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5taWQsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5faGlnaEdhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmhpZ2gsXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5sb3cgPSB0aGlzLl9sb3dHYWluLmdhaW47XG4gICAgICAgIHRoaXMubWlkID0gdGhpcy5fbWlkR2Fpbi5nYWluO1xuICAgICAgICB0aGlzLmhpZ2ggPSB0aGlzLl9oaWdoR2Fpbi5nYWluO1xuICAgICAgICB0aGlzLlEgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdC5RO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IHRoaXMuX211bHRpYmFuZFNwbGl0Lmxvd0ZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gdGhpcy5fbXVsdGliYW5kU3BsaXQuaGlnaEZyZXF1ZW5jeTtcbiAgICAgICAgLy8gdGhlIGZyZXF1ZW5jeSBiYW5kc1xuICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5sb3cuY2hhaW4odGhpcy5fbG93R2FpbiwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5taWQuY2hhaW4odGhpcy5fbWlkR2FpbiwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5oaWdoLmNoYWluKHRoaXMuX2hpZ2hHYWluLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImxvd1wiLCBcIm1pZFwiLCBcImhpZ2hcIiwgXCJsb3dGcmVxdWVuY3lcIiwgXCJoaWdoRnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9tdWx0aWJhbmRTcGxpdF07XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBoaWdoOiAwLFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogMjUwMCxcbiAgICAgICAgICAgIGxvdzogMCxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogNDAwLFxuICAgICAgICAgICAgbWlkOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCIsIFwibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX211bHRpYmFuZFNwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dHYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2hpZ2hHYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5sb3cuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuUS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVRMy5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBDb252b2x2ZXIgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgTmF0aXZlIFdlYiBBdWRpb1xuICogW0NvbnZvbHZlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWNvbnZvbHZlcm5vZGUtaW50ZXJmYWNlKS5cbiAqIENvbnZvbHV0aW9uIGlzIHVzZWZ1bCBmb3IgcmV2ZXJiIGFuZCBmaWx0ZXIgZW11bGF0aW9uLiBSZWFkIG1vcmUgYWJvdXQgY29udm9sdXRpb24gcmV2ZXJiIG9uXG4gKiBbV2lraXBlZGlhXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db252b2x1dGlvbl9yZXZlcmIpLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBpbml0aWFsaXppbmcgdGhlIGNvbnZvbHZlciB3aXRoIGFuIGltcHVsc2UgcmVzcG9uc2VcbiAqIGNvbnN0IGNvbnZvbHZlciA9IG5ldyBUb25lLkNvbnZvbHZlcihcIi4vcGF0aC90by9pci53YXZcIikudG9EZXN0aW5hdGlvbigpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ29udm9sdmVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbnZvbHZlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbnZvbHZlclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hdGl2ZSBDb252b2x2ZXJOb2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDb252b2x2ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKG9wdGlvbnMudXJsLCBidWZmZXIgPT4ge1xuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSBidWZmZXI7XG4gICAgICAgICAgICBvcHRpb25zLm9ubG9hZCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBzZXQgaWYgaXQncyBhbHJlYWR5IGxvYWRlZCwgc2V0IGl0IGltbWVkaWF0ZWx5XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIubG9hZGVkKSB7XG4gICAgICAgICAgICB0aGlzLmJ1ZmZlciA9IHRoaXMuX2J1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBpbml0aWFsbHkgc2V0IG5vcm1hbGl6YXRpb25cbiAgICAgICAgdGhpcy5ub3JtYWxpemUgPSBvcHRpb25zLm5vcm1hbGl6ZTtcbiAgICAgICAgLy8gY29ubmVjdCBpdCB1cFxuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2NvbnZvbHZlciwgdGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbm9ybWFsaXplOiB0cnVlLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9hZCBhbiBpbXB1bHNlIHJlc3BvbnNlIHVybCBhcyBhbiBhdWRpbyBidWZmZXIuXG4gICAgICogRGVjb2RlcyB0aGUgYXVkaW8gYXN5bmNocm9ub3VzbHkgYW5kIGludm9rZXNcbiAgICAgKiB0aGUgY2FsbGJhY2sgb25jZSB0aGUgYXVkaW8gYnVmZmVyIGxvYWRzLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuIGZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGUgYnJvd3Nlci5cbiAgICAgKi9cbiAgICBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSB5aWVsZCB0aGlzLl9idWZmZXIubG9hZCh1cmwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGNvbnZvbHZlcidzIGJ1ZmZlclxuICAgICAqL1xuICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlcikge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGl0J3MgYWxyZWFkeSBnb3QgYSBidWZmZXIsIGNyZWF0ZSBhIG5ldyBvbmVcbiAgICAgICAgaWYgKHRoaXMuX2NvbnZvbHZlci5idWZmZXIpIHtcbiAgICAgICAgICAgIC8vIGRpc2Nvbm5lY3QgdGhlIG9sZCBvbmVcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhbmQgY29ubmVjdCBhIG5ldyBvbmVcbiAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlciA9IHRoaXMuY29udGV4dC5jcmVhdGVDb252b2x2ZXIoKTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fY29udm9sdmVyLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnVmZiA9IHRoaXMuX2J1ZmZlci5nZXQoKTtcbiAgICAgICAgdGhpcy5fY29udm9sdmVyLmJ1ZmZlciA9IGJ1ZmYgPyBidWZmIDogbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG5vcm1hbGl6ZSBwcm9wZXJ0eSBvZiB0aGUgQ29udm9sdmVyTm9kZSBpbnRlcmZhY2UgaXMgYSBib29sZWFuIHRoYXRcbiAgICAgKiBjb250cm9scyB3aGV0aGVyIHRoZSBpbXB1bHNlIHJlc3BvbnNlIGZyb20gdGhlIGJ1ZmZlciB3aWxsIGJlIHNjYWxlZCBieVxuICAgICAqIGFuIGVxdWFsLXBvd2VyIG5vcm1hbGl6YXRpb24gd2hlbiB0aGUgYnVmZmVyIGF0dHJpYnV0ZSBpcyBzZXQsIG9yIG5vdC5cbiAgICAgKi9cbiAgICBnZXQgbm9ybWFsaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udm9sdmVyLm5vcm1hbGl6ZTtcbiAgICB9XG4gICAgc2V0IG5vcm1hbGl6ZShub3JtKSB7XG4gICAgICAgIHRoaXMuX2NvbnZvbHZlci5ub3JtYWxpemUgPSBub3JtO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnZvbHZlci5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9BbmFseXNlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvTWV0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0ZGVFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvRENNZXRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvV2F2ZWZvcm1cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0ZvbGxvd2VyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL0NoYW5uZWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvQ3Jvc3NGYWRlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01lcmdlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01pZFNpZGVNZXJnZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NaWRTaWRlU3BsaXRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTW9ub1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NdWx0aWJhbmRTcGxpdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9QYW5uZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUGFubmVyM0RcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUGFuVm9sXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1JlY29yZGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1NvbG9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvU3BsaXRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvVm9sdW1lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9keW5hbWljcy9Db21wcmVzc29yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9keW5hbWljcy9HYXRlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9keW5hbWljcy9MaW1pdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9keW5hbWljcy9NaWRTaWRlQ29tcHJlc3NvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTXVsdGliYW5kQ29tcHJlc3NvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52ZWxvcGUvQW1wbGl0dWRlRW52ZWxvcGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VudmVsb3BlL0VudmVsb3BlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZlbG9wZS9GcmVxdWVuY3lFbnZlbG9wZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0VRM1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0ZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL09uZVBvbGVGaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9GZWVkYmFja0NvbWJGaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0NvbnZvbHZlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmlsdGVyL0JpcXVhZEZpbHRlclwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vY29yZS9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc291cmNlL2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9zaWduYWwvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2luc3RydW1lbnQvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2V2ZW50L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lZmZlY3QvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbXBvbmVudC9pbmRleFwiO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2xhc3Nlcy5qcy5tYXAiLCJleHBvcnQgeyBnZXRDb250ZXh0LCBzZXRDb250ZXh0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NsYXNzZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3ZlcnNpb25cIjtcbmltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi9jb3JlL0dsb2JhbFwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuZXhwb3J0IHsgc3RhcnQgfSBmcm9tIFwiLi9jb3JlL0dsb2JhbFwiO1xuZXhwb3J0IHsgc3VwcG9ydGVkIH0gZnJvbSBcIi4vY29yZS9jb250ZXh0L0F1ZGlvQ29udGV4dFwiO1xuLyoqXG4gKiBUaGUgY3VycmVudCBhdWRpbyBjb250ZXh0IHRpbWUgb2YgdGhlIGdsb2JhbCBbW0NvbnRleHRdXS5cbiAqIFNlZSBbW0NvbnRleHQubm93XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3coKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5ub3coKTtcbn1cbi8qKlxuICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIG9mIHRoZSBnbG9iYWwgW1tDb250ZXh0XV0gd2l0aG91dCB0aGUgW1tDb250ZXh0Lmxvb2tBaGVhZF1dXG4gKiBTZWUgW1tDb250ZXh0LmltbWVkaWF0ZV1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW1tZWRpYXRlKCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkuaW1tZWRpYXRlKCk7XG59XG4vKipcbiAqIFRoZSBUcmFuc3BvcnQgb2JqZWN0IGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW1RyYW5zcG9ydF1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgVHJhbnNwb3J0ID0gZ2V0Q29udGV4dCgpLnRyYW5zcG9ydDtcbi8qKlxuICogVGhlIFRyYW5zcG9ydCBvYmplY3QgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbVHJhbnNwb3J0XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmFuc3BvcnQoKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS50cmFuc3BvcnQ7XG59XG4vKipcbiAqIFRoZSBEZXN0aW5hdGlvbiAob3V0cHV0KSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tEZXN0aW5hdGlvbl1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgRGVzdGluYXRpb24gPSBnZXRDb250ZXh0KCkuZGVzdGluYXRpb247XG4vKipcbiAqIEBkZXByZWNhdGVkIFVzZSBbW0Rlc3RpbmF0aW9uXV1cbiAqL1xuZXhwb3J0IGNvbnN0IE1hc3RlciA9IGdldENvbnRleHQoKS5kZXN0aW5hdGlvbjtcbi8qKlxuICogVGhlIERlc3RpbmF0aW9uIChvdXRwdXQpIGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW0Rlc3RpbmF0aW9uXV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZXN0aW5hdGlvbigpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmRlc3RpbmF0aW9uO1xufVxuLyoqXG4gKiBUaGUgW1tMaXN0ZW5lcl1dIGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBMaXN0ZW5lciA9IGdldENvbnRleHQoKS5saXN0ZW5lcjtcbi8qKlxuICogVGhlIFtbTGlzdGVuZXJdXSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGlzdGVuZXIoKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5saXN0ZW5lcjtcbn1cbi8qKlxuICogRHJhdyBpcyB1c2VkIHRvIHN5bmNocm9uaXplIHRoZSBkcmF3IGZyYW1lIHdpdGggdGhlIFRyYW5zcG9ydCdzIGNhbGxiYWNrcy5cbiAqIFNlZSBbW0RyYXddXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IERyYXcgPSBnZXRDb250ZXh0KCkuZHJhdztcbi8qKlxuICogR2V0IHRoZSBzaW5nbGV0b24gYXR0YWNoZWQgdG8gdGhlIGdsb2JhbCBjb250ZXh0LlxuICogRHJhdyBpcyB1c2VkIHRvIHN5bmNocm9uaXplIHRoZSBkcmF3IGZyYW1lIHdpdGggdGhlIFRyYW5zcG9ydCdzIGNhbGxiYWNrcy5cbiAqIFNlZSBbW0RyYXddXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERyYXcoKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5kcmF3O1xufVxuLyoqXG4gKiBBIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIGNvbnRleHRcbiAqIFNlZSBbW0NvbnRleHRdXVxuICovXG5leHBvcnQgY29uc3QgY29udGV4dCA9IGdldENvbnRleHQoKTtcbi8qKlxuICogUHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIGFsbCBvZiB0aGUgbG9hZGluZyBwcm9taXNlcyBhcmUgcmVzb2x2ZWQuXG4gKiBBbGlhcyBmb3Igc3RhdGljIFtbVG9uZUF1ZGlvQnVmZmVyLmxvYWRlZF1dIG1ldGhvZC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb2FkZWQoKSB7XG4gICAgcmV0dXJuIFRvbmVBdWRpb0J1ZmZlci5sb2FkZWQoKTtcbn1cbi8vIHRoaXMgZmlsbHMgaW4gbmFtZSBjaGFuZ2VzIGZyb20gMTMueCB0byAxNC54XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXJzIH0gZnJvbSBcIi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9zb3VyY2UvYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmV4cG9ydCBjb25zdCBCdWZmZXIgPSBUb25lQXVkaW9CdWZmZXI7XG5leHBvcnQgY29uc3QgQnVmZmVycyA9IFRvbmVBdWRpb0J1ZmZlcnM7XG5leHBvcnQgY29uc3QgQnVmZmVyU291cmNlID0gVG9uZUJ1ZmZlclNvdXJjZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCAqIGFzIFRvbmUgZnJvbSBcInRvbmVcIjtcbmltcG9ydCBTdGFydEF1ZGlvQ29udGV4dCBmcm9tIFwiLi9zdGFydEF1ZGlvQ29udGV4dFwiO1xuXG5jb25zdCBpc0lwaG9uZSA9XG4gIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQaG9uZS9pKSB8fCBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUG9kL2kpO1xuY29uc3QgaXNJcGFkID0gbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBhZC9pKTtcbmNvbnN0IGlzQW5kcm9pZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSk7XG5jb25zdCBpc01vYmlsZSA9IGlzSXBob25lIHx8IGlzSXBhZCB8fCBpc0FuZHJvaWQ7XG5jb25zdCBpc0Rlc2t0b3AgPSAhaXNNb2JpbGU7XG5cbmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChpc01vYmlsZSA/IFwibW9iaWxlXCIgOiBcImRlc2t0b3BcIik7XG5cbmV4cG9ydCBjb25zdCBicm93c2VyID0geyBpc0lwaG9uZSwgaXNJcGFkLCBpc01vYmlsZSwgaXNEZXNrdG9wIH07XG5leHBvcnQgY29uc3QgY2hvaWNlID0gKGEpID0+IGFbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYS5sZW5ndGgpXTtcbmV4cG9ydCBjb25zdCBtb2QgPSAobiwgbSkgPT4gbiAtIG0gKiBNYXRoLmZsb29yKG4gLyBtKTtcbmV4cG9ydCBjb25zdCByYW5kb20gPSAoKSA9PiBNYXRoLnJhbmRvbSgpO1xuZXhwb3J0IGNvbnN0IHJhbmQgPSAobikgPT4gTWF0aC5yYW5kb20oKSAqIG47XG5leHBvcnQgY29uc3QgcmFuZGludCA9IChuKSA9PiByYW5kKG4pIHwgMDtcbmV4cG9ydCBjb25zdCByYW5kcmFuZ2UgPSAoYSwgYikgPT4gYSArIHJhbmQoYiAtIGEpO1xuZXhwb3J0IGNvbnN0IHJhbmRzaWduID0gKCkgPT4gKHJhbmRvbSgpID49IDAuNSA/IC0xIDogMSk7XG5leHBvcnQgY29uc3QgcmFuZG51bGxzaWduID0gKCkgPT4ge1xuICB2YXIgciA9IHJhbmRvbSgpO1xuICByZXR1cm4gciA8IDAuMzMzID8gLTEgOiByIDwgMC42NjYgPyAwIDogMTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1ZXN0QXVkaW9Db250ZXh0KGZuKSB7XG4gIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gIGNvbnN0IGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gIGJ1dHRvbi5pbm5lckhUTUwgPSBcIlRhcCB0byBzdGFydCAtIHBsZWFzZSB1bm11dGUgeW91ciBwaG9uZVwiO1xuICBPYmplY3QuYXNzaWduKGNvbnRhaW5lci5zdHlsZSwge1xuICAgIGRpc3BsYXk6IFwiYmxvY2tcIixcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIHdpZHRoOiBcIjEwMCVcIixcbiAgICBoZWlnaHQ6IFwiMTAwJVwiLFxuICAgIHpJbmRleDogXCIxMDAwMFwiLFxuICAgIHRvcDogXCIwcHhcIixcbiAgICBsZWZ0OiBcIjBweFwiLFxuICAgIGJhY2tncm91bmRDb2xvcjogXCJyZ2JhKDAsIDAsIDAsIDAuOClcIixcbiAgfSk7XG4gIE9iamVjdC5hc3NpZ24oYnV0dG9uLnN0eWxlLCB7XG4gICAgZGlzcGxheTogXCJibG9ja1wiLFxuICAgIHBvc2l0aW9uOiBcImFic29sdXRlXCIsXG4gICAgbGVmdDogXCI1MCVcIixcbiAgICB0b3A6IFwiNTAlXCIsXG4gICAgcGFkZGluZzogXCIyMHB4XCIsXG4gICAgYmFja2dyb3VuZENvbG9yOiBcIiM3RjMzRURcIixcbiAgICBjb2xvcjogXCJ3aGl0ZVwiLFxuICAgIGZvbnRGYW1pbHk6IFwibW9ub3NwYWNlXCIsXG4gICAgYm9yZGVyUmFkaXVzOiBcIjNweFwiLFxuICAgIHRyYW5zZm9ybTogXCJ0cmFuc2xhdGUzRCgtNTAlLC01MCUsMClcIixcbiAgICB0ZXh0QWxpZ246IFwiY2VudGVyXCIsXG4gICAgbGluZUhlaWdodDogXCIxLjVcIixcbiAgICB3aWR0aDogXCIxNTBweFwiLFxuICB9KTtcbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGJ1dHRvbik7XG4gIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcbiAgU3RhcnRBdWRpb0NvbnRleHQuc2V0Q29udGV4dChUb25lLmNvbnRleHQpO1xuICBTdGFydEF1ZGlvQ29udGV4dC5vbihidXR0b24pO1xuICBTdGFydEF1ZGlvQ29udGV4dC5vblN0YXJ0ZWQoKF8pID0+IHtcbiAgICBjb250YWluZXIucmVtb3ZlKCk7XG4gICAgZm4oKTtcbiAgfSk7XG59XG4iLCIvKipcbiAqIFJlbGFiaSB3YXZlZm9ybSBkaXNwbGF5XG4gKiBAbW9kdWxlIHNyYy9yZWxhYmkvY2FudmFzLmpzO1xuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbGFiaUNhbnZhcyB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIHJlbGFiaSB3YXZlIHJlbmRlcmVyXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7IHJlbGFiaSwgcGFyZW50IH0pIHtcbiAgICB0aGlzLnJlbGFiaSA9IHJlbGFiaTtcbiAgICB0aGlzLmhlaWdodCA9IDQwMDtcbiAgICB0aGlzLmxhc3RGcmFtZSA9IDA7XG4gICAgdGhpcy5sYXN0QXBwZW5kVGltZSA9IDA7XG4gICAgdGhpcy5sYXN0QXBwZW5kRnJhbWUgPSAwO1xuXG4gICAgLy8gU3BlZWQgb2YgdGhlIHdhdmUgaW4gcGl4ZWxzIHBlciBzZWNvbmRcbiAgICB0aGlzLnNwZWVkID0gMSAvIDU7XG5cbiAgICAvLyBBdHRhY2ggdG8gdGhlIERPTVxuICAgIHRoaXMucGFyZW50ID0gcGFyZW50ID0gZG9jdW1lbnQuYm9keTtcbiAgICB0aGlzLmNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJjYW52YXNcIik7XG4gICAgdGhpcy5jdHggPSB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgdGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5jYW52YXMpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBhcnJheVxuICAgIHRoaXMudmFsdWVzID0gbmV3IEFycmF5KHdpbmRvdy5pbm5lcldpZHRoKS5maWxsKDApO1xuICAgIHRoaXMuYXBwZW5kKFtdKTtcblxuICAgIC8vIENsZWFyIHRoZSBjYW52YXNcbiAgICB0aGlzLnJlc2l6ZSgpO1xuXG4gICAgLy8gU3RhcnQgZHJhd2luZ1xuICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKDApO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIG5leHQgZnJhbWVcbiAgICovXG4gIHJlcXVlc3RBbmltYXRpb25GcmFtZShmcmFtZSkge1xuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoZnJhbWUpID0+IHtcbiAgICAgIHRoaXMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZyYW1lKTtcbiAgICB9KTtcbiAgICB0aGlzLnBhaW50KGZyYW1lKTtcbiAgICB0aGlzLmxhc3RGcmFtZSA9IGZyYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSB3aW5kb3cgcmVzaXplXG4gICAqL1xuICByZXNpemUoKSB7XG4gICAgdGhpcy5jYW52YXMud2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSB0aGlzLmhlaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciB0aGUgY2FudmFzXG4gICAqL1xuICBjbGVhcigpIHtcbiAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodCk7XG4gIH1cblxuICAvKipcbiAgICogQXBwZW5kIHZhbHVlc1xuICAgKi9cbiAgYXBwZW5kKHRpbWUsIHZhbHVlcykge1xuICAgIHRoaXMubGFzdEFwcGVuZFRpbWUgPSB0aW1lO1xuICAgIHRoaXMubGFzdEFwcGVuZEZyYW1lID0gdGhpcy5sYXN0RnJhbWU7XG4gICAgdGhpcy52YWx1ZXMgPSB0aGlzLnZhbHVlcy5jb25jYXQodmFsdWVzKS5zbGljZSgtdGhpcy5jYW52YXMud2lkdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhaW50IHRoZSBjYW52YXNcbiAgICovXG4gIHBhaW50KGZyYW1lKSB7XG4gICAgdGhpcy5jbGVhcigpO1xuICAgIHRoaXMuZHJhd1JlbGFiaVdhdmUoZnJhbWUpO1xuICAgIHRoaXMuZHJhd0JvdW5kcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIGJvdW5kc1xuICAgKi9cbiAgZHJhd0JvdW5kcygpIHtcbiAgICBjb25zdCB7IGNhbnZhcywgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY2FudmFzO1xuXG4gICAgLy8gRHJhdyBkYXNoZWQgbGluZXMgZm9yIGFsbCBib3VuZHNcbiAgICBmb3IgKGNvbnN0IGJvdW5kIG9mIHRoaXMucmVsYWJpLmJvdW5kcykge1xuICAgICAgY29uc3QgeSA9IGdldFdhdmVIZWlnaHQoYm91bmQubGV2ZWwsIGhlaWdodCk7XG5cbiAgICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICAgIGN0eC5zZXRMaW5lRGFzaChbMTAsIDVdKTtcbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9IGJvdW5kLmNvbG9yIHx8IFwiIzg4OFwiO1xuICAgICAgY3R4Lm1vdmVUbygwLCB5KTtcbiAgICAgIGN0eC5saW5lVG8od2lkdGgsIHkpO1xuICAgICAgY3R4LnN0cm9rZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSByZWxhYmkgd2F2ZVxuICAgKi9cbiAgZHJhd1JlbGFiaVdhdmUoZnJhbWUpIHtcbiAgICBjb25zdCB7IGNhbnZhcywgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gY2FudmFzO1xuXG4gICAgY29uc3QgcG9pbnRDb3VudCA9IHRoaXMudmFsdWVzLmxlbmd0aDtcbiAgICBsZXQgaW5kZXggPSAwO1xuXG4gICAgLy8gU3RhcnQgdGhlIHBhdGhcbiAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgY3R4LnN0cm9rZVN0eWxlID0gXCJ3aGl0ZVwiO1xuICAgIGN0eC5zZXRMaW5lRGFzaChbXSk7XG5cbiAgICAvLyBUaGlzIGlzIHRoZSBvZmZzZXQgaW4gc2Vjb25kcyBmcm9tIHRoZSBsYXN0IGZyYW1lIHdlIGNvbXB1dGVkXG4gICAgY29uc3QgZnJhbWVPZmZzZXQgPSAoZnJhbWUgLSB0aGlzLmxhc3RBcHBlbmRGcmFtZSkgLyAxMDAwO1xuXG4gICAgLy8gTWFrZSBhIHBhdGggY29ubmVjdGluZyBhbGwgdmFsdWVzXG4gICAgZm9yIChjb25zdCBwb2ludCBvZiB0aGlzLnZhbHVlcykge1xuICAgICAgaWYgKCFwb2ludCkge1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgW3RpbWUsIHZhbHVlXSA9IHBvaW50O1xuXG4gICAgICAvLyBUaGlzIGlzIHRoZSBvZmZzZXQgb2YgdGhpcyB0aW1lIGZyb20gY3VycmVudCB0aW1lXG4gICAgICAvLyBJZiB0aGlzIGlzIGluIHRoZSBmdXR1cmUsIGl0IHdpbGwgYmUgcG9zaXRpdmUuXG4gICAgICAvLyBTdWJ0cmFjdGluZyB0aGUgZnJhbWUgb2Zmc2V0IHB1bGxzIGl0IG5lZ2F0aXZlLlxuICAgICAgY29uc3QgdGltZU9mZnNldCA9IHRoaXMubGFzdEFwcGVuZFRpbWUgKyBmcmFtZU9mZnNldCAtIHRpbWU7XG5cbiAgICAgIGNvbnN0IHggPSB3aWR0aCAtIHRpbWVPZmZzZXQgKiB0aGlzLnNwZWVkICogd2lkdGggLSAxMDtcblxuICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB5ID0gZ2V0V2F2ZUhlaWdodCh2YWx1ZSwgaGVpZ2h0KTtcbiAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICBjdHgubW92ZVRvKHgsIHkpO1xuICAgICAgfVxuICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcbiAgICAgIGluZGV4ICs9IDE7XG4gICAgfVxuXG4gICAgLy8gUGFpbnQgdGhlIGxpbmVcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGhlaWdodCBvZiB0aGUgd2F2ZSBhdCBhIGdpdmVuIHZhbHVlXG4gKi9cbmNvbnN0IGdldFdhdmVIZWlnaHQgPSAodmFsdWUsIGhlaWdodCkgPT4gKCh2YWx1ZSArIDEpIC8gMikgKiBoZWlnaHQ7XG4iLCIvKipcbiAqIFJlbGFiaSBldmVudCBnZW5lcmF0b3JcbiAqL1xuXG5pbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgUmVsYWJpQ2FudmFzIGZyb20gXCIuL2NhbnZhc1wiO1xuXG5jb25zdCBUV09fUEkgPSAyICogTWF0aC5QSTtcblxuLyoqXG4gKiBXYXZlIGZ1bmN0aW9uc1xuICovXG5jb25zdCBXQVZFX0ZVTkNUSU9OUyA9IHtcbiAgc2luZTogTWF0aC5jb3MsXG4gIHRyaWFuZ2xlOiAodGltZSkgPT5cbiAgICAoNCAvIFRXT19QSSkgKlxuICAgICAgTWF0aC5hYnMoXG4gICAgICAgICgoKCh0aW1lIC0gVFdPX1BJIC8gNCkgJSBUV09fUEkpICsgVFdPX1BJKSAlIFRXT19QSSkgLSBUV09fUEkgLyAyXG4gICAgICApIC1cbiAgICAxLFxuICBzcXVhcmU6ICh0aW1lKSA9PiAodGltZSAlIFRXT19QSSA8IE1hdGguUEkgPyAxIDogLTEpLFxuICBzYXc6ICh0aW1lKSA9PiAoKHRpbWUgJSBUV09fUEkpIC0gTWF0aC5QSSkgLyBNYXRoLlBJLFxufTtcblxuLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbGFiaSB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGdlbmVyYXRvclxuICAgKi9cbiAgY29uc3RydWN0b3IoeyB3YXZlcywgYm91bmRzLCBwYXJlbnQgfSkge1xuICAgIHRoaXMudXBkYXRlVGltZSA9IDE7XG4gICAgdGhpcy5zdGVwcyA9IDUwO1xuICAgIHRoaXMud2F2ZXMgPSB3YXZlcyB8fCBbXG4gICAgICB7IHR5cGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IHJhbmRyYW5nZSgwLjUsIDEuNSkgfSxcbiAgICAgIHsgdHlwZTogXCJzaW5lXCIsIGZyZXF1ZW5jeTogcmFuZHJhbmdlKDAuNzUsIDIuMjUpIH0sXG4gICAgICB7IHR5cGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IHJhbmRyYW5nZSgxLCAzKSB9LFxuICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMiwgNCkgfSxcbiAgICBdO1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICAgIHRoaXMucHJldmlvdXNWYWx1ZSA9IDA7XG4gICAgdGhpcy5jYW52YXMgPSBuZXcgUmVsYWJpQ2FudmFzKHsgcmVsYWJpOiB0aGlzLCBwYXJlbnQgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnQgdGhlIGdlbmVyYXRvclxuICAgKi9cbiAgc3RhcnQoKSB7XG4gICAgY29uc29sZS5sb2coXCJTdGFydCBSZWxhYmlcIik7XG4gICAgdGhpcy5zdG9wKCk7XG4gICAgdGhpcy5jbG9jayA9IG5ldyBUb25lLkNsb2NrKCh0aW1lKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLmdlbmVyYXRlKHRpbWUpO1xuICAgICAgdGhpcy5jYW52YXMuYXBwZW5kKHRpbWUsIHZhbHVlcyk7XG4gICAgICB0aGlzLnBsYXkodmFsdWVzKTtcbiAgICB9LCB0aGlzLnVwZGF0ZVRpbWUpO1xuICAgIHRoaXMuY2xvY2suc3RhcnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wIHRoZSBnZW5lcmF0b3IgYW5kIHJlc2V0IGl0XG4gICAqL1xuICBzdG9wKCkge1xuICAgIGlmICh0aGlzLmNsb2NrKSB7XG4gICAgICB0aGlzLmNsb2NrLnN0b3AoKTtcbiAgICAgIHRoaXMuY2xvY2suZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBnZW5lcmF0ZSh0aW1lKSB7XG4gICAgY29uc3Qgd2F2ZUNvdW50ID0gdGhpcy53YXZlcy5sZW5ndGg7XG4gICAgbGV0IGluZGV4O1xuICAgIGxldCBzdGVwO1xuICAgIGxldCB2YWx1ZTtcbiAgICBsZXQgdmFsdWVzID0gW107XG5cbiAgICAvLyBHZW5lcmF0ZSBzZXZlcmFsIGV2ZW50cyBwZXIgc2Vjb25kXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gVGltZSBvZmZzZXQgZm9yIHRoaXMgZXZlbnRcbiAgICAgIGNvbnN0IHRpbWVPZmZzZXQgPSB0aW1lICsgKHN0ZXAgKiB0aGlzLnVwZGF0ZVRpbWUpIC8gdGhpcy5zdGVwcztcblxuICAgICAgLy8gSW5pdGlhbGl6ZSB2YWx1ZVxuICAgICAgdmFsdWUgPSAwO1xuXG4gICAgICAvLyBDb21wdXRlIHRoZSB3YXZlIGZ1bmN0aW9ucyBmb3IgdGhpcyBldmVudFxuICAgICAgZm9yIChpbmRleCA9IDA7IGluZGV4IDwgd2F2ZUNvdW50OyBpbmRleCArPSAxKSB7XG4gICAgICAgIGNvbnN0IHdhdmUgPSB0aGlzLndhdmVzW2luZGV4XTtcbiAgICAgICAgdmFsdWUgKz0gV0FWRV9GVU5DVElPTlNbd2F2ZS50eXBlXSh0aW1lT2Zmc2V0ICogd2F2ZS5mcmVxdWVuY3kpO1xuICAgICAgfVxuXG4gICAgICAvLyBTY2FsZSB0byBbLTEsIDFdXG4gICAgICB2YWx1ZSAvPSB3YXZlQ291bnQ7XG5cbiAgICAgIHZhbHVlcy5wdXNoKFt0aW1lT2Zmc2V0LCB2YWx1ZV0pO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXM7XG4gIH1cblxuICAvKipcbiAgICogU2NoZWR1bGUgcmVsYWJpIGV2ZW50c1xuICAgKi9cbiAgcGxheSh2YWx1ZXMpIHtcbiAgICBjb25zdCBib3VuZHNDb3VudCA9IHRoaXMuYm91bmRzLmxlbmd0aDtcbiAgICBsZXQgcHJldmlvdXNWYWx1ZSA9IHRoaXMucHJldmlvdXNWYWx1ZTtcbiAgICBsZXQgaW5kZXg7XG4gICAgbGV0IHN0ZXA7XG4gICAgbGV0IG5vdGVDb3VudCA9IDA7XG5cbiAgICBmb3IgKHN0ZXAgPSAwOyBzdGVwIDwgdGhpcy5zdGVwczsgc3RlcCArPSAxKSB7XG4gICAgICAvLyBHZXQgdGhlIG5leHQgdmFsdWVcbiAgICAgIGNvbnN0IFt0aW1lLCB2YWx1ZV0gPSB2YWx1ZXNbc3RlcF07XG5cbiAgICAgIC8vIENvbXB1dGUgd2hldGhlciB3ZSBjcm9zc2VkIGEgYm91bmRhcnksIGFuZCB3aGljaCBkaXJlY3Rpb25cbiAgICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGJvdW5kc0NvdW50OyBpbmRleCArPSAxKSB7XG4gICAgICAgIGNvbnN0IGJvdW5kID0gdGhpcy5ib3VuZHNbaW5kZXhdO1xuICAgICAgICBpZiAodmFsdWUgPCBib3VuZC5sZXZlbCAmJiBib3VuZC5sZXZlbCA8IHByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICAvLyBHb2luZyBkb3duXG4gICAgICAgICAgdGhpcy50cmlnZ2VyKHRpbWUsIGJvdW5kLnNvdW5kc1swXSk7XG4gICAgICAgICAgbm90ZUNvdW50ICs9IDE7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPiBib3VuZC5sZXZlbCAmJiBib3VuZC5sZXZlbCA+IHByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICAvLyBHb2luZyB1cFxuICAgICAgICAgIHRoaXMudHJpZ2dlcih0aW1lLCBib3VuZC5zb3VuZHNbMV0pO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFVwZGF0ZSB0aGUgcHJldmlvdXMgdmFsdWVcbiAgICAgIHByZXZpb3VzVmFsdWUgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBTdG9yZSB0aGUgbGF0ZXN0IHZhbHVlXG4gICAgdGhpcy5wcmV2aW91c1ZhbHVlID0gcHJldmlvdXNWYWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGV2ZW50XG4gICAqL1xuICB0cmlnZ2VyKHRpbWUsIHNvdW5kKSB7XG4gICAgLy8gY29uc29sZS5sb2coXCJ0cmlnZ2VyIGluZGV4XCIsIGluZGV4LCB0aW1lKTtcbiAgICBzb3VuZC5pbnN0cnVtZW50LnBsYXkodGltZSwgc291bmQpO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5cbmNvbnN0IGNvbXByZXNzb3IgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG5jb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigwLjMpO1xuY29tcHJlc3Nvci5jb25uZWN0KGdhaW4pO1xuZ2Fpbi50b0Rlc3RpbmF0aW9uKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNvbXByZXNzb3I7XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgeyBjaG9pY2UsIHJhbmRyYW5nZSB9IGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCBvdXRwdXQgZnJvbSBcIi4vb3V0cHV0XCI7XG5cbmNvbnN0IFBMQVlFUl9DT1VOVCA9IDQ7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNhbXBsZXIge1xuICBjb25zdHJ1Y3Rvcih7IHNhbXBsZXMsIHRvbmFsIH0pIHtcbiAgICB0aGlzLnRvbmFsID0gdG9uYWw7XG4gICAgdGhpcy5zYW1wbGVzID0gc2FtcGxlcy5tYXAoKHsgLi4uc2FtcGxlIH0pID0+IHtcbiAgICAgIHNhbXBsZS5wbGF5ZXJzID0gW107XG4gICAgICBzYW1wbGUuaW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUExBWUVSX0NPVU5UOyBpKyspIHtcbiAgICAgICAgbGV0IGZuID0gc2FtcGxlLmZuO1xuICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL2FzZGYudXMvKSkge1xuICAgICAgICAgIGZuID0gXCIvL2FzZGYudXMva2FsaW1iYS9cIiArIGZuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoe1xuICAgICAgICAgIHVybDogZm4sXG4gICAgICAgICAgcmV0cmlnZ2VyOiB0cnVlLFxuICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBsYXllci5jb25uZWN0KG91dHB1dCk7XG4gICAgICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW1wbGU7XG4gICAgfSk7XG4gIH1cblxuICBwbGF5KHRpbWUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VuZCA9IG9wdGlvbnMuaW5kZXhcbiAgICAgID8gdGhpcy5zYW1wbGVzW29wdGlvbnMuaW5kZXhdXG4gICAgICA6IGNob2ljZSh0aGlzLnNhbXBsZXMpO1xuXG4gICAgc291bmQuaW5kZXggPSAoc291bmQuaW5kZXggKyAxKSAlIFBMQVlFUl9DT1VOVDtcblxuICAgIGNvbnN0IHBsYXllciA9IHNvdW5kLnBsYXllcnNbc291bmQuaW5kZXhdO1xuXG4gICAgaWYgKHRoaXMudG9uYWwpIHtcbiAgICAgIHBsYXllci5wbGF5YmFja1JhdGUgPVxuICAgICAgICAob3B0aW9ucy5mcmVxdWVuY3kgKiBjaG9pY2UoWzAuNSwgMV0pICsgcmFuZHJhbmdlKDAsIDEwKSkgLyBzb3VuZC5yb290O1xuICAgIH1cblxuICAgIHBsYXllci5zdGFydCh0aW1lIHx8IDApO1xuICB9XG59XG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi9zYW1wbGVyXCI7XG5cbmV4cG9ydCBjb25zdCBLYWxpbWJhID0gbmV3IFNhbXBsZXIoe1xuICB0b25hbDogdHJ1ZSxcbiAgc2FtcGxlczogW1xuICAgIHsgcm9vdDogMjI2LCBmbjogXCJzYW1wbGVzLzM4MDczN19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDEtYS1yYXcubXAzXCIgfSxcbiAgICB7IHJvb3Q6IDI2NywgZm46IFwic2FtcGxlcy8zODA3MzZfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAyLWMtcmF3Lm1wM1wiIH0sXG4gICAgeyByb290OiAzNDAsIGZuOiBcInNhbXBsZXMvMzgwNzM1X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMy1lLXJhdy5tcDNcIiB9LFxuICAgIHsgcm9vdDogNDUyLCBmbjogXCJzYW1wbGVzLzM4MDczM19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDYtYS0wMi1yYXcubXAzXCIgfSxcbiAgXSxcbn0pO1xuXG5leHBvcnQgY29uc3QgRHJ1bXMgPSBuZXcgU2FtcGxlcih7XG4gIHRvbmFsOiBmYWxzZSxcbiAgc2FtcGxlczogW1xuICAgIHsgZm46IFwic2FtcGxlcy83MDdfYmQubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2NsYXAubXAzXCIgfSxcbiAgICAvLyB7IGZuOiBcInNhbXBsZXMvNzA3X2Nvdy5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfaGF0Lm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19yaW0ubXAzXCIgfSxcbiAgXSxcbn0pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yIFVJXG4gKiBAbW9kdWxlIHNyYy91aS9BcHAuanM7XG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0IH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgUmVsYWJpIGZyb20gXCIuLi9yZWxhYmlcIjtcbmltcG9ydCB7IEthbGltYmEsIERydW1zIH0gZnJvbSBcIi4uL2xpYi9pbnN0cnVtZW50c1wiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBcHAoKSB7XG4gIGNvbnN0IFtyZWxhYmksIHNldFJlbGFiaV0gPSB1c2VTdGF0ZSgpO1xuXG4gIC8qKlxuICAgKiBJbnN0YW50aWF0ZSB0aGUgUmVsYWJpIGdlbmVyYXRvclxuICAgKi9cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXJlbGFiaSkge1xuICAgICAgY29uc3QgcmVsYWJpR2VuZXJhdG9yID0gbmV3IFJlbGFiaSh7XG4gICAgICAgIHdhdmVzOiBbXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAwLjc1IH0sXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAxLjAgfSxcbiAgICAgICAgICB7IHR5cGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuNjE3IH0sXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAzLjE0MSB9LFxuICAgICAgICBdLFxuICAgICAgICBib3VuZHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogLTAuNzUsXG4gICAgICAgICAgICBjb2xvcjogXCIjZjAwXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDAgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDEgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogMC43NSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiNmMDBcIixcbiAgICAgICAgICAgIHNvdW5kczogW1xuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IERydW1zLCBpbmRleDogMiB9LFxuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IERydW1zLCBpbmRleDogMyB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxldmVsOiAtMC4yNSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiMwMGZcIixcbiAgICAgICAgICAgIHNvdW5kczogW1xuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogNDQwIH0sXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiAoNDQwICogMykgLyAyIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGV2ZWw6IDAuMjUsXG4gICAgICAgICAgICBjb2xvcjogXCIjMDBmXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDUgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDcgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgICAgcmVsYWJpR2VuZXJhdG9yLnN0YXJ0KCk7XG4gICAgICBzZXRSZWxhYmkocmVsYWJpR2VuZXJhdG9yKTtcbiAgICB9XG4gIH0sIFtyZWxhYmldKTtcblxuICAvKipcbiAgICogUmVuZGVyXG4gICAqL1xuXG4gIHJldHVybiA8ZGl2PlJlbGFiaSBnZW5lcmF0b3I8L2Rpdj47XG59XG4iLCJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IGNyZWF0ZVJvb3QgfSBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiO1xuaW1wb3J0IHsgcmVxdWVzdEF1ZGlvQ29udGV4dCwgcmFuZHJhbmdlIH0gZnJvbSBcIi4vbGliL3V0aWxcIjtcblxuaW1wb3J0IEFwcCBmcm9tIFwiLi91aS9BcHAuanN4XCI7XG5cbmRvY3VtZW50LmJvZHkuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCIjMTExXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLmNvbG9yID0gXCIjZmZmXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLm1hcmdpbiA9IDA7XG5kb2N1bWVudC5ib2R5LnN0eWxlLnBhZGRpbmcgPSAwO1xuXG5yZXF1ZXN0QXVkaW9Db250ZXh0KCgpID0+IHtcbiAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSAnPGRpdiBpZD1cImFwcFwiPjwvZGl2Pic7XG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwiYXBwXCIpKTtcbiAgcm9vdC5yZW5kZXIoPEFwcCAvPik7XG59KTtcbiJdLCJuYW1lcyI6WyJUb25lIiwiU3RhcnRBdWRpb0NvbnRleHQiLCJpc0lwaG9uZSIsIm5hdmlnYXRvciIsInVzZXJBZ2VudCIsIm1hdGNoIiwiaXNJcGFkIiwiaXNBbmRyb2lkIiwiaXNNb2JpbGUiLCJpc0Rlc2t0b3AiLCJkb2N1bWVudCIsImJvZHkiLCJjbGFzc0xpc3QiLCJhZGQiLCJicm93c2VyIiwiY2hvaWNlIiwiYSIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsImxlbmd0aCIsIm1vZCIsIm4iLCJtIiwicmFuZCIsInJhbmRpbnQiLCJyYW5kcmFuZ2UiLCJiIiwicmFuZHNpZ24iLCJyYW5kbnVsbHNpZ24iLCJyIiwicmVxdWVzdEF1ZGlvQ29udGV4dCIsImZuIiwiY29udGFpbmVyIiwiY3JlYXRlRWxlbWVudCIsImJ1dHRvbiIsImlubmVySFRNTCIsIk9iamVjdCIsImFzc2lnbiIsInN0eWxlIiwiZGlzcGxheSIsInBvc2l0aW9uIiwid2lkdGgiLCJoZWlnaHQiLCJ6SW5kZXgiLCJ0b3AiLCJsZWZ0IiwiYmFja2dyb3VuZENvbG9yIiwicGFkZGluZyIsImNvbG9yIiwiZm9udEZhbWlseSIsImJvcmRlclJhZGl1cyIsInRyYW5zZm9ybSIsInRleHRBbGlnbiIsImxpbmVIZWlnaHQiLCJhcHBlbmRDaGlsZCIsInNldENvbnRleHQiLCJjb250ZXh0Iiwib24iLCJvblN0YXJ0ZWQiLCJfIiwicmVtb3ZlIiwiUmVsYWJpQ2FudmFzIiwiX3JlZiIsInJlbGFiaSIsInBhcmVudCIsIl9jbGFzc0NhbGxDaGVjayIsImxhc3RGcmFtZSIsImxhc3RBcHBlbmRUaW1lIiwibGFzdEFwcGVuZEZyYW1lIiwic3BlZWQiLCJjYW52YXMiLCJjdHgiLCJnZXRDb250ZXh0IiwidmFsdWVzIiwiQXJyYXkiLCJ3aW5kb3ciLCJpbm5lcldpZHRoIiwiZmlsbCIsImFwcGVuZCIsInJlc2l6ZSIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsIl9jcmVhdGVDbGFzcyIsImtleSIsInZhbHVlIiwiX3JlcXVlc3RBbmltYXRpb25GcmFtZSIsIl94IiwiYXBwbHkiLCJhcmd1bWVudHMiLCJ0b1N0cmluZyIsImZyYW1lIiwiX3RoaXMiLCJwYWludCIsImNsZWFyIiwiY2xlYXJSZWN0IiwidGltZSIsImNvbmNhdCIsInNsaWNlIiwiZHJhd1JlbGFiaVdhdmUiLCJkcmF3Qm91bmRzIiwiX2l0ZXJhdG9yIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJib3VuZHMiLCJfc3RlcCIsInMiLCJkb25lIiwiYm91bmQiLCJ5IiwiZ2V0V2F2ZUhlaWdodCIsImxldmVsIiwiYmVnaW5QYXRoIiwic2V0TGluZURhc2giLCJzdHJva2VTdHlsZSIsIm1vdmVUbyIsImxpbmVUbyIsInN0cm9rZSIsImVyciIsImUiLCJmIiwicG9pbnRDb3VudCIsImluZGV4IiwiZnJhbWVPZmZzZXQiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicG9pbnQiLCJfcG9pbnQiLCJfc2xpY2VkVG9BcnJheSIsInRpbWVPZmZzZXQiLCJ4IiwiZGVmYXVsdCIsIlRXT19QSSIsIlBJIiwiV0FWRV9GVU5DVElPTlMiLCJzaW5lIiwiY29zIiwidHJpYW5nbGUiLCJhYnMiLCJzcXVhcmUiLCJzYXciLCJSZWxhYmkiLCJ3YXZlcyIsInVwZGF0ZVRpbWUiLCJzdGVwcyIsInR5cGUiLCJmcmVxdWVuY3kiLCJwcmV2aW91c1ZhbHVlIiwic3RhcnQiLCJjb25zb2xlIiwibG9nIiwic3RvcCIsImNsb2NrIiwiQ2xvY2siLCJnZW5lcmF0ZSIsInBsYXkiLCJkaXNwb3NlIiwid2F2ZUNvdW50Iiwic3RlcCIsIndhdmUiLCJwdXNoIiwiYm91bmRzQ291bnQiLCJub3RlQ291bnQiLCJfdmFsdWVzJHN0ZXAiLCJ0cmlnZ2VyIiwic291bmRzIiwic291bmQiLCJpbnN0cnVtZW50IiwiY29tcHJlc3NvciIsIkNvbXByZXNzb3IiLCJnYWluIiwiR2FpbiIsImNvbm5lY3QiLCJ0b0Rlc3RpbmF0aW9uIiwib3V0cHV0IiwiUExBWUVSX0NPVU5UIiwiU2FtcGxlciIsInNhbXBsZXMiLCJ0b25hbCIsIm1hcCIsIl9yZWYyIiwic2FtcGxlIiwiX2V4dGVuZHMiLCJfb2JqZWN0RGVzdHJ1Y3R1cmluZ0VtcHR5IiwicGxheWVycyIsImkiLCJsb2NhdGlvbiIsImhyZWYiLCJwbGF5ZXIiLCJQbGF5ZXIiLCJ1cmwiLCJyZXRyaWdnZXIiLCJwbGF5YmFja1JhdGUiLCJvcHRpb25zIiwicm9vdCIsIkthbGltYmEiLCJEcnVtcyIsIlJlYWN0IiwidXNlU3RhdGUiLCJ1c2VFZmZlY3QiLCJBcHAiLCJfdXNlU3RhdGUiLCJfdXNlU3RhdGUyIiwic2V0UmVsYWJpIiwicmVsYWJpR2VuZXJhdG9yIiwiY3JlYXRlUm9vdCIsIm1hcmdpbiIsImdldEVsZW1lbnRCeUlkIiwicmVuZGVyIl0sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///441\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\nwindow.__audio_context_started = false;\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" || window.__audio_context_started;\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 try {\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\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 window.__audio_context_started = true;\n } catch (error) {\n //\n }\n }\n return StartAudioContext;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUNFLGFBQWEsQ0FBQ1UsTUFBTSxFQUFFRCxDQUFDLEVBQUUsRUFBRTtVQUMvRFgsaUJBQWlCLENBQUNFLGFBQWEsQ0FBQ1MsQ0FBQyxDQUFDLENBQUN5QixPQUFPLENBQUMsQ0FBQztRQUM5QztRQUNBcEMsaUJBQWlCLENBQUNFLGFBQWEsR0FBRyxJQUFJO01BQ3hDOztNQUVBO01BQ0EsSUFBSUYsaUJBQWlCLENBQUNHLFVBQVUsRUFBRTtRQUNoQyxLQUFLLElBQUkrQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdsRCxpQkFBaUIsQ0FBQ0csVUFBVSxDQUFDUyxNQUFNLEVBQUVzQyxDQUFDLEVBQUUsRUFBRTtVQUM1RGxELGlCQUFpQixDQUFDRyxVQUFVLENBQUMrQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DO1FBQ0FsRCxpQkFBaUIsQ0FBQ0csVUFBVSxHQUFHLElBQUk7TUFDckM7TUFFQVosTUFBTSxDQUFDQyx1QkFBdUIsR0FBRyxJQUFJO0lBQ3ZDLENBQUMsQ0FBQyxPQUFPMkQsS0FBSyxFQUFFO01BQ2Q7SUFBQTtFQUVKO0VBRUEsT0FBT25ELGlCQUFpQjtBQUMxQixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3N0YXJ0QXVkaW9Db250ZXh0LmpzPzZlYmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgU3RhcnRBdWRpb0NvbnRleHQuanNcbiAqICBAYXV0aG9yIFlvdGFtIE1hbm5cbiAqICBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiAgQGNvcHlyaWdodCAyMDE2IFlvdGFtIE1hbm5cbiAqL1xuXG53aW5kb3cuX19hdWRpb19jb250ZXh0X3N0YXJ0ZWQgPSBmYWxzZTtcblxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuU3RhcnRBdWRpb0NvbnRleHQgPSBmYWN0b3J5KCk7XG4gIH1cbn0pKHRoaXMsIGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIFRoZSBTdGFydEF1ZGlvQ29udGV4dCBvYmplY3RcbiAgICovXG4gIHZhciBTdGFydEF1ZGlvQ29udGV4dCA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gY29udGV4dCBwYXNzZWQgaW4gYnkgdGhlIHVzZXJcbiAgICAgKiBAdHlwZSB7QXVkaW9Db250ZXh0fVxuICAgICAqL1xuICAgIGNvbnRleHQ6IG51bGwsXG4gICAgLyoqXG4gICAgICogVGhlIFRhcExpc3RlbmVycyBib3VuZCB0byB0aGUgZWxlbWVudHNcbiAgICAgKiBAdHlwZSB7QXJyYXl9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdGFwTGlzdGVuZXJzOiBbXSxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZFxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9vblN0YXJ0ZWQ6IFtdLFxuICB9O1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvbnRleHRcbiAgICogQHBhcmFtIHtBdWRpb0NvbnRleHR9IGN0eFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0ID0gZnVuY3Rpb24gKGN0eCkge1xuICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQgPSBjdHg7XG4gICAgcmV0dXJuIFN0YXJ0QXVkaW9Db250ZXh0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSB0YXAgbGlzdGVuZXIgdG8gdGhlIGF1ZGlvIGNvbnRleHRcbiAgICogQHBhcmFtICB7QXJyYXl8RWxlbWVudHxTdHJpbmd8alF1ZXJ5fSBlbGVtZW50XG4gICAqIEByZXR1cm5zIHtTdGFydEF1ZGlvQ29udGV4dH1cbiAgICovXG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbGVtZW50KSB8fCAoTm9kZUxpc3QgJiYgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGVsZW1lbnRbaV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbWVudCkpO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudC5qcXVlcnkgJiYgdHlwZW9mIGVsZW1lbnQudG9BcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5vbihlbGVtZW50LnRvQXJyYXkoKSk7XG4gICAgfSBlbHNlIGlmIChFbGVtZW50ICYmIGVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAvL2lmIGl0J3MgYW4gZWxlbWVudCwgY3JlYXRlIGEgVGFwTGlzdGVuZXJcbiAgICAgIHZhciB0YXAgPSBuZXcgVGFwTGlzdGVuZXIoZWxlbWVudCwgb25UYXApO1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5wdXNoKHRhcCk7XG4gICAgfVxuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogQmluZCBhIGNhbGxiYWNrIHRvIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAgICogQHJldHVybiB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5vblN0YXJ0ZWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICAvL2lmIGl0J3MgYWxyZWFkeSBzdGFydGVkLCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCgpKSB7XG4gICAgICBjYigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkLnB1c2goY2IpO1xuICAgIH1cbiAgICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGV4dCBpcyBzdGFydGVkXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5pc1N0YXJ0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIChTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICE9PSBudWxsICYmXG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuc3RhdGUgPT09IFwicnVubmluZ1wiKSB8fFxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogQGNsYXNzICBMaXN0ZW5zIGZvciBub24tZHJhZ2dpbmcgdGFwIGVuZHMgb24gdGhlIGdpdmVuIGVsZW1lbnRcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdmFyIFRhcExpc3RlbmVyID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSB0aGlzLl9tb3ZlZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IHRoaXMuX2VuZGVkLmJpbmQodGhpcyk7XG5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fYmluZGVkTW92ZSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGRyYWcgbW92ZSBldmVudFxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9tb3ZlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdGhpcy5fZHJhZ2dlZCA9IHRydWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIHRhcCBlbmRlZCBsaXN0ZW5lclxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9lbmRlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKCF0aGlzLl9kcmFnZ2VkKSB7XG4gICAgICBvblRhcCgpO1xuICAgIH1cbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJlbW92ZSBhbGwgdGhlIGJvdW5kIGV2ZW50c1xuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX2JpbmRlZE1vdmUpO1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLl9iaW5kZWRFbmQpO1xuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSBudWxsO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IG51bGw7XG4gICAgdGhpcy5fZWxlbWVudCA9IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEludm9rZWQgdGhlIGZpcnN0IHRpbWUgb2YgdGhlIGVsZW1lbnRzIGlzIHRhcHBlZC5cbiAgICogQ3JlYXRlcyBhIHNpbGVudCBvc2NpbGxhdG9yIHdoZW4gYSBub24tZHJhZ2dpbmcgdG91Y2hlbmRcbiAgICogZXZlbnQgaGFzIGJlZW4gdHJpZ2dlcmVkLlxuICAgKi9cbiAgZnVuY3Rpb24gb25UYXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQgd2l0aCBhIHNpbGVudCBvc2NpbGxhdG9yXG4gICAgICBpZiAoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dCAmJiAhU3RhcnRBdWRpb0NvbnRleHQuaXNTdGFydGVkKCkpIHtcbiAgICAgICAgdmFyIG9zYyA9IFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICB2YXIgc2lsZW50ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIHNpbGVudC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgb3NjLmNvbm5lY3Qoc2lsZW50KTtcbiAgICAgICAgc2lsZW50LmNvbm5lY3QoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHZhciBub3cgPSBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICBvc2Muc3RhcnQobm93KTtcbiAgICAgICAgb3NjLnN0b3Aobm93ICsgMC41KTtcbiAgICAgIH1cblxuICAgICAgLy9kaXNwb3NlIGFsbCB0aGUgdGFwIGxpc3RlbmVyc1xuICAgICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBTdGFydEF1ZGlvQ29udGV4dC5fdGFwTGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVyc1tpXS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vdGhlIG9uc3RhcnRlZCBjYWxsYmFja3NcbiAgICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWRbal0oKTtcbiAgICAgICAgfVxuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy9cbiAgICB9XG4gIH1cblxuICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG59KTtcbiJdLCJuYW1lcyI6WyJ3aW5kb3ciLCJfX2F1ZGlvX2NvbnRleHRfc3RhcnRlZCIsInJvb3QiLCJmYWN0b3J5IiwiZGVmaW5lIiwiYW1kIiwibW9kdWxlIiwiX3R5cGVvZiIsImV4cG9ydHMiLCJTdGFydEF1ZGlvQ29udGV4dCIsImNvbnRleHQiLCJfdGFwTGlzdGVuZXJzIiwiX29uU3RhcnRlZCIsInNldENvbnRleHQiLCJjdHgiLCJvbiIsImVsZW1lbnQiLCJBcnJheSIsImlzQXJyYXkiLCJOb2RlTGlzdCIsImkiLCJsZW5ndGgiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJqcXVlcnkiLCJ0b0FycmF5IiwiRWxlbWVudCIsInRhcCIsIlRhcExpc3RlbmVyIiwib25UYXAiLCJwdXNoIiwib25TdGFydGVkIiwiY2IiLCJpc1N0YXJ0ZWQiLCJzdGF0ZSIsIl9kcmFnZ2VkIiwiX2VsZW1lbnQiLCJfYmluZGVkTW92ZSIsIl9tb3ZlZCIsImJpbmQiLCJfYmluZGVkRW5kIiwiX2VuZGVkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByb3RvdHlwZSIsImUiLCJkaXNwb3NlIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIm9zYyIsImNyZWF0ZU9zY2lsbGF0b3IiLCJzaWxlbnQiLCJjcmVhdGVHYWluIiwiZ2FpbiIsInZhbHVlIiwiY29ubmVjdCIsImRlc3RpbmF0aW9uIiwibm93IiwiY3VycmVudFRpbWUiLCJzdGFydCIsInN0b3AiLCJqIiwiZXJyb3IiXSwic291cmNlUm9vdCI6IiJ9\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__(441)})();
\ 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")},441:(__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 util_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/relabi/canvas.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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\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 * Relabi waveform display\n * @module src/relabi/canvas.js;\n */\nvar RelabiCanvas = /*#__PURE__*/function () {\n /**\n * Initialize relabi wave renderer\n */\n function RelabiCanvas(_ref) {\n var relabi = _ref.relabi,\n parent = _ref.parent;\n _classCallCheck(this, RelabiCanvas);\n this.relabi = relabi;\n this.height = 400;\n this.lastFrame = 0;\n this.lastAppendTime = 0;\n this.lastAppendFrame = 0;\n\n // Speed of the wave in pixels per second\n this.speed = 1 / 5;\n\n // Position of current time on the screen, from the left\n this.tZeroOffset = 20;\n\n // Attach to the DOM\n this.appendCanvas(parent);\n // Initialize array\n this.values = new Array(window.innerWidth).fill(0);\n this.notes = [];\n this.append([]);\n\n // Clear the canvas\n this.resize();\n\n // Start drawing\n this.requestAnimationFrame(0);\n }\n\n /**\n * Append the canvas\n */\n _createClass(RelabiCanvas, [{\n key: "appendCanvas",\n value: function appendCanvas(parent) {\n this.parent = parent || document.body;\n this.canvas = this.canvas || document.createElement("canvas");\n this.ctx = this.ctx || this.canvas.getContext("2d");\n this.parent.appendChild(this.canvas);\n }\n\n /**\n * Draw the next frame\n */\n }, {\n key: "requestAnimationFrame",\n value: function (_requestAnimationFrame) {\n function requestAnimationFrame(_x) {\n return _requestAnimationFrame.apply(this, arguments);\n }\n requestAnimationFrame.toString = function () {\n return _requestAnimationFrame.toString();\n };\n return requestAnimationFrame;\n }(function (frame) {\n var _this = this;\n requestAnimationFrame(function (frame) {\n _this.requestAnimationFrame(frame);\n });\n this.paint(frame);\n this.lastFrame = frame;\n }\n\n /**\n * Handle window resize\n */)\n }, {\n key: "resize",\n value: function resize() {\n this.canvas.width = window.innerWidth;\n this.canvas.height = this.height;\n }\n\n /**\n * Clear the canvas\n */\n }, {\n key: "clear",\n value: function clear() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n\n /**\n * Append values\n */\n }, {\n key: "append",\n value: function append(time, values, notes) {\n this.lastAppendTime = time;\n this.lastAppendFrame = this.lastFrame;\n this.values = this.values.concat(values).slice(-this.canvas.width).sort(function (a, b) {\n return a[0] - b[0];\n });\n if (notes !== null && notes !== void 0 && notes.length) {\n this.notes = this.notes.concat(notes).slice(-50).sort(function (a, b) {\n return a[0] - b[0];\n });\n }\n }\n\n /**\n * Paint the canvas\n */\n }, {\n key: "paint",\n value: function paint(frame) {\n this.clear();\n this.drawRelabiWave(frame);\n this.drawBounds();\n this.drawNotes(frame);\n }\n\n /**\n * Draw the bounds\n */\n }, {\n key: "drawBounds",\n value: function drawBounds() {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n\n // Draw dashed lines for all bounds\n var _iterator = _createForOfIteratorHelper(this.relabi.bounds),\n _step;\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var bound = _step.value;\n var y = getWaveHeight(bound.level, height);\n ctx.beginPath();\n ctx.setLineDash([4, 4]);\n ctx.lineWidth = 1;\n ctx.strokeStyle = bound.color || "#888";\n ctx.moveTo(0, y);\n ctx.lineTo(width, y);\n ctx.stroke();\n }\n\n // Draw the zero position\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n ctx.beginPath();\n ctx.setLineDash([1, 1]);\n ctx.lineWidth = 2;\n ctx.strokeStyle = "#666";\n ctx.moveTo(width - this.tZeroOffset, 0);\n ctx.lineTo(width - this.tZeroOffset, height);\n ctx.stroke();\n }\n\n /**\n * Draw the relabi wave\n */\n }, {\n key: "drawRelabiWave",\n value: function drawRelabiWave(frame) {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n var pointCount = this.values.length;\n var index = 0;\n\n // Start the path\n ctx.beginPath();\n ctx.strokeStyle = "#dff";\n ctx.lineWidth = 0.75;\n ctx.setLineDash([]);\n\n // This is the offset in seconds from the last frame we computed\n var frameOffset = (frame - this.lastAppendFrame) / 1000;\n\n // Make a path connecting all values\n var _iterator2 = _createForOfIteratorHelper(this.values),\n _step2;\n try {\n for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {\n var point = _step2.value;\n if (!point) {\n index += 1;\n continue;\n }\n var _point = _slicedToArray(point, 2),\n time = _point[0],\n value = _point[1];\n\n // This is the offset of this time from current time\n // If this is in the future, it will be positive.\n // Subtracting the frame offset pulls it negative.\n var timeOffset = this.lastAppendTime + frameOffset - time;\n var x = width - timeOffset * this.speed * width - this.tZeroOffset;\n var y = getWaveHeight(value, height);\n if (x < 0) {\n continue;\n }\n if (index === 0) {\n ctx.moveTo(x, y);\n }\n ctx.lineTo(x, y);\n index += 1;\n }\n\n // Paint the line\n } catch (err) {\n _iterator2.e(err);\n } finally {\n _iterator2.f();\n }\n ctx.stroke();\n }\n\n /**\n * Draw the notes\n */\n }, {\n key: "drawNotes",\n value: function drawNotes(frame) {\n var canvas = this.canvas,\n ctx = this.ctx;\n var width = canvas.width,\n height = canvas.height;\n\n // This is the offset in seconds from the last frame we computed\n var frameOffset = (frame - this.lastAppendFrame) / 1000;\n\n // Make a path connecting all values\n var _iterator3 = _createForOfIteratorHelper(this.notes),\n _step3;\n try {\n for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {\n var note = _step3.value;\n var _note = _slicedToArray(note, 3),\n time = _note[0],\n value = _note[1],\n direction = _note[2];\n var timeOffset = this.lastAppendTime + frameOffset - time;\n var x = width - timeOffset * this.speed * width - this.tZeroOffset;\n var y = getWaveHeight(value, height);\n\n // Don\'t draw notes that haven\'t played yet\n if (x > width - this.tZeroOffset) {\n continue;\n }\n\n // Draw notes as a dot that fades out\n var opacity = 1 - timeOffset * this.speed * width / 1000;\n if (opacity < 0.001) {\n continue;\n }\n ctx.beginPath();\n ctx.arc(x - 2.5, y, 5, 0, 2 * Math.PI);\n ctx.fillStyle = direction ? "rgba(255,128,192,".concat(opacity, ")") : "rgba(192,255,128,".concat(opacity, ")");\n ctx.fill();\n }\n } catch (err) {\n _iterator3.e(err);\n } finally {\n _iterator3.f();\n }\n }\n }]);\n return RelabiCanvas;\n}();\n/**\n * Get the height of the wave at a given value\n */\n\nvar getWaveHeight = function getWaveHeight(value, height) {\n return (value + 1) / 2 * height;\n};\n;// CONCATENATED MODULE: ./src/relabi/index.js\nfunction relabi_typeof(obj) { "@babel/helpers - typeof"; return relabi_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; }, relabi_typeof(obj); }\nfunction relabi_slicedToArray(arr, i) { return relabi_arrayWithHoles(arr) || relabi_iterableToArrayLimit(arr, i) || relabi_unsupportedIterableToArray(arr, i) || relabi_nonIterableRest(); }\nfunction relabi_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction relabi_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return relabi_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return relabi_arrayLikeToArray(o, minLen); }\nfunction relabi_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction relabi_iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction relabi_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction relabi_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction relabi_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, relabi_toPropertyKey(descriptor.key), descriptor); } }\nfunction relabi_createClass(Constructor, protoProps, staticProps) { if (protoProps) relabi_defineProperties(Constructor.prototype, protoProps); if (staticProps) relabi_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction relabi_toPropertyKey(arg) { var key = relabi_toPrimitive(arg, "string"); return relabi_typeof(key) === "symbol" ? key : String(key); }\nfunction relabi_toPrimitive(input, hint) { if (relabi_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (relabi_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n/**\n * Relabi event generator\n */\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};\n\n/**\n * Relabi generator\n */\nvar Relabi = /*#__PURE__*/function () {\n /**\n * Initialize generator\n */\n function Relabi(_ref) {\n var waves = _ref.waves,\n bounds = _ref.bounds,\n parent = _ref.parent;\n relabi_classCallCheck(this, Relabi);\n this.updateTime = 1;\n this.steps = 50;\n this.waves = waves || [{\n type: "triangle",\n frequency: randrange(0.5, 1.5)\n }, {\n type: "triangle",\n frequency: randrange(0.75, 2.25)\n }, {\n type: "triangle",\n frequency: randrange(1, 3)\n }, {\n type: "triangle",\n frequency: randrange(2, 4)\n }];\n this.bounds = bounds;\n this.previousValue = null;\n this.canvas = new RelabiCanvas({\n relabi: this,\n parent: parent\n });\n }\n\n /**\n * Start the generator\n */\n relabi_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 var values = _this.generate(time);\n var notes = _this.play(values);\n _this.canvas.append(time, values, notes);\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: "generate",\n value: function generate(time) {\n var waveCount = this.waves.length;\n var index;\n var step;\n var value;\n var values = [];\n\n // Overshoot the line slightly each time\n var stepCount = this.steps + 20;\n\n // Generate several events per second\n for (step = 0; step < stepCount; step += 1) {\n // Time offset for this event\n var timeOffset = 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](timeOffset * wave.frequency);\n }\n\n // Scale to [-1, 1]\n value /= waveCount;\n values.push([timeOffset, value]);\n }\n return values;\n }\n\n /**\n * Schedule relabi events\n */\n }, {\n key: "play",\n value: function play(values) {\n var boundsCount = this.bounds.length;\n var previousValue = this.previousValue;\n var index;\n var step;\n var noteCount = 0;\n var notes = [];\n for (step = 0; step < this.steps; step += 1) {\n // Get the next value\n var _values$step = relabi_slicedToArray(values[step], 2),\n time = _values$step[0],\n value = _values$step[1];\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.level && bound.level < previousValue && previousValue !== null) {\n // Going down\n this.trigger(time, bound.sounds[0]);\n notes.push([time, bound.level, true]);\n noteCount += 1;\n } else if (value > bound.level && bound.level > previousValue && previousValue !== null) {\n // Going up\n this.trigger(time, bound.sounds[1]);\n notes.push([time, bound.level, false]);\n noteCount += 1;\n }\n }\n\n // Update the previous value\n previousValue = value;\n }\n\n // Store the latest value\n this.previousValue = previousValue;\n\n // Return the notes\n return notes;\n }\n\n /**\n * Trigger an event\n */\n }, {\n key: "trigger",\n value: function trigger(time, sound) {\n // console.log("trigger index", index, time);\n sound.instrument.play(time, sound);\n }\n }]);\n return Relabi;\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/sampler.js\nfunction sampler_typeof(obj) { "@babel/helpers - typeof"; return sampler_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; }, sampler_typeof(obj); }\nfunction _objectDestructuringEmpty(obj) { if (obj == null) throw new TypeError("Cannot destructure " + obj); }\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nfunction sampler_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }\nfunction sampler_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, sampler_toPropertyKey(descriptor.key), descriptor); } }\nfunction sampler_createClass(Constructor, protoProps, staticProps) { if (protoProps) sampler_defineProperties(Constructor.prototype, protoProps); if (staticProps) sampler_defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }\nfunction sampler_toPropertyKey(arg) { var key = sampler_toPrimitive(arg, "string"); return sampler_typeof(key) === "symbol" ? key : String(key); }\nfunction sampler_toPrimitive(input, hint) { if (sampler_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (sampler_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }\n\n\n\nvar PLAYER_COUNT = 4;\nvar sampler_Sampler = /*#__PURE__*/function () {\n function Sampler(_ref) {\n var samples = _ref.samples,\n tonal = _ref.tonal;\n sampler_classCallCheck(this, Sampler);\n this.tonal = tonal;\n this.samples = samples.map(function (_ref2) {\n var sample = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));\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 return sample;\n });\n }\n sampler_createClass(Sampler, [{\n key: "play",\n value: function play(time, options) {\n var sound = options.index ? this.samples[options.index] : choice(this.samples);\n sound.index = (sound.index + 1) % PLAYER_COUNT;\n var player = sound.players[sound.index];\n if (this.tonal) {\n player.playbackRate = (options.frequency * choice([0.5, 1]) + util_randrange(0, 10)) / sound.root;\n }\n player.start(time || 0);\n }\n }]);\n return Sampler;\n}();\n\n;// CONCATENATED MODULE: ./src/lib/instruments.js\n\nvar Kalimba = new sampler_Sampler({\n tonal: true,\n 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});\nvar Drums = new sampler_Sampler({\n tonal: false,\n samples: [{\n fn: "samples/707_bd.mp3"\n }, {\n fn: "samples/707_clap.mp3"\n },\n // { fn: "samples/707_cow.mp3" },\n {\n fn: "samples/707_hat.mp3"\n }, {\n fn: "samples/707_rim.mp3"\n }]\n});\n;// CONCATENATED MODULE: ./src/ui/App.jsx\nfunction App_slicedToArray(arr, i) { return App_arrayWithHoles(arr) || App_iterableToArrayLimit(arr, i) || App_unsupportedIterableToArray(arr, i) || App_nonIterableRest(); }\nfunction App_nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }\nfunction App_unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return App_arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return App_arrayLikeToArray(o, minLen); }\nfunction App_arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction App_iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }\nfunction App_arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n/**\n * Relabi generator UI\n * @module src/ui/App.js;\n */\n\n\n\n\n\nfunction App() {\n var _useState = (0,react.useState)(),\n _useState2 = App_slicedToArray(_useState, 2),\n relabi = _useState2[0],\n setRelabi = _useState2[1];\n var relabiRef = (0,react.useRef)();\n\n /**\n * Instantiate the Relabi generator\n */\n (0,react.useEffect)(function () {\n if (!relabi) {\n var relabiGenerator = new Relabi({\n waves: [{\n type: "sine",\n frequency: 0.75\n }, {\n type: "sine",\n frequency: 1.0\n }, {\n type: "sine",\n frequency: 1.617\n }, {\n type: "sine",\n frequency: 3.141\n }],\n bounds: [{\n level: -0.75,\n color: "#f33",\n sounds: [{\n instrument: Drums,\n index: 0\n }, {\n instrument: Drums,\n index: 1\n }]\n }, {\n level: 0.75,\n color: "#f83",\n sounds: [{\n instrument: Drums,\n index: 2\n }, {\n instrument: Drums,\n index: 3\n }]\n }, {\n level: -0.25,\n color: "#3b8",\n sounds: [{\n instrument: Kalimba,\n frequency: 440\n }, {\n instrument: Kalimba,\n frequency: 440 * 3 / 2\n }]\n }, {\n level: 0.25,\n color: "#36f",\n sounds: [{\n instrument: Kalimba,\n frequency: 440 * 6 / 5\n }, {\n instrument: Kalimba,\n frequency: 440 * 6 / 7\n }]\n }]\n });\n relabiGenerator.start();\n setRelabi(relabiGenerator);\n }\n }, [relabi]);\n (0,react.useEffect)(function () {\n if (relabi && relabiRef.current) {\n relabi.canvas.appendCanvas(relabiRef.current);\n }\n }, [relabi, relabiRef.current]);\n\n /**\n * Render\n */\n return /*#__PURE__*/react.createElement("div", {\n style: {\n height: "100%",\n width: "100%",\n padding: 0,\n margin: 0,\n display: "flex",\n flexDirection: "column",\n justifyContent: "center"\n }\n }, /*#__PURE__*/react.createElement("div", {\n ref: relabiRef\n }));\n}\n;// CONCATENATED MODULE: ./src/index.jsx\n\n\n\n\ndocument.body.style.backgroundColor = "#111";\ndocument.body.style.color = "#fff";\ndocument.body.style.margin = 0;\ndocument.body.style.padding = 0;\ndocument.body.style.height = "100%";\ndocument.body.style.width = "100%";\ndocument.body.parentNode.style.margin = 0;\ndocument.body.parentNode.style.padding = 0;\ndocument.body.parentNode.style.height = "100%";\ndocument.body.parentNode.style.width = "100%";\nrequestAudioContext(function () {\n var container = document.createElement("div");\n container.style.height = "100%";\n container.style.width = "100%";\n document.body.innerHTML = "";\n document.body.appendChild(container);\n var root = (0,client/* createRoot */.s)(container);\n root.render( /*#__PURE__*/react.createElement(App, null));\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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YUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7QUFDQSxxREFBcUQ7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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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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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBGQUEwRixRQUFRO0FBQ2xHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxRQUFRO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDNVN3QztBQUMwQjtBQUNMO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLCtEQUFlO0FBQ3pDO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQSw2Q0FBNkMsU0FBSTtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQzs7QUNuS2dEO0FBQ2dCO0FBQ1M7QUFDZDtBQUNvQjtBQUN2QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLE1BQU0sb0NBQW9DO0FBQzlDLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sU0FBSSxTQUFTLHlEQUFTO0FBQ25DO0FBQ0EsbUNBQW1DLFNBQUk7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFNBQUk7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQjtBQUN0Qiw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxTQUFJO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ2haNEM7QUFDRjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsbUJBQW1CO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxVQUFVLGlDQUFnQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEM7O0FDcEs4QjtBQUN3QjtBQUNPO0FBQ2Y7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyxzQkFBc0Isb0RBQUk7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xFZ0Q7QUFDNkI7QUFDbEI7QUFDN0I7QUFDVTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLHlEQUFTO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQzs7QUN0UHVCO0FBQ0E7QUFDRztBQUNDO0FBQ0M7QUFDNUIsaUM7O0FDTCtDO0FBQzJCO0FBQ1Y7QUFDWDtBQUNFO0FBQ1Y7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyw2REFBYTtBQUM1QztBQUNBLGlEQUFpRCxtQkFBUztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyx1QkFBdUI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsdUJBQXVCO0FBQ3hEO0FBQ0EsNkNBQTZDLG1CQUFTO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQzs7QUN6RzJEO0FBQ2Y7QUFDa0I7QUFDWjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxhQUFNLFNBQVMsNkRBQWE7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLHVCQUF1QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsdUJBQXVCO0FBQzVEO0FBQ0E7QUFDQTtBQUNBLHVDQUF1Qyx1QkFBdUI7QUFDOUQ7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHVCQUF1QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0M7O0FDckUwQztBQUNLO0FBQ0c7QUFDbEQ7QUFDQTtBQUNBO0FBQ08sTUFBTSxtQkFBUyxTQUFTLHNEQUFNO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQzs7QUM1RW9EO0FBQ1M7QUFDckI7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08seUJBQXlCLHlEQUFTO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQzs7QUNuRWlEO0FBQ2dCO0FBQ0Q7QUFDWDtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDTyxNQUFNLGFBQU0sU0FBUywyQkFBYTtBQUN6QztBQUNBLDRCQUE0Qiw2QkFBb0IsQ0FBQyxhQUFNO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDZCQUFvQixDQUFDLGFBQU07QUFDbkQsdUJBQXVCLFdBQUs7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLGtCQUFRO0FBQ2hCO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDOztBQ3REcUQ7QUFDUTtBQUNyQjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08seUJBQXlCLHlEQUFTO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQ3hDaUU7QUFDRDtBQUNSO0FBQ2pCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSxpQkFBUSxTQUFTLDZEQUFhO0FBQzNDO0FBQ0EsbUNBQW1DLGlCQUFRO0FBQzNDO0FBQ0EsNkNBQTZDLGlCQUFRO0FBQ3JELDJDQUEyQyx1QkFBdUI7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQ2xEa0M7QUFDa0I7QUFDTTtBQUNHO0FBQ2pCO0FBQ2tCO0FBQ2hCO0FBQ0k7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sc0JBQXNCLHNEQUFNO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLHNDQUFzQyx1QkFBdUI7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xJbUQ7QUFDb0I7QUFDaEUsTUFBTSw4QkFBVztBQUNqQjtBQUNQOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLENBQUMsOEJBQVc7QUFDN0IsOEM7O0FDeEJvRTtBQUNsQztBQUNVO0FBQ2lCO0FBQ0M7QUFDaEI7QUFDSztBQUNuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyx5QkFBeUIsc0RBQU07QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsZ0VBQWdCO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHVCQUF1QjtBQUN2RCxpQ0FBaUMsdUJBQXVCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQ3BGa0M7QUFDMkI7QUFDWDtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sd0JBQXdCLHNEQUFNO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQzs7QUM1RmlFO0FBQ0Q7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sV0FBSyxTQUFTLDZEQUFhO0FBQ3hDO0FBQ0EsbUNBQW1DLFdBQUs7QUFDeEM7QUFDQSw2Q0FBNkMsV0FBSztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQzs7QUM3QmlFO0FBQ0Q7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sV0FBSyxTQUFTLDZEQUFhO0FBQ3hDO0FBQ0EsbUNBQW1DLFdBQUs7QUFDeEM7QUFDQSw2Q0FBNkMsV0FBSztBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUM7O0FDL0JzRjtBQUMzQjtBQUNSO0FBQ1A7QUFDTztBQUNEO0FBQ2xEO0FBQ0E7QUFDQTtBQUNPLE1BQU0seUJBQVksU0FBUyw2REFBYTtBQUMvQztBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsdUJBQXVCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLGtDQUFrQyxvQ0FBb0M7QUFDdEUsa0NBQWtDLG9DQUFvQztBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDOztBQzVEOEM7QUFDSjtBQUNFO0FBQ007QUFDQztBQUNBO0FBQ25EO0FBQ0E7QUFDQTtBQUNPLE1BQU0seUNBQW9CLFNBQVMsNERBQVk7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHFDQUFxQyx1QkFBdUI7QUFDNUQscUNBQXFDLHVCQUF1QjtBQUM1RCwwQ0FBMEMsb0NBQW9DO0FBQzlFLDBDQUEwQyxvQ0FBb0M7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnRDs7QUNoRHNFO0FBQ1Q7QUFDZDtBQUNEO0FBQ0k7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxxQkFBcUIsb0VBQW9CO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHVDQUF1Qyx1QkFBdUI7QUFDOUQsdUNBQXVDLHVCQUF1QjtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQzs7QUM1SjZEO0FBQ1g7QUFDaEI7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyx5QkFBeUIsc0RBQU07QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0M7O0FDcEU0QztBQUNNO0FBQ2hCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSw2QkFBYyxTQUFTLHNEQUFNO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDOztBQ2pDOEM7QUFDZTtBQUNYO0FBQ0E7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ08sNEJBQTRCLDhEQUFjO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUM5QytDO0FBQ2lDO0FBQ2hGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNLG1DQUFpQixTQUFTLDZEQUFhO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyx1QkFBdUI7QUFDdkQ7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLHVCQUF1QjtBQUN4RDtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsdUJBQXVCO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkM7O0FDckQwRTtBQUNiO0FBQ25CO0FBQ047QUFDVTtBQUNKO0FBQ0E7QUFDbUI7QUFDZ0I7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sK0JBQStCLHNEQUFNO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCw0Q0FBNEMsdUJBQXVCO0FBQ25FLDhDQUE4Qyx1QkFBdUI7QUFDckUsb0NBQW9DLHVCQUF1QjtBQUMzRCw4QkFBOEIsdUJBQXVCO0FBQ3JELHFEQUFxRCx1QkFBdUI7QUFDNUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDOztBQ3ZGOEM7QUFDZTtBQUNYO0FBQ1I7QUFDZ0M7QUFDMUU7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGdLQUFnSDtBQUMxSTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsb0VBQW9CO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHVCQUF1Qiw0REFBWTtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDdkc4QztBQUNlO0FBQ3JCO0FBQ0U7QUFDa0M7QUFDMUI7QUFDbEQ7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLHdHQUF3RDtBQUNyRjtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsNEVBQTRCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQiw4REFBYztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLDREQUFZO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQ2hHOEQ7QUFDWjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sMkNBQXFCLFNBQVMsb0VBQW9CO0FBQy9EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRDs7QUMzQmdFO0FBQ0g7QUFDZjtBQUNKO0FBQ1E7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLDRCQUE0QixxRUFBcUI7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDOztBQ2pFa0Q7QUFDVztBQUNkO0FBQ0Q7QUFDYTtBQUNqQjtBQUNRO0FBQ2tCO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyx5QkFBeUIsOERBQWM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsdUJBQXVCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsMENBQTBDLHVCQUF1QjtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDOztBQzNJOEM7QUFDZTtBQUNkO0FBQ0w7QUFDUTtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNPLHFCQUFxQiw0REFBWTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsWUFBWTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDOztBQ3RIa0M7QUFDaUI7QUFDUDtBQUNpQjtBQUNyQjtBQUNOO0FBQzhCO0FBQ2xCO0FBQ0c7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08scUJBQXFCLHNEQUFNO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsU0FBUztBQUNoRCx1Q0FBdUMsU0FBUztBQUNoRCxzQ0FBc0MsU0FBUztBQUMvQztBQUNBO0FBQ0Esd0NBQXdDLFNBQVM7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQzs7QUM5R2lFO0FBQ2pDO0FBQ087QUFDVTtBQUNBO0FBQ2U7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakMsa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNPLE1BQU0seUJBQVksU0FBUyw2REFBYTtBQUMvQztBQUNBLG1DQUFtQyx5QkFBWTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxpQ0FBaUMsdUJBQXVCO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCw0Q0FBNEMsdUJBQXVCO0FBQ25FO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0M7O0FDbERpRTtBQUNqQztBQUNPO0FBQ1U7QUFDQTtBQUNGO0FBQ2lCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQyxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ08sTUFBTSx5QkFBWSxTQUFTLDZEQUFhO0FBQy9DO0FBQ0EsbUNBQW1DLHlCQUFZO0FBQy9DO0FBQ0EsOEJBQThCLHVCQUF1QjtBQUNyRCwrQkFBK0IsdUJBQXVCO0FBQ3RELCtCQUErQix1QkFBdUI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHFDQUFxQyx1QkFBdUI7QUFDNUQ7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULGdEQUFnRCx1QkFBdUI7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDOztBQ3BEa0M7QUFDK0I7QUFDQTtBQUNqRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0sMkJBQWEsU0FBUyxzREFBTTtBQUN6QztBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsdUJBQXVCO0FBQ3ZFLGdEQUFnRCx1QkFBdUI7QUFDdkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUNsRHdEO0FBQ2Q7QUFDSTtBQUNBO0FBQ2U7QUFDWDtBQUNNO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sNEJBQTRCLDZEQUFhO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHVDQUF1Qyx1QkFBdUI7QUFDOUQ7QUFDQTtBQUNBLDZDQUE2Qyx1QkFBdUI7QUFDcEU7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLHVCQUF1QjtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Qzs7QUNoRThDO0FBQ0M7QUFDSDtBQUNGO0FBQ21CO0FBQ1g7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sc0JBQXNCLDREQUFZO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULHNDQUFzQyx1QkFBdUI7QUFDN0Qsc0NBQXNDLHVCQUF1QjtBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQ2xJa0M7QUFDMkI7QUFDZDtBQUNEO0FBQ0k7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHNCQUFzQixzREFBTTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DOztBQzVENkI7QUFDQTtBQUNIO0FBQ0c7QUFDRDtBQUNIO0FBQ0k7QUFDRztBQUNHO0FBQ1I7QUFDQTtBQUNLO0FBQ0g7QUFDSjtBQUNBO0FBQ087QUFDTjtBQUNBO0FBQzFCLGlDOztBQ2xCaUU7QUFDRDtBQUN2QjtBQUNNO0FBQ2E7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU0saUJBQVEsU0FBUyw2REFBYTtBQUMzQztBQUNBLG1DQUFtQyxpQkFBUTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsaUJBQVE7QUFDckQsMkRBQTJELHVCQUF1QjtBQUNsRjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLDRCQUE0QjtBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlGQUFpRixLQUFLO0FBQ3RGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDdkhpRTtBQUNEO0FBQzFCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNPLE1BQU0sbUJBQVMsU0FBUyw2REFBYTtBQUM1QztBQUNBLG1DQUFtQyxtQkFBUztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUM7O0FDdEJ1RDtBQUNTO0FBQ3hCO0FBQ0s7QUFDUDtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sb0JBQW9CLHlEQUFTO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDOztBQ3pGaUU7QUFDVjtBQUNTO0FBQ3hCO0FBQ087QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDTyxrQkFBa0IseURBQVM7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEdBQTBHLFVBQVU7QUFDcEg7QUFDQTtBQUNBO0FBQ0EsK0I7O0FDaEVnRTtBQUN4QjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHNCQUFzQix5REFBUztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUM7O0FDOUJnRTtBQUN4QjtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNPLHVCQUF1Qix5REFBUztBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DOztBQ3JDK0M7QUFDa0I7QUFDRDtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxtQkFBbUIsMkJBQWE7QUFDdkM7QUFDQSxjQUFjLDZCQUFvQjtBQUNsQztBQUNBLHdCQUF3Qiw2QkFBb0I7QUFDNUMsdUNBQXVDLFNBQUk7QUFDM0M7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2Qix1Q0FBeUI7QUFDdEQ7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQ3hIcUQ7QUFDWTtBQUNEO0FBQzlCO0FBQ0E7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHFCQUFxQiwyQkFBYTtBQUN6QztBQUNBLGNBQWMsNkJBQW9CO0FBQ2xDO0FBQ0Esd0JBQXdCLDZCQUFvQjtBQUM1Qyx3Q0FBd0MsYUFBTTtBQUM5QztBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSx5Q0FBeUMsYUFBTTtBQUMvQztBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0EsNkJBQTZCLHVDQUF5QjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDOztBQzVEaUU7QUFDRDtBQUNsQztBQUNJO0FBQ21CO0FBQ047QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLHNCQUFzQiwyQkFBYTtBQUMxQztBQUNBLGNBQWMsNkJBQW9CO0FBQ2xDO0FBQ0Esd0JBQXdCLDZCQUFvQjtBQUM1QyxzQ0FBc0MsSUFBSTtBQUMxQztBQUNBO0FBQ0EsU0FBUztBQUNULHlDQUF5QyxNQUFNO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsUUFBUSxrQkFBUTtBQUNoQjtBQUNBO0FBQ0EsNkJBQTZCLHVDQUF5QjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxTQUFJLEdBQUcsdUJBQXVCO0FBQ3RFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixTQUFJO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUM7O0FDM0grQztBQUNrQjtBQUNEO0FBQ2hDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLG1CQUFtQiw2REFBYTtBQUN2QztBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsdUJBQXVCO0FBQ3ZEO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDOztBQzdCK0M7QUFDa0I7QUFDRDtBQUNEO0FBQ2xCO0FBQ0g7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTSw2QkFBYyxTQUFTLDZEQUFhO0FBQ2pEO0FBQ0EsbUNBQW1DLDZCQUFjO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHVCQUF1QjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsNkNBQTZDLDZCQUFjO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDOztBQ3hIZ0Q7QUFDaEI7QUFDd0M7QUFDeEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sdUJBQXVCLDJCQUFhO0FBQzNDO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixXQUFLO0FBQ2xDO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsNkJBQTZCLFdBQUs7QUFDbEM7QUFDQTtBQUNBLFNBQVM7QUFDVCw2QkFBNkIsV0FBSztBQUNsQztBQUNBO0FBQ0EsU0FBUztBQUNULDRCQUE0QixXQUFLO0FBQ2pDO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsNEJBQTRCLFdBQUs7QUFDakM7QUFDQTtBQUNBLFNBQVM7QUFDVCw0QkFBNEIsV0FBSztBQUNqQztBQUNBO0FBQ0EsU0FBUztBQUNULHVCQUF1QixXQUFLO0FBQzVCO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsdUJBQXVCLFdBQUs7QUFDNUI7QUFDQTtBQUNBLFNBQVM7QUFDVCx1QkFBdUIsV0FBSztBQUM1QjtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSw2QkFBNkIsdUNBQXlCO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2Isc0NBQXNDLFNBQVM7QUFDL0MsQ0FBQztBQUNELGNBQWM7QUFDZDtBQUNBLENBQUM7QUFDRCxvQzs7QUN0RmlEO0FBQ2dCO0FBQ0Q7QUFDM0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDTyx1QkFBdUIsNkRBQWE7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0M7O0FDaExrQztBQUMrQjtBQUNsQjtBQUNBO0FBQ2E7QUFDSTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNPLHVCQUF1Qiw2REFBYTtBQUMzQztBQUNBO0FBQ0E7QUFDQTtB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O0FBQy9CdEMsUUFBUSxDQUFDQyxJQUFJLENBQUM0QixLQUFLLENBQUNJLE1BQU0sR0FBRyxNQUFNO0FBQ25DakMsUUFBUSxDQUFDQyxJQUFJLENBQUM0QixLQUFLLENBQUNHLEtBQUssR0FBRyxNQUFNO0FBQ2xDaEMsUUFBUSxDQUFDQyxJQUFJLENBQUN1TixVQUFVLENBQUMzTCxLQUFLLENBQUNzTCxNQUFNLEdBQUcsQ0FBQztBQUN6Q25OLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDdU4sVUFBVSxDQUFDM0wsS0FBSyxDQUFDUyxPQUFPLEdBQUcsQ0FBQztBQUMxQ3RDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDdU4sVUFBVSxDQUFDM0wsS0FBSyxDQUFDSSxNQUFNLEdBQUcsTUFBTTtBQUM5Q2pDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDdU4sVUFBVSxDQUFDM0wsS0FBSyxDQUFDRyxLQUFLLEdBQUcsTUFBTTtBQUU3Q1gsbUJBQW1CLENBQUMsWUFBTTtFQUN4QixJQUFNRSxTQUFTLEdBQUd2QixRQUFRLENBQUN3QixhQUFhLENBQUMsS0FBSyxDQUFDO0VBQy9DRCxTQUFTLENBQUNNLEtBQUssQ0FBQ0ksTUFBTSxHQUFHLE1BQU07RUFDL0JWLFNBQVMsQ0FBQ00sS0FBSyxDQUFDRyxLQUFLLEdBQUcsTUFBTTtFQUM5QmhDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDeUIsU0FBUyxHQUFHLEVBQUU7RUFDNUIxQixRQUFRLENBQUNDLElBQUksQ0FBQzRDLFdBQVcsQ0FBQ3RCLFNBQVMsQ0FBQztFQUNwQyxJQUFNOEssSUFBSSxHQUFHa0IsNEJBQVUsQ0FBQ2hNLFNBQVMsQ0FBQztFQUNsQzhLLElBQUksQ0FBQ29CLE1BQU0sZUFBQ2pCLG1CQUFBLENBQUNJLEdBQUcsTUFBRSxDQUFDLENBQUM7QUFDdEIsQ0FBQyxDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL3ZlcnNpb24uanM/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/MTVjNyIsIndlYnBhY2s6Ly9yZWxhYmkvLi9ub2RlX21vZHVsZXMvdG9uZS9idWlsZC9lc20vY29tcG9uZW50L2R5bmFtaWNzL01pZFNpZGVDb21wcmVzc29yLmpzP2RiNTkiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9keW5hbWljcy9NdWx0aWJhbmRDb21wcmVzc29yLmpzP2ZkYmQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvRVEzLmpzPzJmNzMiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9maWx0ZXIvQ29udm9sdmVyLmpzP2VhMTUiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2NvbXBvbmVudC9pbmRleC5qcz8xZDc2Iiwid2VicGFjazovL3JlbGFiaS8uL25vZGVfbW9kdWxlcy90b25lL2J1aWxkL2VzbS9jbGFzc2VzLmpzP2QzYzciLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vbm9kZV9tb2R1bGVzL3RvbmUvYnVpbGQvZXNtL2luZGV4LmpzPzVlNTQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi91dGlsLmpzP2YxZWQiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3JlbGFiaS9jYW52YXMuanM/ZGM5ZCIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvcmVsYWJpL2luZGV4LmpzPzAyZmEiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL2xpYi9vdXRwdXQuanM/M2ZlNSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3NhbXBsZXIuanM/NTk2YiIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL2luc3RydW1lbnRzLmpzP2Y5YTIiLCJ3ZWJwYWNrOi8vcmVsYWJpLy4vc3JjL3VpL0FwcC5qc3g/NDQyYSIsIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvaW5kZXguanN4P2VkMTIiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNvbnN0IHZlcnNpb24gPSBcIjE0LjcuNzdcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXZlcnNpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFib3J0RXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnQWJvcnRFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWJvcnQtZXJyb3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKGluc2VydEVsZW1lbnRJblNldCkgPT4ge1xuICAgIHJldHVybiAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGlucHV0LCBldmVudExpc3RlbmVyXSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQoYWN0aXZlSW5wdXRzW2lucHV0XSwgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLWFjdGl2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZUNvbm5lY3Rpb25zU3RvcmUpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgYXVkaW9Ob2RlUmVuZGVyZXIsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhY3RpdmVJbnB1dHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgYWN0aXZlSW5wdXRzLnB1c2gobmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb05vZGVDb25uZWN0aW9uc1N0b3JlLnNldChhdWRpb05vZGUsIHtcbiAgICAgICAgICAgIGFjdGl2ZUlucHV0cyxcbiAgICAgICAgICAgIG91dHB1dHM6IG5ldyBTZXQoKSxcbiAgICAgICAgICAgIHBhc3NpdmVJbnB1dHM6IG5ldyBXZWFrTWFwKCksXG4gICAgICAgICAgICByZW5kZXJlcjogYXVkaW9Ob2RlUmVuZGVyZXJcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gKGF1ZGlvUGFyYW1Db25uZWN0aW9uc1N0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb1BhcmFtLCBhdWRpb1BhcmFtUmVuZGVyZXIpID0+IHtcbiAgICAgICAgYXVkaW9QYXJhbUNvbm5lY3Rpb25zU3RvcmUuc2V0KGF1ZGlvUGFyYW0sIHsgYWN0aXZlSW5wdXRzOiBuZXcgU2V0KCksIHBhc3NpdmVJbnB1dHM6IG5ldyBXZWFrTWFwKCksIHJlbmRlcmVyOiBhdWRpb1BhcmFtUmVuZGVyZXIgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IEFDVElWRV9BVURJT19OT0RFX1NUT1JFID0gbmV3IFdlYWtTZXQoKTtcbmV4cG9ydCBjb25zdCBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19OT0RFX1NUT1JFID0gbmV3IFdlYWtNYXAoKTtcbmV4cG9ydCBjb25zdCBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQVVESU9fUEFSQU1fU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IENPTlRFWFRfU1RPUkUgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IEVWRU5UX0xJU1RFTkVSUyA9IG5ldyBXZWFrTWFwKCk7XG5leHBvcnQgY29uc3QgQ1lDTEVfQ09VTlRFUlMgPSBuZXcgV2Vha01hcCgpO1xuLy8gVGhpcyBjbHVua3kgbmFtZSBpcyBib3Jyb3dlZCBmcm9tIHRoZSBzcGVjLiA6LSlcbmV4cG9ydCBjb25zdCBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgPSBuZXcgV2Vha01hcCgpO1xuZXhwb3J0IGNvbnN0IE5PREVfVE9fUFJPQ0VTU09SX01BUFMgPSBuZXcgV2Vha01hcCgpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2xvYmFscy5qcy5tYXAiLCJjb25zdCBoYW5kbGVyID0ge1xuICAgIGNvbnN0cnVjdCgpIHtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXI7XG4gICAgfVxufTtcbmV4cG9ydCBjb25zdCBpc0NvbnN0cnVjdGlibGUgPSAoY29uc3RydWN0aWJsZSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KGNvbnN0cnVjdGlibGUsIGhhbmRsZXIpO1xuICAgICAgICBuZXcgcHJveHkoKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtY29uc3RydWN0aWJsZS5qcy5tYXAiLCIvKlxuICogVGhpcyBtYXNzaXZlIHJlZ2V4IHRyaWVzIHRvIGNvdmVyIGFsbCB0aGUgZm9sbG93aW5nIGNhc2VzLlxuICpcbiAqIGltcG9ydCAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgeyBuYW1lZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgeyBuYW1lZEltcG9ydCBhcyByZW5hbWVuZEltcG9ydCB9IGZyb20gJy4vcGF0aCc7XG4gKiBpbXBvcnQgKiBhcyBuYW1lc3BhY2VJbXBvcnQgZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCB7IG5hbWVkSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCB7IG5hbWVkSW1wb3J0IGFzIHJlbmFtZW5kSW1wb3J0IH0gZnJvbSAnLi9wYXRoJztcbiAqIGltcG9ydCBkZWZhdWx0SW1wb3J0LCAqIGFzIG5hbWVzcGFjZUltcG9ydCBmcm9tICcuL3BhdGgnO1xuICovXG5jb25zdCBJTVBPUlRfU1RBVEVNRU5UX1JFR0VYID0gL15pbXBvcnQoPzooPzpbXFxzXStbXFx3XSt8KD86W1xcc10rW1xcd10rW1xcc10qLCk/W1xcc10qXFx7W1xcc10qW1xcd10rKD86W1xcc10rYXNbXFxzXStbXFx3XSspPyg/OltcXHNdKixbXFxzXSpbXFx3XSsoPzpbXFxzXSthc1tcXHNdK1tcXHddKyk/KSpbXFxzXSp9fCg/OltcXHNdK1tcXHddK1tcXHNdKiwpP1tcXHNdKlxcKltcXHNdK2FzW1xcc10rW1xcd10rKVtcXHNdK2Zyb20pPyg/OltcXHNdKikoXCIoW15cIlxcXFxdfFxcXFwuKStcInwnKFteJ1xcXFxdfFxcXFwuKSsnKSg/OltcXHNdKik7Py87IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG5leHBvcnQgY29uc3Qgc3BsaXRJbXBvcnRTdGF0ZW1lbnRzID0gKHNvdXJjZSwgdXJsKSA9PiB7XG4gICAgY29uc3QgaW1wb3J0U3RhdGVtZW50cyA9IFtdO1xuICAgIGxldCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyA9IHNvdXJjZS5yZXBsYWNlKC9eW1xcc10rLywgJycpO1xuICAgIGxldCByZXN1bHQgPSBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cy5tYXRjaChJTVBPUlRfU1RBVEVNRU5UX1JFR0VYKTtcbiAgICB3aGlsZSAocmVzdWx0ICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHVucmVzb2x2ZWRVcmwgPSByZXN1bHRbMV0uc2xpY2UoMSwgLTEpO1xuICAgICAgICBjb25zdCBpbXBvcnRTdGF0ZW1lbnRXaXRoUmVzb2x2ZWRVcmwgPSByZXN1bHRbMF1cbiAgICAgICAgICAgIC5yZXBsYWNlKC8oW1xcc10rKT87PyQvLCAnJylcbiAgICAgICAgICAgIC5yZXBsYWNlKHVucmVzb2x2ZWRVcmwsIG5ldyBVUkwodW5yZXNvbHZlZFVybCwgdXJsKS50b1N0cmluZygpKTtcbiAgICAgICAgaW1wb3J0U3RhdGVtZW50cy5wdXNoKGltcG9ydFN0YXRlbWVudFdpdGhSZXNvbHZlZFVybCk7XG4gICAgICAgIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMuc2xpY2UocmVzdWx0WzBdLmxlbmd0aCkucmVwbGFjZSgvXltcXHNdKy8sICcnKTtcbiAgICAgICAgcmVzdWx0ID0gc291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHMubWF0Y2goSU1QT1JUX1NUQVRFTUVOVF9SRUdFWCk7XG4gICAgfVxuICAgIHJldHVybiBbaW1wb3J0U3RhdGVtZW50cy5qb2luKCc7JyksIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zcGxpdC1pbXBvcnQtc3RhdGVtZW50cy5qcy5tYXAiLCJpbXBvcnQgeyBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGlzQ29uc3RydWN0aWJsZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtY29uc3RydWN0aWJsZSc7XG5pbXBvcnQgeyBzcGxpdEltcG9ydFN0YXRlbWVudHMgfSBmcm9tICcuLi9oZWxwZXJzL3NwbGl0LWltcG9ydC1zdGF0ZW1lbnRzJztcbmNvbnN0IHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzID0gKHBhcmFtZXRlckRlc2NyaXB0b3JzKSA9PiB7XG4gICAgaWYgKHBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQgJiYgIUFycmF5LmlzQXJyYXkocGFyYW1ldGVyRGVzY3JpcHRvcnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBwYXJhbWV0ZXJEZXNjcmlwdG9ycyBwcm9wZXJ0eSBvZiBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBpcyBub3QgYW4gYXJyYXkuJyk7XG4gICAgfVxufTtcbmNvbnN0IHZlcmlmeVByb2Nlc3NvckN0b3IgPSAocHJvY2Vzc29yQ3RvcikgPT4ge1xuICAgIGlmICghaXNDb25zdHJ1Y3RpYmxlKHByb2Nlc3NvckN0b3IpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1RoZSBnaXZlbiB2YWx1ZSBmb3IgcHJvY2Vzc29yQ3RvciBzaG91bGQgYmUgYSBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgaWYgKHByb2Nlc3NvckN0b3IucHJvdG90eXBlID09PSBudWxsIHx8IHR5cGVvZiBwcm9jZXNzb3JDdG9yLnByb3RvdHlwZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGdpdmVuIHZhbHVlIGZvciBwcm9jZXNzb3JDdG9yIHNob3VsZCBoYXZlIGEgcHJvdG90eXBlLicpO1xuICAgIH1cbn07XG5leHBvcnQgY29uc3QgY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGV2YWx1YXRlU291cmNlLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZmV0Y2hTb3VyY2UsIGdldE5hdGl2ZUNvbnRleHQsIGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG9uZ29pbmdSZXF1ZXN0cywgcmVzb2x2ZWRSZXF1ZXN0cywgdGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydCwgd2luZG93KSA9PiB7XG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICByZXR1cm4gKGNvbnRleHQsIG1vZHVsZVVSTCwgb3B0aW9ucyA9IHsgY3JlZGVudGlhbHM6ICdvbWl0JyB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPSByZXNvbHZlZFJlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKHJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgIT09IHVuZGVmaW5lZCAmJiByZXNvbHZlZFJlcXVlc3RzT2ZDb250ZXh0Lmhhcyhtb2R1bGVVUkwpKSB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID0gb25nb2luZ1JlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgaWYgKG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdCA9IG9uZ29pbmdSZXF1ZXN0c09mQ29udGV4dC5nZXQobW9kdWxlVVJMKTtcbiAgICAgICAgICAgIGlmIChwcm9taXNlT2ZPbmdvaW5nUmVxdWVzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHByb21pc2VPZk9uZ29pbmdSZXF1ZXN0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAvLyBCdWcgIzU5OiBTYWZhcmkgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBhdWRpb1dvcmtsZXQgcHJvcGVydHkuXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuYXRpdmVDb250ZXh0LmF1ZGlvV29ya2xldCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IGZldGNoU291cmNlKG1vZHVsZVVSTClcbiAgICAgICAgICAgICAgICAudGhlbigoW3NvdXJjZSwgYWJzb2x1dGVVcmxdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgW2ltcG9ydFN0YXRlbWVudHMsIHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzXSA9IHNwbGl0SW1wb3J0U3RhdGVtZW50cyhzb3VyY2UsIGFic29sdXRlVXJsKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93OlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiAkeyBpbXBvcnRTdGF0ZW1lbnRzIH07XG4gICAgICAgICAgICAgICAgICogKChhLCBiKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgIChhW2JdID0gYVtiXSB8fCBbIF0pLnB1c2goXG4gICAgICAgICAgICAgICAgICogICAgICAgICAoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLCBnbG9iYWwsIHJlZ2lzdGVyUHJvY2Vzc29yLCBzYW1wbGVSYXRlLCBzZWxmLCB3aW5kb3cpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAkeyBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50cyB9XG4gICAgICAgICAgICAgICAgICogICAgICAgICB9XG4gICAgICAgICAgICAgICAgICogICAgICk7XG4gICAgICAgICAgICAgICAgICogfSkod2luZG93LCAnX0FXR1MnKTtcbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4gICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFNvdXJjZSA9IGAke2ltcG9ydFN0YXRlbWVudHN9OygoYSxiKT0+eyhhW2JdPWFbYl18fFtdKS5wdXNoKChBdWRpb1dvcmtsZXRQcm9jZXNzb3IsZ2xvYmFsLHJlZ2lzdGVyUHJvY2Vzc29yLHNhbXBsZVJhdGUsc2VsZix3aW5kb3cpPT57JHtzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c31cbn0pfSkod2luZG93LCdfQVdHUycpYDtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBFdmFsdWF0aW5nIHRoZSBnaXZlbiBzb3VyY2UgY29kZSBpcyBhIHBvc3NpYmxlIHNlY3VyaXR5IHByb2JsZW0uXG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2YWx1YXRlU291cmNlKHdyYXBwZWRTb3VyY2UpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSA9IHdpbmRvdy5fQVdHUy5wb3AoKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZhbHVhdGVBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTgyIENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhbiBpbnN0YW5jZSBvZiBhIFN5bnRheEVycm9yIGluc3RlYWQgb2YgYSBET01FeGNlcHRpb24uXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lLCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGV2YWx1YXRlQXVkaW9Xb3JrbGV0R2xvYmFsU2NvcGUoY2xhc3MgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIHtcbiAgICAgICAgICAgICAgICB9LCB1bmRlZmluZWQsIChuYW1lLCBwcm9jZXNzb3JDdG9yKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID0gTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLmdldChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGVOYW1lVG9Qcm9jZXNzb3JDb25zdHJ1Y3Rvck1hcCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2ZXJpZnlQcm9jZXNzb3JDdG9yKHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UGFyYW1ldGVyRGVzY3JpcHRvcnMocHJvY2Vzc29yQ3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuc2V0KG5hbWUsIHByb2Nlc3NvckN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZ5UHJvY2Vzc29yQ3Rvcihwcm9jZXNzb3JDdG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcmlmeVBhcmFtZXRlckRlc2NyaXB0b3JzKHByb2Nlc3NvckN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgTk9ERV9OQU1FX1RPX1BST0NFU1NPUl9DT05TVFJVQ1RPUl9NQVBTLnNldChuYXRpdmVDb250ZXh0LCBuZXcgTWFwKFtbbmFtZSwgcHJvY2Vzc29yQ3Rvcl1dKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LCBuYXRpdmVDb250ZXh0LnNhbXBsZVJhdGUsIHVuZGVmaW5lZCwgdW5kZWZpbmVkKSk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgOiBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgZmV0Y2hTb3VyY2UobW9kdWxlVVJMKSxcbiAgICAgICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQsIHRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JQb3N0TWVzc2FnZVN1cHBvcnQpKVxuICAgICAgICAgICAgXSkudGhlbigoW1tzb3VyY2UsIGFic29sdXRlVXJsXSwgaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VdKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudEluZGV4ID0gaW5kZXggKyAxO1xuICAgICAgICAgICAgICAgIGluZGV4ID0gY3VycmVudEluZGV4O1xuICAgICAgICAgICAgICAgIGNvbnN0IFtpbXBvcnRTdGF0ZW1lbnRzLCBzb3VyY2VXaXRob3V0SW1wb3J0U3RhdGVtZW50c10gPSBzcGxpdEltcG9ydFN0YXRlbWVudHMoc291cmNlLCBhYnNvbHV0ZVVybCk7XG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgKiBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiBjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgX19idWZmZXJzID0gbmV3IFdlYWtTZXQoKTtcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICBzdXBlcigpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICB0aGlzLnBvcnQucG9zdE1lc3NhZ2UgPSAoKHBvc3RNZXNzYWdlKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgcmV0dXJuIChtZXNzYWdlLCB0cmFuc2ZlcmFibGVzKSA9PiB7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkVHJhbnNmZXJhYmxlcyA9ICh0cmFuc2ZlcmFibGVzKVxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICAgICAgPyB0cmFuc2ZlcmFibGVzLmZpbHRlcigodHJhbnNmZXJhYmxlKSA9PiAhdGhpcy5fX2J1ZmZlcnMuaGFzKHRyYW5zZmVyYWJsZSkpXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgICAgICA6IHRyYW5zZmVyYWJsZXM7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgcmV0dXJuIHBvc3RNZXNzYWdlLmNhbGwodGhpcy5wb3J0LCBtZXNzYWdlLCBmaWx0ZXJlZFRyYW5zZmVyYWJsZXMpO1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgfSkodGhpcy5wb3J0LnBvc3RNZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgfVxuICAgICAgICAgICAgICAgICAqIH1cbiAgICAgICAgICAgICAgICAgKiBgYGBcbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkQXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gaXNTdXBwb3J0aW5nUG9zdE1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgPyAnQXVkaW9Xb3JrbGV0UHJvY2Vzc29yJ1xuICAgICAgICAgICAgICAgICAgICA6ICdjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7X19iPW5ldyBXZWFrU2V0KCk7Y29uc3RydWN0b3IoKXtzdXBlcigpOyhwPT5wLnBvc3RNZXNzYWdlPShxPT4obSx0KT0+cS5jYWxsKHAsbSx0P3QuZmlsdGVyKHU9PiF0aGlzLl9fYi5oYXModSkpOnQpKShwLnBvc3RNZXNzYWdlKSkodGhpcy5wb3J0KX19JztcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTcwOiBDaHJvbWUgYW5kIEVkZ2UgZG8gY2FsbCBwcm9jZXNzKCkgd2l0aCBhbiBhcnJheSB3aXRoIGVtcHR5IGNoYW5uZWxEYXRhIGZvciBlYWNoIGlucHV0IGlmIG5vIGlucHV0IGlzIGNvbm5lY3RlZC5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjMTc5OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRvIHRyYW5zZmVyIGFueSBidWZmZXIgd2hpY2ggaGFzIGJlZW4gcGFzc2VkIHRvIHRoZSBwcm9jZXNzKCkgbWV0aG9kIGFzIGFuIGFyZ3VtZW50LlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogQnVnICMxOTA6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIGVycm9yIHdoZW4gbG9hZGluZyBhbiB1bnBhcnNhYmxlIG1vZHVsZS5cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgdGhlIHVubWluaWZpZWQgdmVyc2lvbiBvZiB0aGUgY29kZSB1c2VkIGJlbG93OlxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogYGBganNcbiAgICAgICAgICAgICAgICAgKiBgJHsgaW1wb3J0U3RhdGVtZW50cyB9O1xuICAgICAgICAgICAgICAgICAqICgoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLCByZWdpc3RlclByb2Nlc3NvcikgPT4geyR7IHNvdXJjZVdpdGhvdXRJbXBvcnRTdGF0ZW1lbnRzIH1cbiAgICAgICAgICAgICAgICAgKiB9KShcbiAgICAgICAgICAgICAgICAgKiAgICAgJHvCoHBhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgfSxcbiAgICAgICAgICAgICAgICAgKiAgICAgKG5hbWUsIHByb2Nlc3NvckN0b3IpID0+IHJlZ2lzdGVyUHJvY2Vzc29yKG5hbWUsIGNsYXNzIGV4dGVuZHMgcHJvY2Vzc29yQ3RvciB7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIF9fY29sbGVjdEJ1ZmZlcnMgPSAoYXJyYXkpID0+IHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgICAgICBhcnJheS5mb3JFYWNoKChlbGVtZW50KSA9PiB0aGlzLl9fYnVmZmVycy5hZGQoZWxlbWVudC5idWZmZXIpKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHByb2Nlc3MgKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykge1xuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgIGlucHV0cy5mb3JFYWNoKHRoaXMuX19jb2xsZWN0QnVmZmVycyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgb3V0cHV0cy5mb3JFYWNoKHRoaXMuX19jb2xsZWN0QnVmZmVycyk7XG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgdGhpcy5fX2NvbGxlY3RCdWZmZXJzKE9iamVjdC52YWx1ZXMocGFyYW1ldGVycykpO1xuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgcmV0dXJuIHN1cGVyLnByb2Nlc3MoXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgICAgIChpbnB1dHMubWFwKChpbnB1dCkgPT4gaW5wdXQuc29tZSgoY2hhbm5lbERhdGEpID0+IGNoYW5uZWxEYXRhLmxlbmd0aCA9PT0gMCkpID8gWyBdIDogaW5wdXQpLFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBvdXRwdXRzLFxuICAgICAgICAgICAgICAgICAqICAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzXG4gICAgICAgICAgICAgICAgICogICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICB9KVxuICAgICAgICAgICAgICAgICAqICk7XG4gICAgICAgICAgICAgICAgICpcbiAgICAgICAgICAgICAgICAgKiByZWdpc3RlclByb2Nlc3NvcihgX19zYWMke2N1cnJlbnRJbmRleH1gLCBjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvcntcbiAgICAgICAgICAgICAgICAgKlxuICAgICAgICAgICAgICAgICAqICAgICBwcm9jZXNzICgpIHtcbiAgICAgICAgICAgICAgICAgKiAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgKiAgICAgfVxuICAgICAgICAgICAgICAgICAqXG4gICAgICAgICAgICAgICAgICogfSlgXG4gICAgICAgICAgICAgICAgICogYGBgXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyRGVmaW5pdGlvbiA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlID8gJycgOiAnX19jID0gKGEpID0+IGEuZm9yRWFjaChlPT50aGlzLl9fYi5hZGQoZS5idWZmZXIpKTsnO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlclJlZ2lzdHJhdGlvbiA9IGlzU3VwcG9ydGluZ1Bvc3RNZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgID8gJydcbiAgICAgICAgICAgICAgICAgICAgOiAnaS5mb3JFYWNoKHRoaXMuX19jKTtvLmZvckVhY2godGhpcy5fX2MpO3RoaXMuX19jKE9iamVjdC52YWx1ZXMocCkpOyc7XG4gICAgICAgICAgICAgICAgY29uc3Qgd3JhcHBlZFNvdXJjZSA9IGAke2ltcG9ydFN0YXRlbWVudHN9OygoQXVkaW9Xb3JrbGV0UHJvY2Vzc29yLHJlZ2lzdGVyUHJvY2Vzc29yKT0+eyR7c291cmNlV2l0aG91dEltcG9ydFN0YXRlbWVudHN9XG59KSgke3BhdGNoZWRBdWRpb1dvcmtsZXRQcm9jZXNzb3J9LChuLHApPT5yZWdpc3RlclByb2Nlc3NvcihuLGNsYXNzIGV4dGVuZHMgcHske21lbWJlckRlZmluaXRpb259cHJvY2VzcyhpLG8scCl7JHtidWZmZXJSZWdpc3RyYXRpb259cmV0dXJuIHN1cGVyLnByb2Nlc3MoaS5tYXAoaj0+ai5zb21lKGs9PmsubGVuZ3RoPT09MCk/W106aiksbyxwKX19KSk7cmVnaXN0ZXJQcm9jZXNzb3IoJ19fc2FjJHtjdXJyZW50SW5kZXh9JyxjbGFzcyBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3Nvcntwcm9jZXNzKCl7cmV0dXJuICExfX0pYDtcbiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3dyYXBwZWRTb3VyY2VdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04JyB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmF1ZGlvV29ya2xldFxuICAgICAgICAgICAgICAgICAgICAuYWRkTW9kdWxlKHVybCwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE4NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCBhbGxvdyB0byBjcmVhdGUgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBvbiBhIGNsb3NlZCBBdWRpb0NvbnRleHQuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBnZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LmF1ZGlvV29ya2xldC5hZGRNb2R1bGUodXJsLCBvcHRpb25zKS50aGVuKCgpID0+IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKChuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MDogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBsb2FkaW5nIGFuIHVucGFyc2FibGUgbW9kdWxlLlxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVDb250ZXh0T3JCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBgX19zYWMke2N1cnJlbnRJbmRleH1gKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpuby11bnVzZWQtZXhwcmVzc2lvblxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAob25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG9uZ29pbmdSZXF1ZXN0cy5zZXQoY29udGV4dCwgbmV3IE1hcChbW21vZHVsZVVSTCwgcHJvbWlzZV1dKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBvbmdvaW5nUmVxdWVzdHNPZkNvbnRleHQuc2V0KG1vZHVsZVVSTCwgcHJvbWlzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcHJvbWlzZVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQgPSByZXNvbHZlZFJlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkUmVzb2x2ZWRSZXF1ZXN0c09mQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWRSZXF1ZXN0cy5zZXQoY29udGV4dCwgbmV3IFNldChbbW9kdWxlVVJMXSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlZFJlc29sdmVkUmVxdWVzdHNPZkNvbnRleHQuYWRkKG1vZHVsZVVSTCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgICAgICAuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ID0gb25nb2luZ1JlcXVlc3RzLmdldChjb250ZXh0KTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB1cGRhdGVkT25nb2luZ1JlcXVlc3RzT2ZDb250ZXh0LmRlbGV0ZShtb2R1bGVVUkwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHByb21pc2U7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtYXVkaW8td29ya2xldC1tb2R1bGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGdldFZhbHVlRm9yS2V5ID0gKG1hcCwga2V5KSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBtYXAuZ2V0KGtleSk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIHZhbHVlIHdpdGggdGhlIGdpdmVuIGtleSBjb3VsZCBub3QgYmUgZm91bmQuJyk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtdmFsdWUtZm9yLWtleS5qcy5tYXAiLCJleHBvcnQgY29uc3QgcGlja0VsZW1lbnRGcm9tU2V0ID0gKHNldCwgcHJlZGljYXRlKSA9PiB7XG4gICAgY29uc3QgbWF0Y2hpbmdFbGVtZW50cyA9IEFycmF5LmZyb20oc2V0KS5maWx0ZXIocHJlZGljYXRlKTtcbiAgICBpZiAobWF0Y2hpbmdFbGVtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIHRocm93IEVycm9yKCdNb3JlIHRoYW4gb25lIGVsZW1lbnQgd2FzIGZvdW5kLicpO1xuICAgIH1cbiAgICBpZiAobWF0Y2hpbmdFbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ05vIGVsZW1lbnQgd2FzIGZvdW5kLicpO1xuICAgIH1cbiAgICBjb25zdCBbbWF0Y2hpbmdFbGVtZW50XSA9IG1hdGNoaW5nRWxlbWVudHM7XG4gICAgc2V0LmRlbGV0ZShtYXRjaGluZ0VsZW1lbnQpO1xuICAgIHJldHVybiBtYXRjaGluZ0VsZW1lbnQ7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGljay1lbGVtZW50LWZyb20tc2V0LmpzLm1hcCIsImltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gZ2V0VmFsdWVGb3JLZXkocGFzc2l2ZUlucHV0cywgc291cmNlKTtcbiAgICBjb25zdCBtYXRjaGluZ0Nvbm5lY3Rpb24gPSBwaWNrRWxlbWVudEZyb21TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQgJiYgcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gaW5wdXQpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuZGVsZXRlKHNvdXJjZSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGluZ0Nvbm5lY3Rpb247XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEVWRU5UX0xJU1RFTkVSUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShFVkVOVF9MSVNURU5FUlMsIGF1ZGlvTm9kZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IEFDVElWRV9BVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICBpZiAoQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQXVkaW9Ob2RlIGlzIGFscmVhZHkgc3RvcmVkLicpO1xuICAgIH1cbiAgICBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRS5hZGQoYXVkaW9Ob2RlKTtcbiAgICBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSkuZm9yRWFjaCgoZXZlbnRMaXN0ZW5lcikgPT4gZXZlbnRMaXN0ZW5lcih0cnVlKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNBdWRpb1dvcmtsZXROb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAncG9ydCcgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIGlmICghQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgQXVkaW9Ob2RlIGlzIG5vdCBzdG9yZWQuJyk7XG4gICAgfVxuICAgIEFDVElWRV9BVURJT19OT0RFX1NUT1JFLmRlbGV0ZShhdWRpb05vZGUpO1xuICAgIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUoYXVkaW9Ob2RlKS5mb3JFYWNoKChldmVudExpc3RlbmVyKSA9PiBldmVudExpc3RlbmVyKGZhbHNlKSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG4vLyBTZXQgdGhlIGludGVybmFsU3RhdGUgb2YgdGhlIGF1ZGlvTm9kZSB0byAncGFzc2l2ZScgaWYgaXQgaXMgbm90IGFuIEF1ZGlvV29ya2xldE5vZGUgYW5kIGlmIGl0IGhhcyBubyAnYWN0aXZlJyBpbnB1dCBjb25uZWN0aW9ucy5cbmV4cG9ydCBjb25zdCBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeSA9IChhdWRpb05vZGUsIGFjdGl2ZUlucHV0cykgPT4ge1xuICAgIGlmICghaXNBdWRpb1dvcmtsZXROb2RlKGF1ZGlvTm9kZSkgJiYgYWN0aXZlSW5wdXRzLmV2ZXJ5KChjb25uZWN0aW9ucykgPT4gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMCkpIHtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZShhdWRpb05vZGUpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZS13aGVuLW5lY2Vzc2FyeS5qcy5tYXAiLCJpbXBvcnQgeyBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2RlbGV0ZS1wYXNzaXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBZGRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAoYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSwgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRBdWRpb05vZGVUYWlsVGltZSwgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBpbnNlcnRFbGVtZW50SW5TZXQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc1BhcnRPZkFDeWNsZSwgaXNQYXNzaXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgdGFpbFRpbWVUaW1lb3V0SWRzID0gbmV3IFdlYWtNYXAoKTtcbiAgICByZXR1cm4gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQsIGlzT2ZmbGluZSkgPT4ge1xuICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZShzb3VyY2UpO1xuICAgICAgICBjb25zdCBldmVudExpc3RlbmVyID0gKGlzQWN0aXZlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc09mZmxpbmUgJiYgIWlzUGFydE9mQUN5Y2xlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoaXNQYXNzaXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCwgaW5wdXQpO1xuICAgICAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShwYXNzaXZlSW5wdXRzLCBpbnB1dCwgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgdGFpbFRpbWUgPSBnZXRBdWRpb05vZGVUYWlsVGltZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgaWYgKHRhaWxUaW1lID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmVXaGVuTmVjZXNzYXJ5KGRlc3RpbmF0aW9uLCBhY3RpdmVJbnB1dHMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0YWlsVGltZVRpbWVvdXRJZCA9IHRhaWxUaW1lVGltZW91dElkcy5nZXQoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGFpbFRpbWVUaW1lb3V0SWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRhaWxUaW1lVGltZW91dElkKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0YWlsVGltZVRpbWVvdXRJZHMuc2V0KGRlc3RpbmF0aW9uLCBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgdGFpbFRpbWUgKiAxMDAwKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoaW5zZXJ0RWxlbWVudEluU2V0KG91dHB1dHMsIFtkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dF0sIChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQgJiYgb3V0cHV0Q29ubmVjdGlvblsyXSA9PT0gaW5wdXQsIHRydWUpKSB7XG4gICAgICAgICAgICBldmVudExpc3RlbmVycy5hZGQoZXZlbnRMaXN0ZW5lcik7XG4gICAgICAgICAgICBpZiAoaXNBY3RpdmVBdWRpb05vZGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGFjdGl2ZUlucHV0cywgc291cmNlLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IChpbnNlcnRFbGVtZW50SW5TZXQpID0+IHtcbiAgICByZXR1cm4gKHBhc3NpdmVJbnB1dHMsIGlucHV0LCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gcGFzc2l2ZUlucHV0cy5nZXQoc291cmNlKTtcbiAgICAgICAgaWYgKHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBhc3NpdmVJbnB1dHMuc2V0KHNvdXJjZSwgbmV3IFNldChbW291dHB1dCwgaW5wdXQsIGV2ZW50TGlzdGVuZXJdXSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zLCBbb3V0cHV0LCBpbnB1dCwgZXZlbnRMaXN0ZW5lcl0sIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQgJiYgcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gaW5wdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUFkZFNpbGVudENvbm5lY3Rpb24gPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSkuY29ubmVjdChuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgY29uc3QgZGlzY29ubmVjdCA9ICgpID0+IHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIGRpc2Nvbm5lY3QpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB9O1xuICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1zaWxlbnQtY29ubmVjdGlvbi5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSAoZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBhdWRpb1dvcmtsZXROb2RlKSA9PiB7XG4gICAgICAgIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVDb250ZXh0KS5hZGQoYXVkaW9Xb3JrbGV0Tm9kZSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hZGQtdW5yZW5kZXJlZC1hdWRpby13b3JrbGV0LW5vZGUuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZmZ0U2l6ZTogMjA0OCxcbiAgICBtYXhEZWNpYmVsczogLTMwLFxuICAgIG1pbkRlY2liZWxzOiAtMTAwLFxuICAgIHNtb290aGluZ1RpbWVDb25zdGFudDogMC44XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvbk5vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBbmFseXNlck5vZGUgZXh0ZW5kcyBhdWRpb25Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgYW5hbHlzZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyKCkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQW5hbHlzZXJOb2RlLCBhbmFseXNlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUgPSBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZmdFNpemUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGZmdFNpemUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mZnRTaXplID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGZyZXF1ZW5jeUJpbkNvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5mcmVxdWVuY3lCaW5Db3VudDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4RGVjaWJlbHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1heERlY2liZWxzO1xuICAgICAgICB9XG4gICAgICAgIHNldCBtYXhEZWNpYmVscyh2YWx1ZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxMTg6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciBpZiBtYXhEZWNpYmVscyBpcyBub3QgbW9yZSB0aGFuIG1pbkRlY2liZWxzLlxuICAgICAgICAgICAgY29uc3QgbWF4RGVjaWJlbHMgPSB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHM7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICghKHZhbHVlID4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyA9IG1heERlY2liZWxzO1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1pbkRlY2liZWxzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscztcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWluRGVjaWJlbHModmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgICAgIGNvbnN0IG1pbkRlY2liZWxzID0gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLm1pbkRlY2liZWxzID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAoISh0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWF4RGVjaWJlbHMgPiB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUubWluRGVjaWJlbHMgPSBtaW5EZWNpYmVscztcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBzbW9vdGhpbmdUaW1lQ29uc3RhbnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQW5hbHlzZXJOb2RlLnNtb290aGluZ1RpbWVDb25zdGFudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgc21vb3RoaW5nVGltZUNvbnN0YW50KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0Qnl0ZUZyZXF1ZW5jeURhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlRnJlcXVlbmN5RGF0YShhcnJheSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGFycmF5KSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBbmFseXNlck5vZGUuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgICAgICBnZXRGbG9hdEZyZXF1ZW5jeURhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdEZyZXF1ZW5jeURhdGEoYXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIGdldEZsb2F0VGltZURvbWFpbkRhdGEoYXJyYXkpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhKGFycmF5KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5hbHlzZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNPd25lZEJ5Q29udGV4dCA9IChuYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlLmNvbnRleHQgPT09IG5hdGl2ZUNvbnRleHQ7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtb3duZWQtYnktY29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVBbmFseXNlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBbmFseXNlck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgY29uc3QgY3JlYXRlQW5hbHlzZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQW5hbHlzZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVBbmFseXNlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBbmFseXNlck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVBbmFseXNlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBbmFseXNlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVBbmFseXNlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBmZnRTaXplOiBuYXRpdmVBbmFseXNlck5vZGUuZmZ0U2l6ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4RGVjaWJlbHM6IG5hdGl2ZUFuYWx5c2VyTm9kZS5tYXhEZWNpYmVscyxcbiAgICAgICAgICAgICAgICAgICAgbWluRGVjaWJlbHM6IG5hdGl2ZUFuYWx5c2VyTm9kZS5taW5EZWNpYmVscyxcbiAgICAgICAgICAgICAgICAgICAgc21vb3RoaW5nVGltZUNvbnN0YW50OiBuYXRpdmVBbmFseXNlck5vZGUuc21vb3RoaW5nVGltZUNvbnN0YW50XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBbmFseXNlck5vZGUgPSBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBbmFseXNlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSA9IHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQW5hbHlzZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUFuYWx5c2VyTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVBbmFseXNlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQgPSAobmF0aXZlQXVkaW9CdWZmZXIpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKG5ldyBGbG9hdDMyQXJyYXkoMSksIDAsIC0xKTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW5kZXhTaXplRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW5kZXhTaXplRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LXNpemUtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW5kZXhTaXplRXJyb3IgfSBmcm9tICcuLi9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvcic7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgPSAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSA9ICgoZ2V0Q2hhbm5lbERhdGEpID0+IHtcbiAgICAgICAgcmV0dXJuIChjaGFubmVsKSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnZXRDaGFubmVsRGF0YS5jYWxsKGF1ZGlvQnVmZmVyLCBjaGFubmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDEyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1idWZmZXItZ2V0LWNoYW5uZWwtZGF0YS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcy1vdXQtb2YtYm91bmRzLXN1cHBvcnQnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLWdldC1jaGFubmVsLWRhdGEtbWV0aG9kJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBudW1iZXJPZkNoYW5uZWxzOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICBsZXQgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG51bGw7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvQnVmZmVyIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB7IGxlbmd0aCwgbnVtYmVyT2ZDaGFubmVscywgc2FtcGxlUmF0ZSB9ID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoMSwgMSwgNDQxMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjOTk6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBOb3RTdXBwb3J0ZWRFcnJvciB3aGVuIHRoZSBudW1iZXJPZkNoYW5uZWxzIGlzIHplcm8uIEJ1dCBpdCBvbmx5IGRvZXMgaXQgd2hlbiB1c2luZyB0aGVcbiAgICAgICAgICAgICAqIGZhY3RvcnkgZnVuY3Rpb24uIEJ1dCBzaW5jZSBGaXJlZm94IGFsc28gc3VwcG9ydHMgdGhlIGNvbnN0cnVjdG9yIGV2ZXJ5dGhpbmcgc2hvdWxkIGJlIGZpbmUuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIGNhY2hlVGVzdFJlc3VsdCh0ZXN0TmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQsIHRlc3ROYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydClcbiAgICAgICAgICAgICAgICA/IG5ldyBuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0pXG4gICAgICAgICAgICAgICAgOiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgLy8gQnVnICM5OTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gdGhlIG51bWJlck9mQ2hhbm5lbHMgaXMgemVyby5cbiAgICAgICAgICAgIGlmIChhdWRpb0J1ZmZlci5udW1iZXJPZkNoYW5uZWxzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgICAgIC8vIEJ1ZyAjMTAwOiBTYWZhcmkgZG9lcyB0aHJvdyBhIHdyb25nIGVycm9yIHdoZW4gY2FsbGluZyBnZXRDaGFubmVsRGF0YSgpIHdpdGggYW4gb3V0LW9mLWJvdW5kcyB2YWx1ZS5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJHZXRDaGFubmVsRGF0YU1ldGhvZChhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNTc6IEZpcmVmb3ggZG9lcyBub3QgYWxsb3cgdGhlIGJ1ZmZlck9mZnNldCB0byBiZSBvdXQtb2YtYm91bmRzLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIFRoaXMgZG9lcyB2aW9sYXRlIGFsbCBnb29kIHByYXRpY2VzIGJ1dCBpdCBpcyBuZWNlc3NhcnkgdG8gYWxsb3cgdGhpcyBBdWRpb0J1ZmZlciB0byBiZSB1c2VkIHdpdGggbmF0aXZlXG4gICAgICAgICAgICAgKiAoT2ZmbGluZSlBdWRpb0NvbnRleHRzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGljIFtTeW1ib2wuaGFzSW5zdGFuY2VdKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gKChpbnN0YW5jZSAhPT0gbnVsbCAmJiB0eXBlb2YgaW5zdGFuY2UgPT09ICdvYmplY3QnICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnN0YW5jZSkgPT09IEF1ZGlvQnVmZmVyLnByb3RvdHlwZSkgfHxcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmhhcyhpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUID0gLTMuNDAyODIzNDY2Mzg1Mjg4NmUzODtcbmV4cG9ydCBjb25zdCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCA9IC1NT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnN0YW50cy5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzQWN0aXZlQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZSkgPT4gQUNUSVZFX0FVRElPX05PREVfU1RPUkUuaGFzKGF1ZGlvTm9kZSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1hY3RpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgaXNBY3RpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLWFjdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLWFjdGl2ZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tcGFzc2l2ZSc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYnVmZmVyOiBudWxsLFxuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgbG9vcDogZmFsc2UsXG4gICAgbG9vcEVuZDogMCxcbiAgICBsb29wU3RhcnQ6IDAsXG4gICAgcGxheWJhY2tSYXRlOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0J1ZmZlclNvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyID0gYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXI7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJTZXQgPSBtZXJnZWRPcHRpb25zLmJ1ZmZlciAhPT0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQgPSBudWxsO1xuICAgICAgICAgICAgLy8gQnVnICM3MzogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlLCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBidWZmZXIoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHNldCBidWZmZXIodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSB2YWx1ZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzI6IE9ubHkgQ2hyb21lICYgRWRnZSBkbyBub3QgYWxsb3cgdG8gcmVhc3NpZ24gdGhlIGJ1ZmZlciB5ZXQuXG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5faXNCdWZmZXJTZXQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5faXNCdWZmZXJTZXQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wO1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wRW5kO1xuICAgICAgICB9XG4gICAgICAgIHNldCBsb29wRW5kKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZCA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3BTdGFydDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbG9vcFN0YXJ0KHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwbGF5YmFja1JhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwLCBvZmZzZXQgPSAwLCBkdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KHdoZW4sIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIuc3RhcnQgPSBkdXJhdGlvbiA9PT0gdW5kZWZpbmVkID8gW3doZW4sIG9mZnNldF0gOiBbd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbl07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2F1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgc3RhcnQgPSBudWxsO1xuICAgICAgICBsZXQgc3RvcCA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBidWZmZXI6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5sb29wLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcEVuZCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcFN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KC4uLnN0YXJ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHN0b3AgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wbGF5YmFja1JhdGUsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5wbGF5YmFja1JhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucGxheWJhY2tSYXRlLCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUucGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBzdGFydCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHN0YXJ0ID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHN0b3AodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdG9wID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpc0F1ZGlvQnVmZmVyU291cmNlTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BsYXliYWNrUmF0ZScgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNCaXF1YWRGaWx0ZXJOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnZnJlcXVlbmN5JyBpbiBhdWRpb05vZGUgJiYgJ2dhaW4nIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQ29uc3RhbnRTb3VyY2VOb2RlID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAnb2Zmc2V0JyBpbiBhdWRpb05vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29uc3RhbnQtc291cmNlLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzR2Fpbk5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICEoJ2ZyZXF1ZW5jeScgaW4gYXVkaW9Ob2RlKSAmJiAnZ2FpbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdhaW4tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNPc2NpbGxhdG9yTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ2RldHVuZScgaW4gYXVkaW9Ob2RlICYmICdmcmVxdWVuY3knIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1vc2NpbGxhdG9yLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzU3RlcmVvUGFubmVyTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gJ3BhbicgaW4gYXVkaW9Ob2RlO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0ZXJlby1wYW5uZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBnZXRWYWx1ZUZvcktleShBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFLCBhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IChhdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX1BBUkFNX0NPTk5FQ1RJT05TX1NUT1JFLCBhdWRpb1BhcmFtKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tcGFyYW0tY29ubmVjdGlvbnMuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlJztcbmltcG9ydCB7IGlzQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4uL2d1YXJkcy9hdWRpby13b3JrbGV0LW5vZGUnO1xuaW1wb3J0IHsgaXNCaXF1YWRGaWx0ZXJOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2JpcXVhZC1maWx0ZXItbm9kZSc7XG5pbXBvcnQgeyBpc0NvbnN0YW50U291cmNlTm9kZSB9IGZyb20gJy4uL2d1YXJkcy9jb25zdGFudC1zb3VyY2Utbm9kZSc7XG5pbXBvcnQgeyBpc0dhaW5Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2dhaW4tbm9kZSc7XG5pbXBvcnQgeyBpc09zY2lsbGF0b3JOb2RlIH0gZnJvbSAnLi4vZ3VhcmRzL29zY2lsbGF0b3Itbm9kZSc7XG5pbXBvcnQgeyBpc1N0ZXJlb1Bhbm5lck5vZGUgfSBmcm9tICcuLi9ndWFyZHMvc3RlcmVvLXBhbm5lci1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4vc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zID0gKGF1ZGlvTm9kZSwgdHJhY2UpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoYXVkaW9Ob2RlKTtcbiAgICBhY3RpdmVJbnB1dHMuZm9yRWFjaCgoY29ubmVjdGlvbnMpID0+IGNvbm5lY3Rpb25zLmZvckVhY2goKFtzb3VyY2VdKSA9PiB7XG4gICAgICAgIGlmICghdHJhY2UuaW5jbHVkZXMoYXVkaW9Ob2RlKSkge1xuICAgICAgICAgICAgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoc291cmNlLCBbLi4udHJhY2UsIGF1ZGlvTm9kZV0pO1xuICAgICAgICB9XG4gICAgfSkpO1xuICAgIGNvbnN0IGF1ZGlvUGFyYW1zID0gaXNBdWRpb0J1ZmZlclNvdXJjZU5vZGUoYXVkaW9Ob2RlKVxuICAgICAgICA/IFtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTQ5OiBTYWZhcmkgZG9lcyBub3QgeWV0IHN1cHBvcnQgdGhlIGRldHVuZSBBdWRpb1BhcmFtLlxuICAgICAgICAgICAgYXVkaW9Ob2RlLnBsYXliYWNrUmF0ZVxuICAgICAgICBdXG4gICAgICAgIDogaXNBdWRpb1dvcmtsZXROb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgID8gQXJyYXkuZnJvbShhdWRpb05vZGUucGFyYW1ldGVycy52YWx1ZXMoKSlcbiAgICAgICAgICAgIDogaXNCaXF1YWRGaWx0ZXJOb2RlKGF1ZGlvTm9kZSlcbiAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuUSwgYXVkaW9Ob2RlLmRldHVuZSwgYXVkaW9Ob2RlLmZyZXF1ZW5jeSwgYXVkaW9Ob2RlLmdhaW5dXG4gICAgICAgICAgICAgICAgOiBpc0NvbnN0YW50U291cmNlTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5vZmZzZXRdXG4gICAgICAgICAgICAgICAgICAgIDogaXNHYWluTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICA/IFthdWRpb05vZGUuZ2Fpbl1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogaXNPc2NpbGxhdG9yTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBbYXVkaW9Ob2RlLmRldHVuZSwgYXVkaW9Ob2RlLmZyZXF1ZW5jeV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGlzU3RlcmVvUGFubmVyTm9kZShhdWRpb05vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gW2F1ZGlvTm9kZS5wYW5dXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogW107XG4gICAgZm9yIChjb25zdCBhdWRpb1BhcmFtIG9mIGF1ZGlvUGFyYW1zKSB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgaWYgKGF1ZGlvUGFyYW1Db25uZWN0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBhdWRpb1BhcmFtQ29ubmVjdGlvbnMuYWN0aXZlSW5wdXRzLmZvckVhY2goKFtzb3VyY2VdKSA9PiBkZWFjdGl2YXRlQWN0aXZlQXVkaW9Ob2RlSW5wdXRDb25uZWN0aW9ucyhzb3VyY2UsIHRyYWNlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZShhdWRpb05vZGUpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBY3RpdmVBdWRpb05vZGVJbnB1dENvbm5lY3Rpb25zIH0gZnJvbSAnLi9kZWFjdGl2YXRlLWFjdGl2ZS1hdWRpby1ub2RlLWlucHV0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBkZWFjdGl2YXRlQXVkaW9HcmFwaCA9IChjb250ZXh0KSA9PiB7XG4gICAgZGVhY3RpdmF0ZUFjdGl2ZUF1ZGlvTm9kZUlucHV0Q29ubmVjdGlvbnMoY29udGV4dC5kZXN0aW5hdGlvbiwgW10pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlYWN0aXZhdGUtYXVkaW8tZ3JhcGguanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzVmFsaWRMYXRlbmN5SGludCA9IChsYXRlbmN5SGludCkgPT4ge1xuICAgIHJldHVybiAobGF0ZW5jeUhpbnQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICB0eXBlb2YgbGF0ZW5jeUhpbnQgPT09ICdudW1iZXInIHx8XG4gICAgICAgICh0eXBlb2YgbGF0ZW5jeUhpbnQgPT09ICdzdHJpbmcnICYmIChsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJyB8fCBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJykpKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy12YWxpZC1sYXRlbmN5LWhpbnQuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgaXNWYWxpZExhdGVuY3lIaW50IH0gZnJvbSAnLi4vaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBjcmVhdGVVbmtub3duRXJyb3IsIG1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQXVkaW9Db250ZXh0IGV4dGVuZHMgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Db250ZXh0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Iob3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTIgU2FmYXJpIGRvZXMgdGhyb3cgYSBTeW50YXhFcnJvciBpZiB0aGUgc2FtcGxlUmF0ZSBpcyBub3Qgc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIgJiYgZXJyLm1lc3NhZ2UgPT09ICdzYW1wbGVSYXRlIGlzIG5vdCBpbiByYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxMzEgU2FmYXJpIHJldHVybnMgbnVsbCB3aGVuIHRoZXJlIGFyZSBmb3VyIG90aGVyIEF1ZGlvQ29udGV4dHMgcnVubmluZyBhbHJlYWR5LlxuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZVVua25vd25FcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM1MSBPbmx5IENocm9tZSBhbmQgRWRnZSB0aHJvdyBhbiBlcnJvciBpZiB0aGUgZ2l2ZW4gbGF0ZW5jeUhpbnQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgIGlmICghaXNWYWxpZExhdGVuY3lIaW50KG9wdGlvbnMubGF0ZW5jeUhpbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgVGhlIHByb3ZpZGVkIHZhbHVlICcke29wdGlvbnMubGF0ZW5jeUhpbnR9JyBpcyBub3QgYSB2YWxpZCBlbnVtIHZhbHVlIG9mIHR5cGUgQXVkaW9Db250ZXh0TGF0ZW5jeUNhdGVnb3J5LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICMxNTAgU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgc2V0dGluZyB0aGUgc2FtcGxlUmF0ZS5cbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNhbXBsZVJhdGUgIT09IHVuZGVmaW5lZCAmJiBuYXRpdmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSAhPT0gb3B0aW9ucy5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvQ29udGV4dCwgMik7XG4gICAgICAgICAgICBjb25zdCB7IGxhdGVuY3lIaW50IH0gPSBvcHRpb25zO1xuICAgICAgICAgICAgY29uc3QgeyBzYW1wbGVSYXRlIH0gPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBAdG9kbyBUaGUgdmFsdWVzIGZvciAnYmFsYW5jZWQnLCAnaW50ZXJhY3RpdmUnIGFuZCAncGxheWJhY2snIGFyZSBqdXN0IGNvcGllZCBmcm9tIENocm9tZSdzIGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgICAgdGhpcy5fYmFzZUxhdGVuY3kgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3kgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgICAgICAgID8gbmF0aXZlQXVkaW9Db250ZXh0LmJhc2VMYXRlbmN5XG4gICAgICAgICAgICAgICAgICAgIDogbGF0ZW5jeUhpbnQgPT09ICdiYWxhbmNlZCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gNTEyIC8gc2FtcGxlUmF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2ludGVyYWN0aXZlJyB8fCBsYXRlbmN5SGludCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAyNTYgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ3BsYXliYWNrJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDEwMjQgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogLypcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBAdG9kbyBUaGUgbWluICgyNTYpIGFuZCBtYXggKDE2Mzg0KSB2YWx1ZXMgYXJlIHRha2VuIGZyb20gdGhlIGFsbG93ZWQgYnVmZmVyU2l6ZSB2YWx1ZXMgb2YgYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIFNjcmlwdFByb2Nlc3Nvck5vZGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTWF0aC5tYXgoMiwgTWF0aC5taW4oMTI4LCBNYXRoLnJvdW5kKChsYXRlbmN5SGludCAqIHNhbXBsZVJhdGUpIC8gMTI4KSkpICogMTI4KSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQgPSBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICAvLyBCdWcgIzE4ODogU2FmYXJpIHdpbGwgc2V0IHRoZSBjb250ZXh0J3Mgc3RhdGUgdG8gJ2ludGVycnVwdGVkJyBpbiBjYXNlIHRoZSB1c2VyIHN3aXRjaGVzIHRhYnMuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWUgPSAxZS0zNztcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5jb25uZWN0KHRoaXMuX25hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICMzNDogQ2hyb21lIGFuZCBFZGdlIHByZXRlbmQgdG8gYmUgcnVubmluZyByaWdodCBhd2F5LCBidXQgZmlyZSBhbiBvbnN0YXRlY2hhbmdlIGV2ZW50IHdoZW4gdGhlIHN0YXRlIGFjdHVhbGx5IGNoYW5nZXNcbiAgICAgICAgICAgICAqIHRvICdydW5uaW5nJy5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAnc3VzcGVuZGVkJztcbiAgICAgICAgICAgICAgICBjb25zdCByZXZva2VTdGF0ZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dC5hZGRFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJldm9rZVN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgYmFzZUxhdGVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUxhdGVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlICE9PSBudWxsID8gdGhpcy5fc3RhdGUgOiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2UoKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzM1OiBGaXJlZm94IGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBBdWRpb0NvbnRleHQgd2FzIGNsb3NlZCBiZWZvcmUuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ2Nsb3NlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzM0OiBJZiB0aGUgc3RhdGUgd2FzIHNldCB0byBzdXNwZW5kZWQgYmVmb3JlIGl0IHNob3VsZCBiZSByZXZva2VkIG5vdy5cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmNsb3NlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX25hdGl2ZUdhaW5Ob2RlICE9PSBudWxsICYmIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKG1lZGlhRWxlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhRWxlbWVudCB9KTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2UobWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgbWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzLCB7IG1lZGlhU3RyZWFtIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZU1lZGlhU3RyZWFtVHJhY2tTb3VyY2UobWVkaWFTdHJlYW1UcmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IodGhpcywgeyBtZWRpYVN0cmVhbVRyYWNrIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VtZSgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3N1c3BlbmRlZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZlUHJvbWlzZSA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyKCdzdGF0ZWNoYW5nZScsIHJlc29sdmVQcm9taXNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3RhdGUgPT09ICdydW5uaW5nJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVzdW1lKCkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuYWRkRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnJlc3VtZSgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU1OiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gSW52YWxpZEFjY2Vzc0Vycm9yIGluc3RlYWQgb2YgYW4gSW52YWxpZFN0YXRlRXJyb3IuXG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NjogU2FmYXJpIGludm9rZXMgdGhlIGNhdGNoIGhhbmRsZXIgYnV0IHdpdGhvdXQgYW4gZXJyb3IuXG4gICAgICAgICAgICAgICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkIHx8IGVyci5jb2RlID09PSAxNSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBzdXNwZW5kKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdXNwZW5kKCkuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgY2hhbm5lbENvdW50KSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpc09mZmxpbmUpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlcihyZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgOiBudWxsKSk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gaXNPZmZsaW5lO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzUyOiBDaHJvbWUsIEVkZ2UgJiBTYWZhcmkgZG8gbm90IHRocm93IGFuIGV4Y2VwdGlvbiBhdCBhbGwuXG4gICAgICAgICAgICAvLyBCdWcgIzU0OiBGaXJlZm94IGRvZXMgdGhyb3cgYW4gSW5kZXhTaXplRXJyb3IuXG4gICAgICAgICAgICBpZiAodGhpcy5faXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZG9lcyBub3QgaW5pdGlhbGl6ZSB0aGUgbWF4Q2hhbm5lbENvdW50IHByb3BlcnR5IGNvcnJlY3RseS5cbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IHRoaXMuX25hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzUzOiBObyBicm93c2VyIGRvZXMgdGhyb3cgYW4gZXhjZXB0aW9uIHlldC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9pc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtYXhDaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUubWF4Q2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0Rlc3RpbmF0aW9uTm9kZVJlbmRlcmVyID0gKHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgIGNvbnN0IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbjtcbiAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlO1xuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb0xpc3RlbmVyRmFjdG9yeSA9IChjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZ2V0Rmlyc3RTYW1wbGUsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3ZlcndyaXRlQWNjZXNzb3JzKSA9PiB7XG4gICAgcmV0dXJuIChjb250ZXh0LCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUxpc3RlbmVyID0gbmF0aXZlQ29udGV4dC5saXN0ZW5lcjtcbiAgICAgICAgLy8gQnVnICMxMTc6IE9ubHkgQ2hyb21lICYgRWRnZSBzdXBwb3J0IHRoZSBuZXcgaW50ZXJmYWNlIGFscmVhZHkuXG4gICAgICAgIGNvbnN0IGNyZWF0ZUZha2VBdWRpb1BhcmFtcyA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoMSk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgbGV0IGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBsYXN0T3JpZW50YXRpb24gPSBbMCwgMCwgLTEsIDAsIDEsIDBdO1xuICAgICAgICAgICAgbGV0IGxhc3RQb3NpdGlvbiA9IFswLCAwLCAwXTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzU2NyaXB0UHJvY2Vzc29yTm9kZUNyZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpc1NjcmlwdFByb2Nlc3Nvck5vZGVDcmVhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCAyNTYsIDksIDApO1xuICAgICAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUub25hdWRpb3Byb2Nlc3MgPSAoeyBpbnB1dEJ1ZmZlciB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMCksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCAxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMyksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDUpXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcmllbnRhdGlvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0T3JpZW50YXRpb24oLi4ub3JpZW50YXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNiksXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRGaXJzdFNhbXBsZShpbnB1dEJ1ZmZlciwgYnVmZmVyLCA3KSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDgpXG4gICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdG9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RQb3NpdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVMaXN0ZW5lci5zZXRQb3NpdGlvbiguLi5wb3NpdG9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTZXRPcmllbnRhdGlvbiA9IChpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBsYXN0T3JpZW50YXRpb25baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbltpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0T3JpZW50YXRpb24oLi4ubGFzdE9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVTZXRQb3NpdGlvbiA9IChpbmRleCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSB7XG4gICAgICAgICAgICAgICAgICAgIGxhc3RQb3NpdGlvbltpbmRleF0gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlTGlzdGVuZXIuc2V0UG9zaXRpb24oLi4ubGFzdFBvc2l0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCBjcmVhdGVGYWtlQXVkaW9QYXJhbSA9IChpbnB1dCwgaW5pdGlhbFZhbHVlLCBzZXRWYWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGluaXRpYWxWYWx1ZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCBpbnB1dCk7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVGhpcyBzaG91bGQgYmUgc3RvcHBlZCB3aGVuIHRoZSBjb250ZXh0IGlzIGNsb3NlZC5cbiAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCwgJ2RlZmF1bHRWYWx1ZScsIHtcbiAgICAgICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICM2MiAmICM3NDogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgQ29uc3RhbnRTb3VyY2VOb2RlcyBhbmQgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kXG4gICAgICAgICAgICAgICAgICogbWluVmFsdWUgZm9yIEdhaW5Ob2Rlcy5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBhdWRpb1BhcmFtID0gY3JlYXRlQXVkaW9QYXJhbSh7IGNvbnRleHQgfSwgaXNPZmZsaW5lLCBjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhhdWRpb1BhcmFtLCAndmFsdWUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChhdWRpb1BhcmFtKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQuY2FsbChhdWRpb1BhcmFtLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlICE9PSA5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVNjcmlwdFByb2Nlc3Nvck5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxMTc6IFVzaW5nIHNldE9yaWVudGF0aW9uKCkgYW5kIHNldFBvc2l0aW9uKCkgZG9lc24ndCB3b3JrIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFZhbHVlKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSA9ICgoY2FuY2VsQW5kSG9sZEF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjYW5jZWxBbmRIb2xkQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMgPSAoKGNhbmNlbFNjaGVkdWxlZFZhbHVlcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSA9ICgoZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSA9ICgobGluZWFyUmFtcFRvVmFsdWVBdFRpbWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUgPSAoKHNldFRhcmdldEF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRUYXJnZXRBdFRpbWUuYXBwbHkoYXVkaW9QYXJhbSwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVTY3JpcHRQcm9jZXNzb3JOb2RlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoYXVkaW9QYXJhbS5zZXRUYXJnZXRBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUgPSAoKHNldFZhbHVlQXRUaW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHNldFZhbHVlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUpO1xuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSA9ICgoc2V0VmFsdWVDdXJ2ZUF0VGltZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzZXRWYWx1ZUN1cnZlQXRUaW1lLmFwcGx5KGF1ZGlvUGFyYW0sIGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlU2NyaXB0UHJvY2Vzc29yTm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0pKGF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmb3J3YXJkWDogY3JlYXRlRmFrZUF1ZGlvUGFyYW0oMCwgMCwgY3JlYXRlU2V0T3JpZW50YXRpb24oMCkpLFxuICAgICAgICAgICAgICAgIGZvcndhcmRZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgxLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigxKSksXG4gICAgICAgICAgICAgICAgZm9yd2FyZFo6IGNyZWF0ZUZha2VBdWRpb1BhcmFtKDIsIC0xLCBjcmVhdGVTZXRPcmllbnRhdGlvbigyKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25YOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg2LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigwKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg3LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigxKSksXG4gICAgICAgICAgICAgICAgcG9zaXRpb25aOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg4LCAwLCBjcmVhdGVTZXRQb3NpdGlvbigyKSksXG4gICAgICAgICAgICAgICAgdXBYOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSgzLCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbigzKSksXG4gICAgICAgICAgICAgICAgdXBZOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg0LCAxLCBjcmVhdGVTZXRPcmllbnRhdGlvbig0KSksXG4gICAgICAgICAgICAgICAgdXBaOiBjcmVhdGVGYWtlQXVkaW9QYXJhbSg1LCAwLCBjcmVhdGVTZXRPcmllbnRhdGlvbig1KSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHsgZm9yd2FyZFgsIGZvcndhcmRZLCBmb3J3YXJkWiwgcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWiwgdXBYLCB1cFksIHVwWiB9ID0gbmF0aXZlTGlzdGVuZXIuZm9yd2FyZFggPT09IHVuZGVmaW5lZCA/IGNyZWF0ZUZha2VBdWRpb1BhcmFtcygpIDogbmF0aXZlTGlzdGVuZXI7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBnZXQgZm9yd2FyZFgoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZvcndhcmRYO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBmb3J3YXJkWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZm9yd2FyZFk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGZvcndhcmRaKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmb3J3YXJkWjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25YKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvblg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25ZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgdXBYKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1cFg7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHVwWSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdXBZO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCB1cFooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVwWjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLWxpc3RlbmVyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzQXVkaW9Ob2RlID0gKGF1ZGlvTm9kZU9yQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAnY29udGV4dCcgaW4gYXVkaW9Ob2RlT3JBdWRpb1BhcmFtO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGUgfSBmcm9tICcuL2F1ZGlvLW5vZGUnO1xuZXhwb3J0IGNvbnN0IGlzQXVkaW9Ob2RlT3V0cHV0Q29ubmVjdGlvbiA9IChvdXRwdXRDb25uZWN0aW9uKSA9PiB7XG4gICAgcmV0dXJuIGlzQXVkaW9Ob2RlKG91dHB1dENvbm5lY3Rpb25bMF0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWF1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24uanMubWFwIiwiZXhwb3J0IGNvbnN0IGluc2VydEVsZW1lbnRJblNldCA9IChzZXQsIGVsZW1lbnQsIHByZWRpY2F0ZSwgaWdub3JlRHVwbGljYXRlcykgPT4ge1xuICAgIGZvciAoY29uc3QgbG1udCBvZiBzZXQpIHtcbiAgICAgICAgaWYgKHByZWRpY2F0ZShsbW50KSkge1xuICAgICAgICAgICAgaWYgKGlnbm9yZUR1cGxpY2F0ZXMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBFcnJvcignVGhlIHNldCBjb250YWlucyBhdCBsZWFzdCBvbmUgc2ltaWxhciBlbGVtZW50LicpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldC5hZGQoZWxlbWVudCk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5zZXJ0LWVsZW1lbnQtaW4tc2V0LmpzLm1hcCIsImltcG9ydCB7IGluc2VydEVsZW1lbnRJblNldCB9IGZyb20gJy4vaW5zZXJ0LWVsZW1lbnQtaW4tc2V0JztcbmV4cG9ydCBjb25zdCBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0gPSAoYWN0aXZlSW5wdXRzLCBzb3VyY2UsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgaW5zZXJ0RWxlbWVudEluU2V0KGFjdGl2ZUlucHV0cywgW3NvdXJjZSwgb3V0cHV0LCBldmVudExpc3RlbmVyXSwgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbikgPT4gYWN0aXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBzb3VyY2UgJiYgYWN0aXZlSW5wdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIGlnbm9yZUR1cGxpY2F0ZXMpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFkZC1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5leHBvcnQgY29uc3QgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChwYXNzaXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCBpZ25vcmVEdXBsaWNhdGVzKSA9PiB7XG4gICAgY29uc3QgcGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMgPSBwYXNzaXZlSW5wdXRzLmdldChzb3VyY2UpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuc2V0KHNvdXJjZSwgbmV3IFNldChbW291dHB1dCwgZXZlbnRMaXN0ZW5lcl1dKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpbnNlcnRFbGVtZW50SW5TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIFtvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCAocGFzc2l2ZUlucHV0Q29ubmVjdGlvbikgPT4gcGFzc2l2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gb3V0cHV0LCBpZ25vcmVEdXBsaWNhdGVzKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNOYXRpdmVBdWRpb05vZGVGYWtlciA9IChuYXRpdmVBdWRpb05vZGVPck5hdGl2ZUF1ZGlvTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuICdpbnB1dHMnIGluIG5hdGl2ZUF1ZGlvTm9kZU9yTmF0aXZlQXVkaW9Ob2RlRmFrZXI7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXIuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5leHBvcnQgY29uc3QgY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSwgbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSkpIHtcbiAgICAgICAgY29uc3QgZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUuaW5wdXRzW2lucHV0XTtcbiAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QoZmFrZU5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIDApO1xuICAgICAgICByZXR1cm4gW2Zha2VOYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCAwXTtcbiAgICB9XG4gICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXQpO1xuICAgIHJldHVybiBbbmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUsIG91dHB1dCwgaW5wdXRdO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IChhY3RpdmVJbnB1dENvbm5lY3Rpb25zLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIGZvciAoY29uc3QgYWN0aXZlSW5wdXRDb25uZWN0aW9uIG9mIGFjdGl2ZUlucHV0Q29ubmVjdGlvbnMpIHtcbiAgICAgICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSB7XG4gICAgICAgICAgICBhY3RpdmVJbnB1dENvbm5lY3Rpb25zLmRlbGV0ZShhY3RpdmVJbnB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgcmV0dXJuIGFjdGl2ZUlucHV0Q29ubmVjdGlvbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24uanMubWFwIiwiaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9waWNrLWVsZW1lbnQtZnJvbS1zZXQnO1xuZXhwb3J0IGNvbnN0IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KSA9PiB7XG4gICAgcmV0dXJuIHBpY2tFbGVtZW50RnJvbVNldChhY3RpdmVJbnB1dHMsIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0uanMubWFwIiwiaW1wb3J0IHsgZ2V0RXZlbnRMaXN0ZW5lcnNPZkF1ZGlvTm9kZSB9IGZyb20gJy4vZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUgPSAoYXVkaW9Ob2RlLCBldmVudExpc3RlbmVyKSA9PiB7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKGF1ZGlvTm9kZSk7XG4gICAgaWYgKCFldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnRMaXN0ZW5lcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBleHBlY3RlZCBldmVudCBsaXN0ZW5lci4nKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5pbXBvcnQgeyBwaWNrRWxlbWVudEZyb21TZXQgfSBmcm9tICcuL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5leHBvcnQgY29uc3QgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSA9IChwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb25zID0gZ2V0VmFsdWVGb3JLZXkocGFzc2l2ZUlucHV0cywgc291cmNlKTtcbiAgICBjb25zdCBtYXRjaGluZ0Nvbm5lY3Rpb24gPSBwaWNrRWxlbWVudEZyb21TZXQocGFzc2l2ZUlucHV0Q29ubmVjdGlvbnMsIChwYXNzaXZlSW5wdXRDb25uZWN0aW9uKSA9PiBwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzBdID09PSBvdXRwdXQpO1xuICAgIGlmIChwYXNzaXZlSW5wdXRDb25uZWN0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgIHBhc3NpdmVJbnB1dHMuZGVsZXRlKHNvdXJjZSk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGluZ0Nvbm5lY3Rpb247XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmV4cG9ydCBjb25zdCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSA9IChuYXRpdmVTb3VyY2VBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlRGVzdGluYXRpb25BdWRpb05vZGUpKSB7XG4gICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLmlucHV0c1tpbnB1dF0sIG91dHB1dCwgMCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBuYXRpdmVTb3VyY2VBdWRpb05vZGUuZGlzY29ubmVjdChuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5pbXBvcnQgeyBnZXRWYWx1ZUZvcktleSB9IGZyb20gJy4vZ2V0LXZhbHVlLWZvci1rZXknO1xuZXhwb3J0IGNvbnN0IGdldE5hdGl2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkoQVVESU9fTk9ERV9TVE9SRSwgYXVkaW9Ob2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgQVVESU9fUEFSQU1fU1RPUkUgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGdldFZhbHVlRm9yS2V5IH0gZnJvbSAnLi9nZXQtdmFsdWUtZm9yLWtleSc7XG5leHBvcnQgY29uc3QgZ2V0TmF0aXZlQXVkaW9QYXJhbSA9IChhdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIGdldFZhbHVlRm9yS2V5KEFVRElPX1BBUkFNX1NUT1JFLCBhdWRpb1BhcmFtKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IENZQ0xFX0NPVU5URVJTIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgaXNQYXJ0T2ZBQ3ljbGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIENZQ0xFX0NPVU5URVJTLmhhcyhhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBhcnQtb2YtYS1jeWNsZS5qcy5tYXAiLCJpbXBvcnQgeyBBQ1RJVkVfQVVESU9fTk9ERV9TVE9SRSB9IGZyb20gJy4uL2dsb2JhbHMnO1xuZXhwb3J0IGNvbnN0IGlzUGFzc2l2ZUF1ZGlvTm9kZSA9IChhdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gIUFDVElWRV9BVURJT19OT0RFX1NUT1JFLmhhcyhhdWRpb05vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLXBhc3NpdmUtYXVkaW8tbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2RTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIFRoaXMgYnVnIGV4aXN0ZWQgaW4gU2FmYXJpIHVwIHVudGlsIHYxNC4wLjIuIFNpbmNlIEF1ZGlvV29ya2xldHMgd2VyZSBub3Qgc3VwcG9ydGVkIGluIFNhZmFyaSB1bnRpbCB2MTQuMSB0aGUgcHJlc2VuY2Ugb2YgdGhlXG4gICAgICAgICAqIGNvbnN0cnVjdG9yIGZvciBhbiBBdWRpb1dvcmtsZXROb2RlIGNhbiBiZSB1c2VkIGhlcmUgdG8gc2tpcCB0aGUgdGVzdC5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhbmFseXplciA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVTY3JpcHRQcm9jZXNzb3IoMjU2LCAxLCAxKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxuICAgICAgICAgICAgY29uc3QgZHVtbXkgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgLy8gQnVnICM5NTogU2FmYXJpIGRvZXMgbm90IHBsYXkgb25lIHNhbXBsZSBidWZmZXJzLlxuICAgICAgICAgICAgY29uc3Qgb25lcyA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMiwgNDQxMDApO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBvbmVzLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAgICAgY2hhbm5lbERhdGFbMF0gPSAxO1xuICAgICAgICAgICAgY2hhbm5lbERhdGFbMV0gPSAxO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICAgICAgc291cmNlLmJ1ZmZlciA9IG9uZXM7XG4gICAgICAgICAgICBzb3VyY2UubG9vcCA9IHRydWU7XG4gICAgICAgICAgICBzb3VyY2UuY29ubmVjdChhbmFseXplcikuY29ubmVjdChuYXRpdmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgc291cmNlLmNvbm5lY3QoZHVtbXkpO1xuICAgICAgICAgICAgc291cmNlLmRpc2Nvbm5lY3QoZHVtbXkpO1xuICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgICAgICBhbmFseXplci5vbmF1ZGlvcHJvY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNobm5sRHQgPSBldmVudC5pbnB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZSBkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5wcm90b3R5cGUuc29tZS5jYWxsKGNobm5sRHQsIChzYW1wbGUpID0+IHNhbXBsZSA9PT0gMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3RvcCgpO1xuICAgICAgICAgICAgICAgIGFuYWx5emVyLm9uYXVkaW9wcm9jZXNzID0gbnVsbDsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgIHNvdXJjZS5kaXNjb25uZWN0KGFuYWx5emVyKTtcbiAgICAgICAgICAgICAgICBhbmFseXplci5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc291cmNlLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLW5vZGUtZGlzY29ubmVjdC1tZXRob2Qtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZSA9IChjeWNsZXMsIHZpc2l0b3IpID0+IHtcbiAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwKCk7XG4gICAgZm9yIChjb25zdCBjeWNsZSBvZiBjeWNsZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBhdWRpb05vZGUgb2YgY3ljbGUpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gY291bnRzLmdldChhdWRpb05vZGUpO1xuICAgICAgICAgICAgY291bnRzLnNldChhdWRpb05vZGUsIGNvdW50ID09PSB1bmRlZmluZWQgPyAxIDogY291bnQgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb3VudHMuZm9yRWFjaCgoY291bnQsIGF1ZGlvTm9kZSkgPT4gdmlzaXRvcihhdWRpb05vZGUsIGNvdW50KSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UuanMubWFwIiwiZXhwb3J0IGNvbnN0IGlzTmF0aXZlQXVkaW9Ob2RlID0gKG5hdGl2ZUF1ZGlvTm9kZU9yQXVkaW9QYXJhbSkgPT4ge1xuICAgIHJldHVybiAnY29udGV4dCcgaW4gbmF0aXZlQXVkaW9Ob2RlT3JBdWRpb1BhcmFtO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCB3cmFwQXVkaW9Ob2RlRGlzY29ubmVjdE1ldGhvZCA9IChuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdCA9ICgoY29ubmVjdCkgPT4ge1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkIG5vLWluZmVycmFibGUtdHlwZXNcbiAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSA/IGNvbm5lY3QoZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpIDogY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICAgICAgICAgIC8vIFNhdmUgdGhlIG5ldyBjb25uZWN0aW9uIG9ubHkgaWYgdGhlIGNhbGxzIHRvIGNvbm5lY3QgYWJvdmUgZGlkbid0IHRocm93IGFuIGVycm9yLlxuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID0gY29ubmVjdGlvbnMuZ2V0KGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgIGlmIChjb25uZWN0aW9uc1RvRGVzdGluYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbiwgW3sgaW5wdXQsIG91dHB1dCB9XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uLmV2ZXJ5KChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLmlucHV0ICE9PSBpbnB1dCB8fCBjb25uZWN0aW9uLm91dHB1dCAhPT0gb3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24ucHVzaCh7IGlucHV0LCBvdXRwdXQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0LmJpbmQobmF0aXZlQXVkaW9Ob2RlKSk7XG4gICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QgPSAoKGRpc2Nvbm5lY3QpID0+IHtcbiAgICAgICAgcmV0dXJuIChkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KSA9PiB7XG4gICAgICAgICAgICBkaXNjb25uZWN0LmFwcGx5KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2Rlc3RpbmF0aW9uLCBjb25uZWN0aW9uc1RvRGVzdGluYXRpb25dIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQ29ubmVjdGlvbnMgPSBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZmlsdGVyKChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLm91dHB1dCAhPT0gZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJlZENvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLnNldChkZXN0aW5hdGlvbiwgZmlsdGVyZWRDb25uZWN0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb25uZWN0aW9ucy5oYXMoZGVzdGluYXRpb25Pck91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uID0gY29ubmVjdGlvbnMuZ2V0KGRlc3RpbmF0aW9uT3JPdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQ29ubmVjdGlvbnMgPSBjb25uZWN0aW9uc1RvRGVzdGluYXRpb24uZmlsdGVyKChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uLm91dHB1dCAhPT0gb3V0cHV0ICYmIChjb25uZWN0aW9uLmlucHV0ICE9PSBpbnB1dCB8fCBpbnB1dCA9PT0gdW5kZWZpbmVkKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRDb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5kZWxldGUoZGVzdGluYXRpb25Pck91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0aW9ucy5zZXQoZGVzdGluYXRpb25Pck91dHB1dCwgZmlsdGVyZWRDb25uZWN0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtkZXN0aW5hdGlvbiwgY29ubmVjdGlvbnNUb0Rlc3RpbmF0aW9uXSBvZiBjb25uZWN0aW9ucykge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zVG9EZXN0aW5hdGlvbi5mb3JFYWNoKChjb25uZWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KGRlc3RpbmF0aW9uLCBjb25uZWN0aW9uLm91dHB1dCwgY29ubmVjdGlvbi5pbnB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgY29ubmVjdGlvbi5vdXRwdXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZC5qcy5tYXAiLCJpbXBvcnQgeyBBVURJT19OT0RFX1NUT1JFLCBFVkVOVF9MSVNURU5FUlMgfSBmcm9tICcuLi9nbG9iYWxzJztcbmltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvYWRkLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtdG8tbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24nO1xuaW1wb3J0IHsgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9kZWxldGUtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZGVsZXRlLXBhc3NpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvZGlzY29ubmVjdC1uYXRpdmUtYXVkaW8tbm9kZS1mcm9tLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2dldC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtZXZlbnQtbGlzdGVuZXJzLW9mLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9QYXJhbSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LW5hdGl2ZS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBpbnNlcnRFbGVtZW50SW5TZXQgfSBmcm9tICcuLi9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNQYXJ0T2ZBQ3ljbGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXBhcnQtb2YtYS1jeWNsZSc7XG5pbXBvcnQgeyBpc1Bhc3NpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2lzLXBhc3NpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZVdoZW5OZWNlc3NhcnkgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlLXdoZW4tbmVjZXNzYXJ5JztcbmltcG9ydCB7IHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hdWRpby1ub2RlLWRpc2Nvbm5lY3QtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZSB9IGZyb20gJy4uL2hlbHBlcnMvdmlzaXQtZWFjaC1hdWRpby1ub2RlLW9uY2UnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvTm9kZURpc2Nvbm5lY3RNZXRob2QgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tbm9kZS1kaXNjb25uZWN0LW1ldGhvZCc7XG5jb25zdCBhZGRDb25uZWN0aW9uVG9BdWRpb1BhcmFtT2ZBdWRpb0NvbnRleHQgPSAoc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpc09mZmxpbmUpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGRlc3RpbmF0aW9uKTtcbiAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBnZXRFdmVudExpc3RlbmVyc09mQXVkaW9Ob2RlKHNvdXJjZSk7XG4gICAgY29uc3QgZXZlbnRMaXN0ZW5lciA9IChpc0FjdGl2ZSkgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKTtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pO1xuICAgICAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgICAgICAgICBhZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0oYWN0aXZlSW5wdXRzLCBzb3VyY2UsIHBhcnRpYWxDb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsQ29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgICAgIGFkZFBhc3NpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0ocGFzc2l2ZUlucHV0cywgcGFydGlhbENvbm5lY3Rpb24sIGZhbHNlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG4gICAgaWYgKGluc2VydEVsZW1lbnRJblNldChvdXRwdXRzLCBbZGVzdGluYXRpb24sIG91dHB1dF0sIChvdXRwdXRDb25uZWN0aW9uKSA9PiBvdXRwdXRDb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBvdXRwdXRDb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIHRydWUpKSB7XG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmFkZChldmVudExpc3RlbmVyKTtcbiAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShhY3RpdmVJbnB1dHMsIHNvdXJjZSwgW291dHB1dCwgZXZlbnRMaXN0ZW5lcl0sIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9QYXJhbShwYXNzaXZlSW5wdXRzLCBbc291cmNlLCBvdXRwdXQsIGV2ZW50TGlzdGVuZXJdLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbmNvbnN0IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9Ob2RlID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCB7IGFjdGl2ZUlucHV0cywgcGFzc2l2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbihhY3RpdmVJbnB1dHNbaW5wdXRdLCBzb3VyY2UsIG91dHB1dCk7XG4gICAgaWYgKGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9PT0gbnVsbCkge1xuICAgICAgICBjb25zdCBwYXNzaXZlSW5wdXRDb25uZWN0aW9uID0gZGVsZXRlUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgIHJldHVybiBbcGFzc2l2ZUlucHV0Q29ubmVjdGlvblsyXSwgZmFsc2VdO1xuICAgIH1cbiAgICByZXR1cm4gW2FjdGl2ZUlucHV0Q29ubmVjdGlvblsyXSwgdHJ1ZV07XG59O1xuY29uc3QgZGVsZXRlSW5wdXRDb25uZWN0aW9uT2ZBdWRpb1BhcmFtID0gKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCkgPT4ge1xuICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzLCBwYXNzaXZlSW5wdXRzIH0gPSBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgIGNvbnN0IGFjdGl2ZUlucHV0Q29ubmVjdGlvbiA9IGRlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvbihhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICBpZiAoYWN0aXZlSW5wdXRDb25uZWN0aW9uID09PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHBhc3NpdmVJbnB1dENvbm5lY3Rpb24gPSBkZWxldGVQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb1BhcmFtKHBhc3NpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0KTtcbiAgICAgICAgcmV0dXJuIFtwYXNzaXZlSW5wdXRDb25uZWN0aW9uWzFdLCBmYWxzZV07XG4gICAgfVxuICAgIHJldHVybiBbYWN0aXZlSW5wdXRDb25uZWN0aW9uWzJdLCB0cnVlXTtcbn07XG5jb25zdCBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZSA9IChzb3VyY2UsIGlzT2ZmbGluZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICBjb25zdCBbbGlzdGVuZXIsIGlzQWN0aXZlXSA9IGRlbGV0ZUlucHV0Q29ubmVjdGlvbk9mQXVkaW9Ob2RlKHNvdXJjZSwgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQpO1xuICAgIGlmIChsaXN0ZW5lciAhPT0gbnVsbCkge1xuICAgICAgICBkZWxldGVFdmVudExpc3RlbmVyT2ZBdWRpb05vZGUoc291cmNlLCBsaXN0ZW5lcik7XG4gICAgICAgIGlmIChpc0FjdGl2ZSAmJiAhaXNPZmZsaW5lICYmICFpc1BhcnRPZkFDeWNsZShzb3VyY2UpKSB7XG4gICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZShnZXROYXRpdmVBdWRpb05vZGUoc291cmNlKSwgZ2V0TmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSwgb3V0cHV0LCBpbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICBjb25zdCB7IGFjdGl2ZUlucHV0cyB9ID0gZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMoZGVzdGluYXRpb24pO1xuICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlV2hlbk5lY2Vzc2FyeShkZXN0aW5hdGlvbiwgYWN0aXZlSW5wdXRzKTtcbiAgICB9XG59O1xuY29uc3QgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgW2xpc3RlbmVyLCBpc0FjdGl2ZV0gPSBkZWxldGVJbnB1dENvbm5lY3Rpb25PZkF1ZGlvUGFyYW0oc291cmNlLCBkZXN0aW5hdGlvbiwgb3V0cHV0KTtcbiAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgZGVsZXRlRXZlbnRMaXN0ZW5lck9mQXVkaW9Ob2RlKHNvdXJjZSwgbGlzdGVuZXIpO1xuICAgICAgICBpZiAoaXNBY3RpdmUgJiYgIWlzT2ZmbGluZSAmJiAhaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgZ2V0TmF0aXZlQXVkaW9Ob2RlKHNvdXJjZSkuZGlzY29ubmVjdChnZXROYXRpdmVBdWRpb1BhcmFtKGRlc3RpbmF0aW9uKSwgb3V0cHV0KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5jb25zdCBkZWxldGVBbnlDb25uZWN0aW9uID0gKHNvdXJjZSwgaXNPZmZsaW5lKSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZGVzdGluYXRpb25zID0gW107XG4gICAgZm9yIChjb25zdCBvdXRwdXRDb25uZWN0aW9uIG9mIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cykge1xuICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvTm9kZShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBkZWxldGVJbnB1dHNPZkF1ZGlvUGFyYW0oc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGRlc3RpbmF0aW9ucy5wdXNoKG91dHB1dENvbm5lY3Rpb25bMF0pO1xuICAgIH1cbiAgICBhdWRpb05vZGVDb25uZWN0aW9uc09mU291cmNlLm91dHB1dHMuY2xlYXIoKTtcbiAgICByZXR1cm4gZGVzdGluYXRpb25zO1xufTtcbmNvbnN0IGRlbGV0ZUNvbm5lY3Rpb25BdE91dHB1dCA9IChzb3VyY2UsIGlzT2ZmbGluZSwgb3V0cHV0KSA9PiB7XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKHNvdXJjZSk7XG4gICAgY29uc3QgZGVzdGluYXRpb25zID0gW107XG4gICAgZm9yIChjb25zdCBvdXRwdXRDb25uZWN0aW9uIG9mIGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cykge1xuICAgICAgICBpZiAob3V0cHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dENvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb05vZGUoc291cmNlLCBpc09mZmxpbmUsIC4uLm91dHB1dENvbm5lY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlSW5wdXRzT2ZBdWRpb1BhcmFtKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlc3RpbmF0aW9ucy5wdXNoKG91dHB1dENvbm5lY3Rpb25bMF0pO1xuICAgICAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmRlbGV0ZShvdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZGVzdGluYXRpb25zO1xufTtcbmNvbnN0IGRlbGV0ZUNvbm5lY3Rpb25Ub0Rlc3RpbmF0aW9uID0gKHNvdXJjZSwgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbiwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2UgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhzb3VyY2UpO1xuICAgIHJldHVybiBBcnJheS5mcm9tKGF1ZGlvTm9kZUNvbm5lY3Rpb25zT2ZTb3VyY2Uub3V0cHV0cylcbiAgICAgICAgLmZpbHRlcigob3V0cHV0Q29ubmVjdGlvbikgPT4gb3V0cHV0Q29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiZcbiAgICAgICAgKG91dHB1dCA9PT0gdW5kZWZpbmVkIHx8IG91dHB1dENvbm5lY3Rpb25bMV0gPT09IG91dHB1dCkgJiZcbiAgICAgICAgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgb3V0cHV0Q29ubmVjdGlvblsyXSA9PT0gaW5wdXQpKVxuICAgICAgICAubWFwKChvdXRwdXRDb25uZWN0aW9uKSA9PiB7XG4gICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0Q29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9Ob2RlKHNvdXJjZSwgaXNPZmZsaW5lLCAuLi5vdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbGV0ZUlucHV0c09mQXVkaW9QYXJhbShzb3VyY2UsIGlzT2ZmbGluZSwgLi4ub3V0cHV0Q29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9Ob2RlQ29ubmVjdGlvbnNPZlNvdXJjZS5vdXRwdXRzLmRlbGV0ZShvdXRwdXRDb25uZWN0aW9uKTtcbiAgICAgICAgcmV0dXJuIG91dHB1dENvbm5lY3Rpb25bMF07XG4gICAgfSk7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yID0gKGFkZEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBhZGRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGVjcmVtZW50Q3ljbGVDb3VudGVyLCBkZXRlY3RDeWNsZXMsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQXVkaW9Db250ZXh0LCBpc05hdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVBdWRpb1BhcmFtLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBBdWRpb05vZGUgZXh0ZW5kcyBldmVudFRhcmdldENvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgaXNBY3RpdmUsIG5hdGl2ZUF1ZGlvTm9kZSwgYXVkaW9Ob2RlUmVuZGVyZXIpIHtcbiAgICAgICAgICAgIHN1cGVyKG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZSA9IG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxMjogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgdG8gZGlzY29ubmVjdCBhIHNwZWNpZmljIGRlc3RpbmF0aW9uLlxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpICYmXG4gICAgICAgICAgICAgICAgdHJ1ZSAhPT1cbiAgICAgICAgICAgICAgICAgICAgY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRlc3RBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kU3VwcG9ydChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IpO1xuICAgICAgICAgICAgICAgICAgICB9KSkge1xuICAgICAgICAgICAgICAgIHdyYXBBdWRpb05vZGVEaXNjb25uZWN0TWV0aG9kKG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBBVURJT19OT0RFX1NUT1JFLnNldCh0aGlzLCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgRVZFTlRfTElTVEVORVJTLnNldCh0aGlzLCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgaWYgKGNvbnRleHQuc3RhdGUgIT09ICdjbG9zZWQnICYmIGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlKHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWRkQXVkaW9Ob2RlQ29ubmVjdGlvbnModGhpcywgYXVkaW9Ob2RlUmVuZGVyZXIsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgIH1cbiAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG51bWJlck9mSW5wdXRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgfVxuICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmludmFsaWQtdm9pZFxuICAgICAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXQgPSAwLCBpbnB1dCA9IDApIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTc0OiBTYWZhcmkgZG9lcyBleHBvc2UgYSB3cm9uZyBudW1iZXJPZk91dHB1dHMgZm9yIE1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVzLlxuICAgICAgICAgICAgaWYgKG91dHB1dCA8IDAgfHwgb3V0cHV0ID49IHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQodGhpcy5fY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pIHx8IGlzTmF0aXZlQXVkaW9QYXJhbShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSh0aGlzLl9uYXRpdmVBdWRpb05vZGUsIG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaXNQYXNzaXZlID0gaXNQYXNzaXZlQXVkaW9Ob2RlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNPZmZsaW5lIHx8IGlzUGFzc2l2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Ob2RlLmRpc2Nvbm5lY3QoLi4uY29ubmVjdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC5zdGF0ZSAhPT0gJ2Nsb3NlZCcgJiYgIWlzUGFzc2l2ZSAmJiBpc1Bhc3NpdmVBdWRpb05vZGUoZGVzdGluYXRpb24pKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUoZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM0MTogU2FmYXJpIGRvZXMgbm90IHRocm93IHRoZSBjb3JyZWN0IGV4Y2VwdGlvbiBzbyBmYXIuXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PT0gMTIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgaXNOZXdDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBhZGRDb25uZWN0aW9uVG9BdWRpb05vZGUodGhpcywgZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxNjQ6IE9ubHkgRmlyZWZveCBkZXRlY3RzIGN5Y2xlcyBzbyBmYXIuXG4gICAgICAgICAgICAgICAgaWYgKGlzTmV3Q29ubmVjdGlvblRvQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGN5Y2xlcyA9IGRldGVjdEN5Y2xlcyhbdGhpc10sIGRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlcihpc09mZmxpbmUpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9QYXJhbSA9IGdldE5hdGl2ZUF1ZGlvUGFyYW0oZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAqIEJ1ZyAjNzMsICMxNDcgJiAjMTUzOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCB0byBjb25uZWN0IGFuIGlucHV0IHNpZ25hbCB0byB0aGUgcGxheWJhY2tSYXRlIEF1ZGlvUGFyYW0gb2YgYW5cbiAgICAgICAgICAgICAqIEF1ZGlvQnVmZmVyU291cmNlTm9kZS4gVGhpcyBjYW4ndCBiZSBlYXNpbHkgZGV0ZWN0ZWQgYW5kIHRoYXQncyB3aHkgdGhlIG91dGRhdGVkIG5hbWUgcHJvcGVydHkgaXMgdXNlZCBoZXJlIHRvIGlkZW50aWZ5XG4gICAgICAgICAgICAgKiBTYWZhcmkuIEluIGFkZGl0aW9uIHRvIHRoYXQgdGhlIG1heFZhbHVlIHByb3BlcnR5IGlzIHVzZWQgdG8gb25seSBkZXRlY3QgdGhlIGFmZmVjdGVkIHZlcnNpb25zIGJlbG93IHYxNC4wLjIuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1BhcmFtLm5hbWUgPT09ICdwbGF5YmFja1JhdGUnICYmIG5hdGl2ZUF1ZGlvUGFyYW0ubWF4VmFsdWUgPT09IDEwMjQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb05vZGUuY29ubmVjdChuYXRpdmVBdWRpb1BhcmFtLCBvdXRwdXQpO1xuICAgICAgICAgICAgICAgIGlmIChpc09mZmxpbmUgfHwgaXNQYXNzaXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvUGFyYW0sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTg6IFNhZmFyaSBkb2Vzbid0IHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMikge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaXNOZXdDb25uZWN0aW9uVG9BdWRpb1BhcmFtID0gYWRkQ29ubmVjdGlvblRvQXVkaW9QYXJhbU9mQXVkaW9Db250ZXh0KHRoaXMsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgIGlmIChpc05ld0Nvbm5lY3Rpb25Ub0F1ZGlvUGFyYW0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjeWNsZXMgPSBkZXRlY3RDeWNsZXMoW3RoaXNdLCBkZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgdmlzaXRFYWNoQXVkaW9Ob2RlT25jZShjeWNsZXMsIGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlcihpc09mZmxpbmUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpIHtcbiAgICAgICAgICAgIGxldCBkZXN0aW5hdGlvbnM7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dCh0aGlzLl9jb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGlmIChkZXN0aW5hdGlvbk9yT3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVBbnlDb25uZWN0aW9uKHRoaXMsIGlzT2ZmbGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA8IDAgfHwgZGVzdGluYXRpb25Pck91dHB1dCA+PSB0aGlzLm51bWJlck9mT3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbnMgPSBkZWxldGVDb25uZWN0aW9uQXRPdXRwdXQodGhpcywgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChvdXRwdXQgIT09IHVuZGVmaW5lZCAmJiAob3V0cHV0IDwgMCB8fCBvdXRwdXQgPj0gdGhpcy5udW1iZXJPZk91dHB1dHMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZShkZXN0aW5hdGlvbk9yT3V0cHV0KSAmJiBpbnB1dCAhPT0gdW5kZWZpbmVkICYmIChpbnB1dCA8IDAgfHwgaW5wdXQgPj0gZGVzdGluYXRpb25Pck91dHB1dC5udW1iZXJPZklucHV0cykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW5kZXhTaXplRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVzdGluYXRpb25zID0gZGVsZXRlQ29ubmVjdGlvblRvRGVzdGluYXRpb24odGhpcywgaXNPZmZsaW5lLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE2NDogT25seSBGaXJlZm94IGRldGVjdHMgY3ljbGVzIHNvIGZhci5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZGVzdGluYXRpb24gb2YgZGVzdGluYXRpb25zKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY3ljbGVzID0gZGV0ZWN0Q3ljbGVzKFt0aGlzXSwgZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgIHZpc2l0RWFjaEF1ZGlvTm9kZU9uY2UoY3ljbGVzLCBkZWNyZW1lbnRDeWNsZUNvdW50ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IEF1dG9tYXRpb25FdmVudExpc3QgfSBmcm9tICdhdXRvbWF0aW9uLWV2ZW50cyc7XG5leHBvcnQgY29uc3QgY3JlYXRlQXVkaW9QYXJhbUZhY3RvcnkgPSAoYWRkQXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIGF1ZGlvUGFyYW1TdG9yZSwgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyLCBjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVDYW5jZWxTY2hlZHVsZWRWYWx1ZXNBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50LCBjcmVhdGVTZXRWYWx1ZUN1cnZlQXV0b21hdGlvbkV2ZW50LCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb05vZGUsIGlzQXVkaW9QYXJhbU9mT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSwgbWF4VmFsdWUgPSBudWxsLCBtaW5WYWx1ZSA9IG51bGwpID0+IHtcbiAgICAgICAgLy8gQnVnICMxOTYgT25seSBTYWZhcmkgc2V0cyB0aGUgZGVmYXVsdFZhbHVlIHRvIHRoZSBpbml0aWFsIHZhbHVlLlxuICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlO1xuICAgICAgICBjb25zdCBhdXRvbWF0aW9uRXZlbnRMaXN0ID0gbmV3IEF1dG9tYXRpb25FdmVudExpc3QoZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbVJlbmRlcmVyID0gaXNBdWRpb1BhcmFtT2ZPZmZsaW5lQXVkaW9Db250ZXh0ID8gY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyKGF1dG9tYXRpb25FdmVudExpc3QpIDogbnVsbDtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbSA9IHtcbiAgICAgICAgICAgIGdldCBkZWZhdWx0VmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHRWYWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1heFZhbHVlID09PSBudWxsID8gbmF0aXZlQXVkaW9QYXJhbS5tYXhWYWx1ZSA6IG1heFZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtaW5WYWx1ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbWluVmFsdWUgPT09IG51bGwgPyBuYXRpdmVBdWRpb1BhcmFtLm1pblZhbHVlIDogbWluVmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1BhcmFtLnZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCB2YWx1ZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0udmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzk4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCB5ZXQgdHJlYXQgdGhlIHZhbHVlIHNldHRlciBsaWtlIGEgY2FsbCB0byBzZXRWYWx1ZUF0VGltZSgpLlxuICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWUsIGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5jZWxBbmRIb2xkQXRUaW1lKGNhbmNlbFRpbWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzI4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCB5ZXQgaW1wbGVtZW50IGNhbmNlbEFuZEhvbGRBdFRpbWUoKS5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsQW5kSG9sZEF0VGltZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJldmlvdXNMYXN0RXZlbnQgPSBBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVDYW5jZWxBbmRIb2xkQXV0b21hdGlvbkV2ZW50KGNhbmNlbFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudExhc3RFdmVudCA9IEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGNhbmNlbFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJldmlvdXNMYXN0RXZlbnQgIT09IGN1cnJlbnRMYXN0RXZlbnQgJiYgY3VycmVudExhc3RFdmVudCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5lbmRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ2xpbmVhclJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5lbmRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRMYXN0RXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZSwgY3VycmVudExhc3RFdmVudC5zdGFydFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudExhc3RFdmVudC50eXBlID09PSAnc2V0VmFsdWVDdXJ2ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUoY3VycmVudExhc3RFdmVudC52YWx1ZXMsIGN1cnJlbnRMYXN0RXZlbnQuc3RhcnRUaW1lLCBjdXJyZW50TGFzdEV2ZW50LmR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChhdWRpb05vZGUuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudChjYW5jZWxUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY2FuY2VsVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTg3OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICghTnVtYmVyLmlzRmluaXRlKGVuZFRpbWUpIHx8IGVuZFRpbWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgaWYgKGF1ZGlvUGFyYW1SZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmZsdXNoKGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOTQ6IEZpcmVmb3ggZG9lcyBub3QgaW1wbGljaXRseSBjYWxsIHNldFZhbHVlQXRUaW1lKCkgaWYgdGhlcmUgaXMgbm8gcHJldmlvdXMgZXZlbnQuXG4gICAgICAgICAgICAgICAgaWYgKEFycmF5LmZyb20oYXV0b21hdGlvbkV2ZW50TGlzdCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQXV0b21hdGlvbkV2ZW50KGRlZmF1bHRWYWx1ZSwgY3VycmVudFRpbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZShkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5hZGQoY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgZW5kVGltZSkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VGltZSA9IGF1ZGlvTm9kZS5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgYXV0b21hdGlvbkV2ZW50TGlzdC5mbHVzaChjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTk1OiBGaXJlZm94IGRvZXMgbm90IGltcGxpY2l0bHkgY2FsbCBzZXRWYWx1ZUF0VGltZSgpIGlmIHRoZXJlIGlzIG5vIHByZXZpb3VzIGV2ZW50LlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5mcm9tKGF1dG9tYXRpb25FdmVudExpc3QpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudChkZWZhdWx0VmFsdWUsIGN1cnJlbnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVBdFRpbWUoZGVmYXVsdFZhbHVlLCBjdXJyZW50VGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZUxpbmVhclJhbXBUb1ZhbHVlQXV0b21hdGlvbkV2ZW50KHZhbHVlLCBlbmRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRUYXJnZXRBdXRvbWF0aW9uRXZlbnQodGFyZ2V0LCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb1BhcmFtO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCBzdGFydFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXVkaW9QYXJhbVJlbmRlcmVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhdXRvbWF0aW9uRXZlbnRMaXN0LmFkZChjcmVhdGVTZXRWYWx1ZUF1dG9tYXRpb25FdmVudCh2YWx1ZSwgc3RhcnRUaW1lKSk7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXRWYWx1ZUN1cnZlQXRUaW1lKHZhbHVlcywgc3RhcnRUaW1lLCBkdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAxODM6IFNhZmFyaSBvbmx5IGFjY2VwdHMgYSBGbG9hdDMyQXJyYXkuXG4gICAgICAgICAgICAgICAgY29uc3QgY29udmVydGVkVmFsdWVzID0gdmFsdWVzIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gdmFsdWVzIDogbmV3IEZsb2F0MzJBcnJheSh2YWx1ZXMpO1xuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICogQnVnICMxNTI6IFNhZmFyaSBkb2VzIG5vdCBjb3JyZWN0bHkgaW50ZXJwb2xhdGUgdGhlIHZhbHVlcyBvZiB0aGUgY3VydmUuXG4gICAgICAgICAgICAgICAgICogQHRvZG8gVW5mb3J0dW5hdGVseSB0aGVyZSBpcyBubyB3YXkgdG8gdGVzdCBmb3IgdGhpcyBiZWhhdmlvciBpbiBhIHN5bmNocm9ub3VzIGZhc2hpb24gd2hpY2ggaXMgd2h5IHRlc3RpbmcgZm9yIHRoZVxuICAgICAgICAgICAgICAgICAqIGV4aXN0ZW5jZSBvZiB0aGUgd2Via2l0QXVkaW9Db250ZXh0IGlzIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGhlcmUuXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yICE9PSBudWxsICYmIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLm5hbWUgPT09ICd3ZWJraXRBdWRpb0NvbnRleHQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBzdGFydFRpbWUgKyBkdXJhdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2FtcGxlUmF0ZSA9IGF1ZGlvTm9kZS5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0U2FtcGxlID0gTWF0aC5jZWlsKHN0YXJ0VGltZSAqIHNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBsYXN0U2FtcGxlID0gTWF0aC5mbG9vcihlbmRUaW1lICogc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzID0gbGFzdFNhbXBsZSAtIGZpcnN0U2FtcGxlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnBvbGF0ZWRWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG51bWJlck9mSW50ZXJwb2xhdGVkVmFsdWVzKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkludGVycG9sYXRlZFZhbHVlczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aGVvcmV0aWNJbmRleCA9ICgoY29udmVydGVkVmFsdWVzLmxlbmd0aCAtIDEpIC8gZHVyYXRpb24pICogKChmaXJzdFNhbXBsZSArIGkpIC8gc2FtcGxlUmF0ZSAtIHN0YXJ0VGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb3dlckluZGV4ID0gTWF0aC5mbG9vcih0aGVvcmV0aWNJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1cHBlckluZGV4ID0gTWF0aC5jZWlsKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVycG9sYXRlZFZhbHVlc1tpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGNvbnZlcnRlZFZhbHVlc1tsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICgxIC0gKHRoZW9yZXRpY0luZGV4IC0gbG93ZXJJbmRleCkpICogY29udmVydGVkVmFsdWVzW2xvd2VySW5kZXhdICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxIC0gKHVwcGVySW5kZXggLSB0aGVvcmV0aWNJbmRleCkpICogY29udmVydGVkVmFsdWVzW3VwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoaW50ZXJwb2xhdGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShpbnRlcnBvbGF0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lT2ZMYXN0U2FtcGxlID0gbGFzdFNhbXBsZSAvIHNhbXBsZVJhdGU7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aW1lT2ZMYXN0U2FtcGxlIDwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VmFsdWVBdFRpbWVVbnRpbFBvc3NpYmxlKGF1ZGlvUGFyYW0sIGludGVycG9sYXRlZFZhbHVlc1tpbnRlcnBvbGF0ZWRWYWx1ZXMubGVuZ3RoIC0gMV0sIHRpbWVPZkxhc3RTYW1wbGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZShhdWRpb1BhcmFtLCBjb252ZXJ0ZWRWYWx1ZXNbY29udmVydGVkVmFsdWVzLmxlbmd0aCAtIDFdLCBlbmRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhdWRpb1BhcmFtUmVuZGVyZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuZmx1c2goYXVkaW9Ob2RlLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1dG9tYXRpb25FdmVudExpc3QuYWRkKGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQoY29udmVydGVkVmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvUGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZShjb252ZXJ0ZWRWYWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9QYXJhbTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYXVkaW9QYXJhbVN0b3JlLnNldChhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgYXVkaW9QYXJhbUF1ZGlvTm9kZVN0b3JlLnNldChhdWRpb1BhcmFtLCBhdWRpb05vZGUpO1xuICAgICAgICBhZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoYXVkaW9QYXJhbSwgYXVkaW9QYXJhbVJlbmRlcmVyKTtcbiAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1wYXJhbS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIgPSAoYXV0b21hdGlvbkV2ZW50TGlzdCkgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIHJlcGxheShhdWRpb1BhcmFtKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF1dG9tYXRpb25FdmVudCBvZiBhdXRvbWF0aW9uRXZlbnRMaXN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKGF1dG9tYXRpb25FdmVudC50eXBlID09PSAnZXhwb25lbnRpYWxSYW1wVG9WYWx1ZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBlbmRUaW1lLCB2YWx1ZSB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ2xpbmVhclJhbXBUb1ZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGVuZFRpbWUsIHZhbHVlIH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0ubGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIGVuZFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFRhcmdldCcpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBzdGFydFRpbWUsIHRhcmdldCwgdGltZUNvbnN0YW50IH0gPSBhdXRvbWF0aW9uRXZlbnQ7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvUGFyYW0uc2V0VGFyZ2V0QXRUaW1lKHRhcmdldCwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdXRvbWF0aW9uRXZlbnQudHlwZSA9PT0gJ3NldFZhbHVlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IHN0YXJ0VGltZSwgdmFsdWUgfSA9IGF1dG9tYXRpb25FdmVudDtcbiAgICAgICAgICAgICAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYXV0b21hdGlvbkV2ZW50LnR5cGUgPT09ICdzZXRWYWx1ZUN1cnZlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGR1cmF0aW9uLCBzdGFydFRpbWUsIHZhbHVlcyB9ID0gYXV0b21hdGlvbkV2ZW50O1xuICAgICAgICAgICAgICAgICAgICBhdWRpb1BhcmFtLnNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbid0IGFwcGx5IGFuIHVua25vd24gYXV0b21hdGlvbi5cIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby1wYXJhbS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY2xhc3MgUmVhZE9ubHlNYXAge1xuICAgIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnMpIHtcbiAgICAgICAgdGhpcy5fbWFwID0gbmV3IE1hcChwYXJhbWV0ZXJzKTtcbiAgICB9XG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuc2l6ZTtcbiAgICB9XG4gICAgZW50cmllcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5lbnRyaWVzKCk7XG4gICAgfVxuICAgIGZvckVhY2goY2FsbGJhY2ssIHRoaXNBcmcgPSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwga2V5LCB0aGlzKSk7XG4gICAgfVxuICAgIGdldChuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAuZ2V0KG5hbWUpO1xuICAgIH1cbiAgICBoYXMobmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwLmhhcyhuYW1lKTtcbiAgICB9XG4gICAga2V5cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC5rZXlzKCk7XG4gICAgfVxuICAgIHZhbHVlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcC52YWx1ZXMoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1yZWFkLW9ubHktbWFwLmpzLm1hcCIsImltcG9ydCB7IE5PREVfTkFNRV9UT19QUk9DRVNTT1JfQ09OU1RSVUNUT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgUmVhZE9ubHlNYXAgfSBmcm9tICcuLi9yZWFkLW9ubHktbWFwJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgLy8gQnVnICM2MTogVGhlIGNoYW5uZWxDb3VudE1vZGUgc2hvdWxkIGJlICdtYXgnIGFjY29yZGluZyB0byB0aGUgc3BlYyBidXQgaXMgc2V0IHRvICdleHBsaWNpdCcgdG8gYWNoaWV2ZSBjb25zaXN0ZW50IGJlaGF2aW9yLlxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG51bWJlck9mSW5wdXRzOiAxLFxuICAgIG51bWJlck9mT3V0cHV0czogMSxcbiAgICBwYXJhbWV0ZXJEYXRhOiB7fSxcbiAgICBwcm9jZXNzb3JPcHRpb25zOiB7fVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPSAoYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVBdWRpb1dvcmtsZXROb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvciwgc2FuaXRpemVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucywgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHksIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEF1ZGlvV29ya2xldE5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHZhciBfYTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMoeyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfSk7XG4gICAgICAgICAgICAvLyBCdWcgIzE5MTogU2FmYXJpIGRvZXNuJ3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG9wdGlvbnMgYXJlbid0IGNsb25hYmxlLlxuICAgICAgICAgICAgdGVzdEF1ZGlvV29ya2xldE5vZGVPcHRpb25zQ2xvbmFiaWxpdHkobWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPSBOT0RFX05BTUVfVE9fUFJPQ0VTU09SX0NPTlNUUlVDVE9SX01BUFMuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgcHJvY2Vzc29yQ29uc3RydWN0b3IgPSBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAgPT09IG51bGwgfHwgbm9kZU5hbWVUb1Byb2Nlc3NvckNvbnN0cnVjdG9yTWFwID09PSB2b2lkIDAgPyB2b2lkIDAgOiBub2RlTmFtZVRvUHJvY2Vzc29yQ29uc3RydWN0b3JNYXAuZ2V0KG5hbWUpO1xuICAgICAgICAgICAgLy8gQnVnICMxODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgYWxsb3cgdG8gY3JlYXRlIGFuIEF1ZGlvV29ya2xldE5vZGUgb24gYSBjbG9zZWQgQXVkaW9Db250ZXh0LlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dE9yQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGlzT2ZmbGluZSB8fCBuYXRpdmVDb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJ1xuICAgICAgICAgICAgICAgID8gbmF0aXZlQ29udGV4dFxuICAgICAgICAgICAgICAgIDogKF9hID0gZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogbmF0aXZlQ29udGV4dDtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlKG5hdGl2ZUNvbnRleHRPckJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQsIGlzT2ZmbGluZSA/IG51bGwgOiBjb250ZXh0LmJhc2VMYXRlbmN5LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hbWUsIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldE5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyKG5hbWUsIG1lcmdlZE9wdGlvbnMsIHByb2Nlc3NvckNvbnN0cnVjdG9yKSA6IG51bGwpKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBAdG9kbyBBZGQgYSBtZWNoYW5pc20gdG8gc3dpdGNoIGFuIEF1ZGlvV29ya2xldE5vZGUgdG8gcGFzc2l2ZSBvbmNlIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gb2YgdGhlIEF1ZGlvV29ya2xldFByb2Nlc3NvclxuICAgICAgICAgICAgICogcmV0dXJucyBmYWxzZS5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBbXTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucGFyYW1ldGVycy5mb3JFYWNoKChuYXRpdmVBdWRpb1BhcmFtLCBubSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgICAgICAgICAgICAgcGFyYW1ldGVycy5wdXNoKFtubSwgYXVkaW9QYXJhbV0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgICAgIHRoaXMuX29ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5fcGFyYW1ldGVycyA9IG5ldyBSZWFkT25seU1hcChwYXJhbWV0ZXJzKTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzg2ICYgIzg3OiBJbnZva2luZyB0aGUgcmVuZGVyZXIgb2YgYW4gQXVkaW9Xb3JrbGV0Tm9kZSBtaWdodCBiZSBuZWNlc3NhcnkgaWYgaXQgaGFzIG5vIGRpcmVjdCBvciBpbmRpcmVjdCBjb25uZWN0aW9uIHRvXG4gICAgICAgICAgICAgKiB0aGUgZGVzdGluYXRpb24uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmIChpc09mZmxpbmUpIHtcbiAgICAgICAgICAgICAgICBhZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShuYXRpdmVDb250ZXh0LCB0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgYWN0aXZlSW5wdXRzIH0gPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyh0aGlzKTtcbiAgICAgICAgICAgIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb25wcm9jZXNzb3JlcnJvcigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vbnByb2Nlc3NvcmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHNldCBvbnByb2Nlc3NvcmVycm9yKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkTGlzdGVuZXIgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB3cmFwRXZlbnRMaXN0ZW5lcih0aGlzLCB2YWx1ZSkgOiBudWxsO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciA9IHRoaXMuX25hdGl2ZUF1ZGlvV29ya2xldE5vZGUub25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgICAgIHRoaXMuX29ucHJvY2Vzc29yZXJyb3IgPVxuICAgICAgICAgICAgICAgIG5hdGl2ZU9uUHJvY2Vzc29yRXJyb3IgIT09IG51bGwgJiYgbmF0aXZlT25Qcm9jZXNzb3JFcnJvciA9PT0gd3JhcHBlZExpc3RlbmVyXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgOiBuYXRpdmVPblByb2Nlc3NvckVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYXJhbWV0ZXJzKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3BhcmFtZXRlcnMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtZXRlcnM7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvcnQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wb3J0O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGZ1bmN0aW9uIGNvcHlGcm9tQ2hhbm5lbChhdWRpb0J1ZmZlciwgXG4vLyBAdG9kbyBUaGVyZSBpcyBjdXJyZW50bHkgbm8gd2F5IHRvIGRlZmluZSBzb21ldGhpbmcgbGlrZSB7IFsga2V5OiBudW1iZXIgfCBzdHJpbmcgXTogRmxvYXQzMkFycmF5IH1cbnBhcmVudCwga2V5LCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpIHtcbiAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICBpZiAocGFyZW50W2tleV0uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcGFyZW50W2tleV0gPSBuZXcgRmxvYXQzMkFycmF5KDEyOCk7XG4gICAgICAgIH1cbiAgICAgICAgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsKHBhcmVudFtrZXldLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICAvLyBCdWcgIzU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNvcHlGcm9tQ2hhbm5lbCgpLlxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY29uc3QgY2hhbm5lbERhdGEgPSBhdWRpb0J1ZmZlci5nZXRDaGFubmVsRGF0YShjaGFubmVsTnVtYmVyKTtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHBhcmVudFtrZXldID0gY2hhbm5lbERhdGEuc2xpY2UoYnVmZmVyT2Zmc2V0LCBidWZmZXJPZmZzZXQgKyAxMjgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgc2xpY2VkSW5wdXQgPSBuZXcgRmxvYXQzMkFycmF5KGNoYW5uZWxEYXRhLmJ1ZmZlciwgYnVmZmVyT2Zmc2V0ICogRmxvYXQzMkFycmF5LkJZVEVTX1BFUl9FTEVNRU5ULCAxMjgpO1xuICAgICAgICAgICAgcGFyZW50W2tleV0uc2V0KHNsaWNlZElucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcHktZnJvbS1jaGFubmVsLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjb3B5VG9DaGFubmVsID0gKGF1ZGlvQnVmZmVyLCBwYXJlbnQsIGtleSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgIGlmIChwYXJlbnRba2V5XS5ieXRlTGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKHBhcmVudFtrZXldLCBjaGFubmVsTnVtYmVyLCBidWZmZXJPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weVRvQ2hhbm5lbCgpLlxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgLy8gVGhlIGJ5dGVMZW5ndGggd2lsbCBiZSAwIHdoZW4gdGhlIEFycmF5QnVmZmVyIHdhcyB0cmFuc2ZlcnJlZC5cbiAgICAgICAgaWYgKHBhcmVudFtrZXldLmJ5dGVMZW5ndGggIT09IDApIHtcbiAgICAgICAgICAgIGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpLnNldChwYXJlbnRba2V5XSwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb3B5LXRvLWNoYW5uZWwuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5lc3RlZEFycmF5cyA9ICh4LCB5KSA9PiB7XG4gICAgY29uc3QgYXJyYXlzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB4OyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgYXJyYXkgPSBbXTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdHlwZW9mIHkgPT09ICdudW1iZXInID8geSA6IHlbaV07XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgIGFycmF5LnB1c2gobmV3IEZsb2F0MzJBcnJheSgxMjgpKTtcbiAgICAgICAgfVxuICAgICAgICBhcnJheXMucHVzaChhcnJheSk7XG4gICAgfVxuICAgIHJldHVybiBhcnJheXM7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLW5lc3RlZC1hcnJheXMuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9nZXQtbmF0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2dldC12YWx1ZS1mb3Ita2V5JztcbmV4cG9ydCBjb25zdCBnZXRBdWRpb1dvcmtsZXRQcm9jZXNzb3IgPSAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpID0+IHtcbiAgICBjb25zdCBub2RlVG9Qcm9jZXNzb3JNYXAgPSBnZXRWYWx1ZUZvcktleShOT0RFX1RPX1BST0NFU1NPUl9NQVBTLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICByZXR1cm4gZ2V0VmFsdWVGb3JLZXkobm9kZVRvUHJvY2Vzc29yTWFwLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgY29weUZyb21DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LWZyb20tY2hhbm5lbCc7XG5pbXBvcnQgeyBjb3B5VG9DaGFubmVsIH0gZnJvbSAnLi4vaGVscGVycy9jb3B5LXRvLWNoYW5uZWwnO1xuaW1wb3J0IHsgY3JlYXRlTmVzdGVkQXJyYXlzIH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGUtbmVzdGVkLWFycmF5cyc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0LWF1ZGlvLW5vZGUtY29ubmVjdGlvbnMnO1xuaW1wb3J0IHsgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yIH0gZnJvbSAnLi4vaGVscGVycy9nZXQtYXVkaW8td29ya2xldC1wcm9jZXNzb3InO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5jb25zdCBwcm9jZXNzQnVmZmVyID0gYXN5bmMgKHByb3h5LCByZW5kZXJlZEJ1ZmZlciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucywgb3V0cHV0Q2hhbm5lbENvdW50LCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUpID0+IHtcbiAgICAvLyBDZWlsIHRoZSBsZW5ndGggdG8gdGhlIG5leHQgZnVsbCByZW5kZXIgcXVhbnR1bS5cbiAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgIGNvbnN0IGxlbmd0aCA9IHJlbmRlcmVkQnVmZmVyID09PSBudWxsID8gTWF0aC5jZWlsKHByb3h5LmNvbnRleHQubGVuZ3RoIC8gMTI4KSAqIDEyOCA6IHJlbmRlcmVkQnVmZmVyLmxlbmd0aDtcbiAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxDb3VudCAqIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgY29uc3QgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyA9IG91dHB1dENoYW5uZWxDb3VudC5yZWR1Y2UoKHN1bSwgdmFsdWUpID0+IHN1bSArIHZhbHVlLCAwKTtcbiAgICBjb25zdCBwcm9jZXNzZWRCdWZmZXIgPSBudW1iZXJPZk91dHB1dENoYW5uZWxzID09PSAwXG4gICAgICAgID8gbnVsbFxuICAgICAgICA6IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mT3V0cHV0Q2hhbm5lbHMsIGxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHByb2Nlc3NvciBjb25zdHJ1Y3Rvci4nKTtcbiAgICB9XG4gICAgY29uc3QgYXVkaW9Ob2RlQ29ubmVjdGlvbnMgPSBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyhwcm94eSk7XG4gICAgY29uc3QgYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gYXdhaXQgZ2V0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5KTtcbiAgICBjb25zdCBpbnB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZklucHV0cywgb3B0aW9ucy5jaGFubmVsQ291bnQpO1xuICAgIGNvbnN0IG91dHB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZk91dHB1dHMsIG91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgY29uc3QgcGFyYW1ldGVycyA9IEFycmF5LmZyb20ocHJveHkucGFyYW1ldGVycy5rZXlzKCkpLnJlZHVjZSgocHJtdHJzLCBuYW1lKSA9PiAoeyAuLi5wcm10cnMsIFtuYW1lXTogbmV3IEZsb2F0MzJBcnJheSgxMjgpIH0pLCB7fSk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMTI4KSB7XG4gICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mSW5wdXRzID4gMCAmJiByZW5kZXJlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKHJlbmRlcmVkQnVmZmVyLCBpbnB1dHNbal0sIGssIGssIGkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgIT09IHVuZGVmaW5lZCAmJiByZW5kZXJlZEJ1ZmZlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMuZm9yRWFjaCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29weUZyb21DaGFubmVsKHJlbmRlcmVkQnVmZmVyLCBwYXJhbWV0ZXJzLCBuYW1lLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCwgaSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGogKz0gMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBieXRlTGVuZ3RoIHdpbGwgYmUgMCB3aGVuIHRoZSBBcnJheUJ1ZmZlciB3YXMgdHJhbnNmZXJyZWQuXG4gICAgICAgICAgICAgICAgaWYgKG91dHB1dHNbal1ba10uYnl0ZUxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRzW2pdW2tdID0gbmV3IEZsb2F0MzJBcnJheSgxMjgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcG90ZW50aWFsbHlFbXB0eUlucHV0cyA9IGlucHV0cy5tYXAoKGlucHV0LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhdWRpb05vZGVDb25uZWN0aW9ucy5hY3RpdmVJbnB1dHNbaW5kZXhdLnNpemUgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVNvdXJjZUZsYWcgPSBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShpIC8gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUsICgpID0+IGF1ZGlvV29ya2xldFByb2Nlc3Nvci5wcm9jZXNzKHBvdGVudGlhbGx5RW1wdHlJbnB1dHMsIG91dHB1dHMsIHBhcmFtZXRlcnMpKTtcbiAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlUb0NoYW5uZWwocHJvY2Vzc2VkQnVmZmVyLCBvdXRwdXRzW2pdLCBrLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbal07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFhY3RpdmVTb3VyY2VGbGFnKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBwcm94eS5kaXNwYXRjaEV2ZW50KG5ldyBFcnJvckV2ZW50KCdwcm9jZXNzb3JlcnJvcicsIHtcbiAgICAgICAgICAgICAgICBjb2xubzogZXJyb3IuY29sbm8sXG4gICAgICAgICAgICAgICAgZmlsZW5hbWU6IGVycm9yLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgIGxpbmVubzogZXJyb3IubGluZW5vLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9jZXNzZWRCdWZmZXI7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGRlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKG5hbWUsIG9wdGlvbnMsIHByb2Nlc3NvckNvbnN0cnVjdG9yKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBwcm9jZXNzZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICBsZXQgbmF0aXZlT3V0cHV0Tm9kZXMgPSBudWxsO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbENvdW50ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudClcbiAgICAgICAgICAgICAgICA/IG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50XG4gICAgICAgICAgICAgICAgOiBBcnJheS5mcm9tKG9wdGlvbnMub3V0cHV0Q2hhbm5lbENvdW50KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNjE6IE9ubHkgQ2hyb21lLCBFZGdlICYgRmlyZWZveCBoYXZlIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZSBBdWRpb1dvcmtsZXROb2RlIHlldC5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZk91dHB1dENoYW5uZWxzID0gb3V0cHV0Q2hhbm5lbENvdW50LnJlZHVjZSgoc3VtLCB2YWx1ZSkgPT4gc3VtICsgdmFsdWUsIDApO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJPZk91dHB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcm94eS5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IG91dHB1dENoYW5uZWxDb3VudFtpXVxuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG9wdGlvbnMuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jb25uZWN0ID0gY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcyk7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdCA9IGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMuYmluZChudWxsLCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXMpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZU91dHB1dE5vZGVzID0gW291dHB1dENoYW5uZWxTcGxpdHRlck5vZGUsIG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlcywgb3V0cHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA9IG5ldyBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU91dHB1dE5vZGVzID09PSBudWxsID8gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSA6IG5hdGl2ZU91dHB1dE5vZGVzWzJdKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVPdXRwdXROb2RlcyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIHByb2Nlc3NvciBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIG5hdGl2ZSBPZmZsaW5lQXVkaW9Db250ZXh0IGNvbnN0cnVjdG9yLicpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZ2V0cyBub3QgaW5pdGlhbGl6ZWQgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBwcm94eS5jaGFubmVsQ291bnQgKiBwcm94eS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtYmVyT2ZQYXJhbWV0ZXJzID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMgPT09IHVuZGVmaW5lZCA/IDAgOiBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBudW1iZXJPZlBhcmFtZXRlcnM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlckJ1ZmZlciA9IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmV3IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihudW1iZXJPZkNoYW5uZWxzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENlaWwgdGhlIGxlbmd0aCB0byB0aGUgbmV4dCBmdWxsIHJlbmRlciBxdWFudHVtLlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGguY2VpbChwcm94eS5jb250ZXh0Lmxlbmd0aCAvIDEyOCkgKiAxMjgsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBnYWluTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGVzLnB1c2goY3JlYXRlTmF0aXZlR2Fpbk5vZGUocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluOiAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXMucHVzaChjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZXMgPSBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKHByb3h5LnBhcmFtZXRlcnMudmFsdWVzKCkpLm1hcChhc3luYyAoYXVkaW9QYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBhdWRpb1BhcmFtLnZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgY29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogTWF0aC5tYXgoMSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzKVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdhaW5Ob2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5jaGFubmVsQ291bnQ7IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2ldLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgaiwgaSAqIG9wdGlvbnMuY2hhbm5lbENvdW50ICsgaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGNvbnN0YW50U291cmNlTm9kZV0gb2YgY29uc3RhbnRTb3VyY2VOb2Rlcy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudFNvdXJjZU5vZGUuY29ubmVjdChpbnB1dENoYW5uZWxNZXJnZXJOb2RlLCAwLCBudW1iZXJPZklucHV0Q2hhbm5lbHMgKyBpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5jb25uZWN0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGdhaW5Ob2Rlcy5tYXAoKGdhaW5Ob2RlKSA9PiByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQsIGdhaW5Ob2RlKSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRCdWZmZXJQcm9taXNlID0gcHJvY2Vzc0J1ZmZlcihwcm94eSwgbnVtYmVyT2ZDaGFubmVscyA9PT0gMCA/IG51bGwgOiBhd2FpdCByZW5kZXJCdWZmZXIoKSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucywgb3V0cHV0Q2hhbm5lbENvdW50LCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBwcm9jZXNzZWRCdWZmZXIgPSBhd2FpdCBwcm9jZXNzZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAyLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgICAgICAgICBwbGF5YmFja1JhdGU6IDFcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBbb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSwgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLCBvdXRwdXRHYWluTm9kZV0gPSBuYXRpdmVPdXRwdXROb2RlcztcbiAgICAgICAgICAgICAgICBpZiAocHJvY2Vzc2VkQnVmZmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBwcm9jZXNzZWRCdWZmZXI7XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3Qob3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgcHJveHkubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3V0cHV0Q2hhbm5lbENvdW50W2ldOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgKz0gb3V0cHV0Q2hhbm5lbENvdW50W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0R2Fpbk5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvV29ya2xldE5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbbm0sIGF1ZGlvUGFyYW1dIG9mIHByb3h5LnBhcmFtZXRlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgYXVkaW9QYXJhbSwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFRoZSBkZWZpbml0aW9uIHRoYXQgVHlwZVNjcmlwdCB1c2VzIG9mIHRoZSBBdWRpb1BhcmFtTWFwIGlzIGxhY2tpbmcgbWFueSBtZXRob2RzLlxuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnBhcmFtZXRlcnMuZ2V0KG5tKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBbbm0sIGF1ZGlvUGFyYW1dIG9mIHByb3h5LnBhcmFtZXRlcnMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGF1ZGlvUGFyYW0sIFxuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUaGUgZGVmaW5pdGlvbiB0aGF0IFR5cGVTY3JpcHQgdXNlcyBvZiB0aGUgQXVkaW9QYXJhbU1hcCBpcyBsYWNraW5nIG1hbnkgbWV0aG9kcy5cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5wYXJhbWV0ZXJzLmdldChubSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb1dvcmtsZXROb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZU9yR2Fpbk5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUF1ZGlvV29ya2xldE5vZGVPckdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGFkZEF1ZGlvV29ya2xldE1vZHVsZSwgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yLCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciwgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciwgZGVjb2RlQXVkaW9EYXRhLCBkZWxheU5vZGVDb25zdHJ1Y3RvciwgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yLCBnYWluTm9kZUNvbnN0cnVjdG9yLCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IsIHBhbm5lck5vZGVDb25zdHJ1Y3RvciwgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IsIHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvciwgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBCYXNlQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICBzdXBlcihfbmF0aXZlQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0ID0gX25hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICB0aGlzLl9hdWRpb1dvcmtsZXQgPVxuICAgICAgICAgICAgICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWRkTW9kdWxlOiAobW9kdWxlVVJMLCBvcHRpb25zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEF1ZGlvV29ya2xldE1vZHVsZSh0aGlzLCBtb2R1bGVVUkwsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGdldCBhdWRpb1dvcmtsZXQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXVkaW9Xb3JrbGV0O1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhbmFseXNlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCaXF1YWRGaWx0ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGJpcXVhZEZpbHRlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVCdWZmZXIobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGgsIG51bWJlck9mQ2hhbm5lbHMsIHNhbXBsZVJhdGUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBhdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDaGFubmVsTWVyZ2VyKG51bWJlck9mSW5wdXRzID0gNikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbnVtYmVyT2ZJbnB1dHMgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cyA9IDYpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbnVtYmVyT2ZPdXRwdXRzIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVEZWxheShtYXhEZWxheVRpbWUgPSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGRlbGF5Tm9kZUNvbnN0cnVjdG9yKHRoaXMsIHsgbWF4RGVsYXlUaW1lIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3NvcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGdhaW5Ob2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlSUlSRmlsdGVyKGZlZWRmb3J3YXJkLCBmZWVkYmFjaykge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IodGhpcywgeyBmZWVkYmFjaywgZmVlZGZvcndhcmQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlT3NjaWxsYXRvcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgb3NjaWxsYXRvck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVQYW5uZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBhbm5lck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBjcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMgPSB7IGRpc2FibGVOb3JtYWxpemF0aW9uOiBmYWxzZSB9KSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yKHRoaXMsIHsgLi4uY29uc3RyYWludHMsIGltYWcsIHJlYWwgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlU3RlcmVvUGFubmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3JlYXRlV2F2ZVNoYXBlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3Rvcih0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBkZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBkZWNvZGVBdWRpb0RhdGEodGhpcy5fbmF0aXZlQ29udGV4dCwgYXVkaW9EYXRhKS50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygc3VjY2Vzc0NhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3NDYWxsYmFjayhhdWRpb0J1ZmZlcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgICAgIH0sIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGVycm9yQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JDYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YmFzZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgUTogMSxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRldHVuZTogMCxcbiAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICBnYWluOiAwLFxuICAgIHR5cGU6ICdsb3dwYXNzJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciwgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVOYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEJpcXVhZEZpbHRlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGJpcXVhZEZpbHRlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIGJpcXVhZEZpbHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzgwOiBTYWZhcmkgZG9lcyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fUSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLlEsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc4OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9kZXR1bmUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUsIDEyMDAgKiBNYXRoLmxvZzIoTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQpLCAtMTIwMCAqIE1hdGgubG9nMihNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCkpO1xuICAgICAgICAgICAgLy8gQnVnICM3NzogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlIGZvciBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSwgY29udGV4dC5zYW1wbGVSYXRlIC8gMiwgMCk7XG4gICAgICAgICAgICAvLyBCdWcgIzc5OiBGaXJlZm94ICYgU2FmYXJpIGRvIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9nYWluID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2FpbiwgNDAgKiBNYXRoLmxvZzEwKE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUKSwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBkZXR1bmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV0dW5lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBnYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dhaW47XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IFEoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fUTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHR5cGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUJpcXVhZEZpbHRlck5vZGUudHlwZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgLy8gQnVnICMxODk6IFNhZmFyaSBkb2VzIHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnVnICM2ODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIGlmIHRoZSBwYXJhbWV0ZXJzIGRpZmZlciBpbiB0aGVpciBsZW5ndGguXG4gICAgICAgICAgICBpZiAoZnJlcXVlbmN5SHoubGVuZ3RoICE9PSBtYWdSZXNwb25zZS5sZW5ndGggfHwgbWFnUmVzcG9uc2UubGVuZ3RoICE9PSBwaGFzZVJlc3BvbnNlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWRcbiAgICAgICAgICAgICAqIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUJpcXVhZEZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgUTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRldHVuZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGZyZXF1ZW5jeTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZ2Fpbi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS50eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQmlxdWFkRmlsdGVyTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuUSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRldHVuZSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5kZXR1bmUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuUSwgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZS5RKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZGV0dW5lKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5nYWluLCBuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgPSByZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVCaXF1YWRGaWx0ZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUJpcXVhZEZpbHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ2FjaGVUZXN0UmVzdWx0ID0gKG9uZ29pbmdUZXN0cywgdGVzdFJlc3VsdHMpID0+IHtcbiAgICByZXR1cm4gKHRlc3RlciwgdGVzdCkgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZWRUZXN0UmVzdWx0ID0gdGVzdFJlc3VsdHMuZ2V0KHRlc3Rlcik7XG4gICAgICAgIGlmIChjYWNoZWRUZXN0UmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWNoZWRUZXN0UmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9uZ29pbmdUZXN0ID0gb25nb2luZ1Rlc3RzLmdldCh0ZXN0ZXIpO1xuICAgICAgICBpZiAob25nb2luZ1Rlc3QgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG9uZ29pbmdUZXN0O1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQgPSB0ZXN0KCk7XG4gICAgICAgICAgICBpZiAoc3luY2hyb25vdXNUZXN0UmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgIG9uZ29pbmdUZXN0cy5zZXQodGVzdGVyLCBzeW5jaHJvbm91c1Rlc3RSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBzeW5jaHJvbm91c1Rlc3RSZXN1bHRcbiAgICAgICAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAudGhlbigoZmluYWxUZXN0UmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIG9uZ29pbmdUZXN0cy5kZWxldGUodGVzdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGVzdFJlc3VsdHMuc2V0KHRlc3RlciwgZmluYWxUZXN0UmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbmFsVGVzdFJlc3VsdDtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIHN5bmNocm9ub3VzVGVzdFJlc3VsdCk7XG4gICAgICAgICAgICByZXR1cm4gc3luY2hyb25vdXNUZXN0UmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgIHRlc3RSZXN1bHRzLnNldCh0ZXN0ZXIsIGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y2FjaGUtdGVzdC1yZXN1bHQuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBudW1iZXJPZklucHV0czogNlxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENoYW5uZWxNZXJnZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIGZhbHNlLCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlcik7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtbWVyZ2VyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiBuYXRpdmVBdWRpb05vZGUubnVtYmVyT2ZJbnB1dHNcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiA2LFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgIG51bWJlck9mT3V0cHV0czogNlxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzYW5pdGl6ZUNoYW5uZWxTcGxpdHRlck9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ2hhbm5lbFNwbGl0dGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0gc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH0pO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIgPSAoKGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KSA/IGNyZWF0ZUNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlcigpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNoYW5uZWxTcGxpdHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNoYW5uZWwtc3BsaXR0ZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVBdWRpb05vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUF1ZGlvTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUF1ZGlvTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUF1ZGlvTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIG51bWJlck9mT3V0cHV0czogbmF0aXZlQXVkaW9Ob2RlLm51bWJlck9mT3V0cHV0c1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Ob2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb05vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jaGFubmVsLXNwbGl0dGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ29ubmVjdEF1ZGlvUGFyYW0gPSAocmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIHJldHVybiByZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0oYXVkaW9QYXJhbSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9QYXJhbSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LWF1ZGlvLXBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbiwgb3V0cHV0ID0gMCwgaW5wdXQgPSAwKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dEF1ZGlvTm9kZSA9IG91dHB1dEF1ZGlvTm9kZXNbb3V0cHV0XTtcbiAgICAgICAgaWYgKG91dHB1dEF1ZGlvTm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZShkZXN0aW5hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgMCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXRwdXRBdWRpb05vZGUuY29ubmVjdChkZXN0aW5hdGlvbiwgMCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0LW11bHRpcGxlLW91dHB1dHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb05vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGJ1ZmZlcjogbnVsbCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDIsIDQ0MTAwKTtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLmJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyO1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUubG9vcCA9IHRydWU7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCgpO1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUF1ZGlvTm9kZSk7XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCB9IGZyb20gJy4uL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4uL2hlbHBlcnMvaXMtYWN0aXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvQWN0aXZlIH0gZnJvbSAnLi4vaGVscGVycy9zZXQtaW50ZXJuYWwtc3RhdGUtdG8tYWN0aXZlJztcbmltcG9ydCB7IHNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1wYXNzaXZlJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIG9mZnNldDogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgQ29uc3RhbnRTb3VyY2VOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSAoKGlzT2ZmbGluZSA/IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeSgpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgPSBjb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZSA9IG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzYyICYgIzc0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBDb25zdGFudFNvdXJjZU5vZGVzIGFuZCBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWVcbiAgICAgICAgICAgICAqIGZvciBHYWluTm9kZXMuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIHRoaXMuX29mZnNldCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCBNT1NUX1BPU0lUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9mZnNldCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG9uZW5kZWQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb25lbmRlZDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZExpc3RlbmVyID0gdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nID8gd3JhcEV2ZW50TGlzdGVuZXIodGhpcywgdmFsdWUpIDogbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5vbmVuZGVkO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG5hdGl2ZU9uRW5kZWQgIT09IG51bGwgJiYgbmF0aXZlT25FbmRlZCA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPbkVuZGVkO1xuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RhcnQod2hlbik7XG4gICAgICAgICAgICBpZiAodGhpcy5fY29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlci5zdGFydCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0FjdGl2ZUF1ZGlvTm9kZSh0aGlzKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBzdG9wKHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb25zdGFudFNvdXJjZU5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9jb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLnN0b3AgPSB3aGVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkXG4gICAgICAgICAgICAgKiBhZ2Fpbi5cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0OiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LnZhbHVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdGFydChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZS5zdG9wKHN0b3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub2Zmc2V0LCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9mZnNldCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gcmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25zdGFudC1zb3VyY2Utbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgPSAodW5pdDMyQXJyYXkpID0+IHtcbiAgICByZXR1cm4gKHZhbHVlKSA9PiB7XG4gICAgICAgIHVuaXQzMkFycmF5WzBdID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB1bml0MzJBcnJheVswXTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZlcnQtbnVtYmVyLXRvLXVuc2lnbmVkLWxvbmcuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGJ1ZmZlcjogbnVsbCxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGlzYWJsZU5vcm1hbGl6YXRpb246IGZhbHNlXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIENvbnZvbHZlck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb252b2x2ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnZvbHZlck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVDb252b2x2ZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUNvbnZvbHZlck5vZGUsIGNvbnZvbHZlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZSA9IG5hdGl2ZUNvbnZvbHZlck5vZGU7XG4gICAgICAgICAgICBpZiAobWVyZ2VkT3B0aW9ucy5idWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCBtZXJnZWRPcHRpb25zLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pc0J1ZmZlck51bGxpZmllZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyO1xuICAgICAgICB9XG4gICAgICAgIHNldCBidWZmZXIodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID0gdmFsdWU7XG4gICAgICAgICAgICAvLyBCdWcgIzExNTogU2FmYXJpIGRvZXMgbm90IGFsbG93IHRvIHNldCB0aGUgYnVmZmVyIHRvIG51bGwuXG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgJiYgdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gdGhpcy5fbmF0aXZlQ29udm9sdmVyTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9pc0J1ZmZlck51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyID09PSBudWxsID8gMCA6IHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBnZXQgbm9ybWFsaXplKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplO1xuICAgICAgICB9XG4gICAgICAgIHNldCBub3JtYWxpemUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUNvbnZvbHZlck5vZGUubm9ybWFsaXplID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUtZmFrZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUNvbnZvbHZlck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVDb252b2x2ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVDb252b2x2ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUNvbnZvbHZlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVDb252b2x2ZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGJ1ZmZlcjogbmF0aXZlQ29udm9sdmVyTm9kZS5idWZmZXIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogbmF0aXZlQ29udm9sdmVyTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZUNvbnZvbHZlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVDb252b2x2ZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbixcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZU5vcm1hbGl6YXRpb246ICFuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUNvbnZvbHZlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgIGlmIChpc05hdGl2ZUF1ZGlvTm9kZUZha2VyKG5hdGl2ZUNvbnZvbHZlck5vZGUpKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUNvbnZvbHZlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVDb252b2x2ZXJOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlID0gcmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlQ29udm9sdmVyTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVDb252b2x2ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUNvbnZvbHZlck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y29udm9sdmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlQ3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAvLyBCdWcgIzE0MywgIzE0NCAmICMxNDY6IFNhZmFyaSB0aHJvd3MgYSBTeW50YXhFcnJvciB3aGVuIG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCBvciBzYW1wbGVSYXRlIGFyZSBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKGVyci5uYW1lID09PSAnU3ludGF4RXJyb3InKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZURhdGFDbG9uZUVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0RhdGFDbG9uZUVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kYXRhLWNsb25lLWVycm9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBkZXRhY2hBcnJheUJ1ZmZlciA9IChhcnJheUJ1ZmZlcikgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgY29uc3QgY2xvc2VBbmRSZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICAgICAgcG9ydDIub25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgICAgICBwb3J0Mi5jbG9zZSgpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0Mi5vbm1lc3NhZ2UgPSAoKSA9PiBjbG9zZUFuZFJlc29sdmUoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGFycmF5QnVmZmVyLCBbYXJyYXlCdWZmZXJdKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgY2xvc2VBbmRSZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZXRhY2gtYXJyYXktYnVmZmVyLmpzLm1hcCIsImltcG9ydCB7IGRldGFjaEFycmF5QnVmZmVyIH0gZnJvbSAnLi4vaGVscGVycy9kZXRhY2gtYXJyYXktYnVmZmVyJztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVjb2RlQXVkaW9EYXRhID0gKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlRGF0YUNsb25lRXJyb3IsIGNyZWF0ZUVuY29kaW5nRXJyb3IsIGRldGFjaGVkQXJyYXlCdWZmZXJzLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZUNvbnRleHQsIHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgdGVzdFByb21pc2VTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKSA9PiB7XG4gICAgcmV0dXJuIChhbnlDb250ZXh0LCBhdWRpb0RhdGEpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGlzTmF0aXZlQ29udGV4dChhbnlDb250ZXh0KSA/IGFueUNvbnRleHQgOiBnZXROYXRpdmVDb250ZXh0KGFueUNvbnRleHQpO1xuICAgICAgICAvLyBCdWcgIzQzOiBPbmx5IENocm9tZSBhbmQgRWRnZSBkbyB0aHJvdyBhIERhdGFDbG9uZUVycm9yLlxuICAgICAgICBpZiAoZGV0YWNoZWRBcnJheUJ1ZmZlcnMuaGFzKGF1ZGlvRGF0YSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVyciA9IGNyZWF0ZURhdGFDbG9uZUVycm9yKCk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUaGUgYXVkaW9EYXRhIHBhcmFtZXRlciBtYXliZSBvZiBhIHR5cGUgd2hpY2ggY2FuJ3QgYmUgYWRkZWQgdG8gYSBXZWFrU2V0LlxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGV0YWNoZWRBcnJheUJ1ZmZlcnMuYWRkKGF1ZGlvRGF0YSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIGlmIChjYWNoZVRlc3RSZXN1bHQodGVzdFByb21pc2VTdXBwb3J0LCAoKSA9PiB0ZXN0UHJvbWlzZVN1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKS50aGVuKChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMzOiBTYWZhcmkgZG9lcyBuZXV0ZXIgdGhlIEFycmF5QnVmZmVyLlxuICAgICAgICAgICAgICAgIGRldGFjaEFycmF5QnVmZmVyKGF1ZGlvRGF0YSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydChhdWRpb0J1ZmZlcikpKSB7XG4gICAgICAgICAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTdG9yZS5hZGQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCByZXR1cm4gYSBQcm9taXNlIHlldC5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXBsZXRlID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTMzOiBTYWZhcmkgZG9lcyBuZXV0ZXIgdGhlIEFycmF5QnVmZmVyLlxuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGRldGFjaEFycmF5QnVmZmVyKGF1ZGlvRGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgZmFpbCA9IChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICBjb21wbGV0ZSgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMjY6IFNhZmFyaSB0aHJvd3MgYSBzeW5jaHJvbm91cyBlcnJvci5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxOiBTYWZhcmkgcmVxdWlyZXMgYSBzdWNjZXNzQ2FsbGJhY2suXG4gICAgICAgICAgICAgICAgbmF0aXZlQ29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhLCAoYXVkaW9CdWZmZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMDogU2FmYXJpIGRvZXMgdGhyb3cgYSB3cm9uZyBlcnJvciB3aGVuIGNhbGxpbmcgZ2V0Q2hhbm5lbERhdGEoKSB3aXRoIGFuIG91dC1vZi1ib3VuZHMgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYXVkaW9CdWZmZXIuY29weUZyb21DaGFubmVsICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyR2V0Q2hhbm5lbERhdGFNZXRob2QoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU3RvcmUuYWRkKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgICAgICAgICAgY29tcGxldGUoKS50aGVuKCgpID0+IHJlc29sdmUoYXVkaW9CdWZmZXIpKTtcbiAgICAgICAgICAgICAgICB9LCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNDogU2FmYXJpIHJldHVybnMgbnVsbCBpbnN0ZWFkIG9mIGFuIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGNyZWF0ZUVuY29kaW5nRXJyb3IoKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmYWlsKGVycik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBmYWlsKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGVjb2RlLWF1ZGlvLWRhdGEuanMubWFwIiwiaW1wb3J0IHsgaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUtb3V0cHV0LWNvbm5lY3Rpb24nO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlciA9IChjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIGN5Y2xlQ291bnRlcnMsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGdldE5hdGl2ZUNvbnRleHQsIGlzQWN0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSwgY291bnQpID0+IHtcbiAgICAgICAgY29uc3QgY3ljbGVDb3VudGVyID0gY3ljbGVDb3VudGVycy5nZXQoYXVkaW9Ob2RlKTtcbiAgICAgICAgaWYgKGN5Y2xlQ291bnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgdGhlIGV4cGVjdGVkIGN5Y2xlIGNvdW50LicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGF1ZGlvTm9kZS5jb250ZXh0KTtcbiAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSBjb3VudCkge1xuICAgICAgICAgICAgY3ljbGVDb3VudGVycy5kZWxldGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgIGlmICghaXNPZmZsaW5lICYmIGlzQWN0aXZlQXVkaW9Ob2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVTb3VyY2VBdWRpb05vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUoYXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBvdXRwdXQgb2Ygb3V0cHV0cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb05vZGVPdXRwdXRDb25uZWN0aW9uKG91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0WzFdLCBvdXRwdXRbMl0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlU291cmNlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtLCBvdXRwdXRbMV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY3ljbGVDb3VudGVycy5zZXQoYXVkaW9Ob2RlLCBjeWNsZUNvdW50ZXIgLSBjb3VudCk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlY3JlbWVudC1jeWNsZS1jb3VudGVyLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ21heCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIGRlbGF5VGltZTogMCxcbiAgICBtYXhEZWxheVRpbWU6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRGVsYXlOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVsYXlOb2RlID0gY3JlYXRlTmF0aXZlRGVsYXlOb2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgY29uc3QgaXNPZmZsaW5lID0gaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgZGVsYXlOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIobWVyZ2VkT3B0aW9ucy5tYXhEZWxheVRpbWUpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlRGVsYXlOb2RlLCBkZWxheU5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9kZWxheVRpbWUgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCBtZXJnZWRPcHRpb25zLm1heERlbGF5VGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRlbGF5VGltZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWxheVRpbWU7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKG1heERlbGF5VGltZSkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVEZWxheU5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVEZWxheU5vZGUgPSBnZXROYXRpdmVBdWRpb05vZGUocHJveHkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZURlbGF5Tm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZURlbGF5Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZURlbGF5Tm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGRlbGF5VGltZTogbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgbWF4RGVsYXlUaW1lXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVEZWxheU5vZGUgPSBjcmVhdGVOYXRpdmVEZWxheU5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZURlbGF5Tm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmRlbGF5VGltZSwgbmF0aXZlRGVsYXlOb2RlLmRlbGF5VGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZWxheVRpbWUsIG5hdGl2ZURlbGF5Tm9kZS5kZWxheVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZURlbGF5Tm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlRGVsYXlOb2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVEZWxheU5vZGUgPSByZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZURlbGF5Tm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVEZWxheU5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRGVsYXlOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSAocGlja0VsZW1lbnRGcm9tU2V0KSA9PiB7XG4gICAgcmV0dXJuIChhY3RpdmVJbnB1dHMsIHNvdXJjZSwgb3V0cHV0LCBpbnB1dCkgPT4ge1xuICAgICAgICByZXR1cm4gcGlja0VsZW1lbnRGcm9tU2V0KGFjdGl2ZUlucHV0c1tpbnB1dF0sIChhY3RpdmVJbnB1dENvbm5lY3Rpb24pID0+IGFjdGl2ZUlucHV0Q29ubmVjdGlvblswXSA9PT0gc291cmNlICYmIGFjdGl2ZUlucHV0Q29ubmVjdGlvblsxXSA9PT0gb3V0cHV0KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSA9IChnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGF1ZGlvV29ya2xldE5vZGUpID0+IHtcbiAgICAgICAgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKG5hdGl2ZUNvbnRleHQpLmRlbGV0ZShhdWRpb1dvcmtsZXROb2RlKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRlbGV0ZS11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNEZWxheU5vZGUgPSAoYXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICdkZWxheVRpbWUnIGluIGF1ZGlvTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlIH0gZnJvbSAnLi4vZ3VhcmRzL2F1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgaXNEZWxheU5vZGUgfSBmcm9tICcuLi9ndWFyZHMvZGVsYXktbm9kZSc7XG5leHBvcnQgY29uc3QgY3JlYXRlRGV0ZWN0Q3ljbGVzID0gKGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldFZhbHVlRm9yS2V5KSA9PiB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGRldGVjdEN5Y2xlcyhjaGFpbiwgbmV4dExpbmspIHtcbiAgICAgICAgY29uc3QgYXVkaW9Ob2RlID0gaXNBdWRpb05vZGUobmV4dExpbmspID8gbmV4dExpbmsgOiBnZXRWYWx1ZUZvcktleShhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIG5leHRMaW5rKTtcbiAgICAgICAgaWYgKGlzRGVsYXlOb2RlKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhaW5bMF0gPT09IGF1ZGlvTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIFtjaGFpbl07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYWluLmluY2x1ZGVzKGF1ZGlvTm9kZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKG91dHB1dHMpXG4gICAgICAgICAgICAubWFwKChvdXRwdXRDb25uZWN0aW9uKSA9PiBkZXRlY3RDeWNsZXMoWy4uLmNoYWluLCBhdWRpb05vZGVdLCBvdXRwdXRDb25uZWN0aW9uWzBdKSlcbiAgICAgICAgICAgIC5yZWR1Y2UoKG1lcmdlZEN5Y2xlcywgbmVzdGVkQ3ljbGVzKSA9PiBtZXJnZWRDeWNsZXMuY29uY2F0KG5lc3RlZEN5Y2xlcyksIFtdKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRldGVjdC1jeWNsZXMuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuLi9ndWFyZHMvbmF0aXZlLWF1ZGlvLW5vZGUnO1xuY29uc3QgZ2V0T3V0cHV0QXVkaW9Ob2RlQXRJbmRleCA9IChjcmVhdGVJbmRleFNpemVFcnJvciwgb3V0cHV0QXVkaW9Ob2Rlcywgb3V0cHV0KSA9PiB7XG4gICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlID0gb3V0cHV0QXVkaW9Ob2Rlc1tvdXRwdXRdO1xuICAgIGlmIChvdXRwdXRBdWRpb05vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2RlO1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVEaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzID0gKGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbk9yT3V0cHV0ID0gdW5kZWZpbmVkLCBvdXRwdXQgPSB1bmRlZmluZWQsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KCkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZGVzdGluYXRpb25Pck91dHB1dCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBkZXN0aW5hdGlvbk9yT3V0cHV0KS5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAob3V0cHV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0QXVkaW9Ob2Rlcy5mb3JFYWNoKChvdXRwdXRBdWRpb05vZGUpID0+IG91dHB1dEF1ZGlvTm9kZS5kaXNjb25uZWN0KGRlc3RpbmF0aW9uT3JPdXRwdXQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbnB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZXRPdXRwdXRBdWRpb05vZGVBdEluZGV4KGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBvdXRwdXRBdWRpb05vZGVzLCBvdXRwdXQpLmRpc2Nvbm5lY3QoZGVzdGluYXRpb25Pck91dHB1dCwgMCwgaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdXRwdXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG91dHB1dEF1ZGlvTm9kZXMuZm9yRWFjaCgob3V0cHV0QXVkaW9Ob2RlKSA9PiBvdXRwdXRBdWRpb05vZGUuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGdldE91dHB1dEF1ZGlvTm9kZUF0SW5kZXgoY3JlYXRlSW5kZXhTaXplRXJyb3IsIG91dHB1dEF1ZGlvTm9kZXMsIG91dHB1dCkuZGlzY29ubmVjdChkZXN0aW5hdGlvbk9yT3V0cHV0LCAwKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWRpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cy5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgYXR0YWNrOiAwLjAwMyxcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAga25lZTogMzAsXG4gICAgcmF0aW86IDEyLFxuICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgdGhyZXNob2xkOiAtMjRcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIER5bmFtaWNzQ29tcHJlc3Nvck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIGR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9hdHRhY2sgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5hdHRhY2spO1xuICAgICAgICAgICAgdGhpcy5fa25lZSA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgICAgICAgICB0aGlzLl9yYXRpbyA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgIHRoaXMuX3JlbGVhc2UgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yZWxlYXNlKTtcbiAgICAgICAgICAgIHRoaXMuX3RocmVzaG9sZCA9IGNyZWF0ZUF1ZGlvUGFyYW0odGhpcywgaXNPZmZsaW5lLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICBzZXRBdWRpb05vZGVUYWlsVGltZSh0aGlzLCAwLjAwNik7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGF0dGFjaygpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hdHRhY2s7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDg6IFNhZmFyaSBhbGxvd3MgYSBjaGFubmVsQ291bnQgb2YgdGhyZWUgYW5kIGFib3ZlIHdoaWNoIGlzIHdoeSB0aGUgZ2V0dGVyIGFuZCBzZXR0ZXIgbmVlZHMgdG8gYmUgb3ZlcndyaXR0ZW4gaGVyZS5cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudDtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY2hhbm5lbENvdW50KHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0NoYW5uZWxDb3VudCA9IHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIGlmICh2YWx1ZSA+IDIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHByZXZpb3VzQ2hhbm5lbENvdW50O1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDk6IE9ubHkgQ2hyb21lIGFuZCBGaXJlZm94IGRpc2FsbG93IGEgY2hhbm5lbENvdW50TW9kZSBvZiAnbWF4JyB5ZXQgd2hpY2ggaXMgd2h5IHRoZSBnZXR0ZXIgYW5kIHNldHRlciBuZWVkcyB0byBiZVxuICAgICAgICAgKiBvdmVyd3JpdHRlbiBoZXJlLlxuICAgICAgICAgKi9cbiAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0NoYW5uZWxDb3VudCA9IHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHByZXZpb3VzQ2hhbm5lbENvdW50O1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGtuZWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fa25lZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmF0aW8oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcmF0aW87XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTExOiBTYWZhcmkgcmV0dXJucyBhbiBBdWRpb1BhcmFtIGluc3RlYWQgb2YgYSBudW1iZXIuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuX25hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUucmVkdWN0aW9uLnZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbi52YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlZHVjdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcmVsZWFzZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWxlYXNlO1xuICAgICAgICB9XG4gICAgICAgIGdldCB0aHJlc2hvbGQoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGhyZXNob2xkO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeSA9IChjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogSWYgdGhlIGluaXRpYWxseSB1c2VkIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlXG4gICAgICAgICAgICAgKiBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmF0dGFjay52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246IG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBrbmVlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJhdGlvOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvLnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHRocmVzaG9sZDogbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQudmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5hdHRhY2ssIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmtuZWUsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUua25lZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yYXRpbywgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS5yYXRpbyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yZWxlYXNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkudGhyZXNob2xkLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnRocmVzaG9sZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5hdHRhY2ssIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUuYXR0YWNrKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5rbmVlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLmtuZWUpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnJhdGlvLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJhdGlvKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5yZWxlYXNlLCBuYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlLnJlbGVhc2UpO1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnRocmVzaG9sZCwgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZS50aHJlc2hvbGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUgPSByZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1keW5hbWljcy1jb21wcmVzc29yLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRW5jb2RpbmdFcnJvciA9ICgpID0+IG5ldyBET01FeGNlcHRpb24oJycsICdFbmNvZGluZ0Vycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1lbmNvZGluZy1lcnJvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlRXZhbHVhdGVTb3VyY2UgPSAod2luZG93KSA9PiB7XG4gICAgcmV0dXJuIChzb3VyY2UpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgaWYgKHdpbmRvdyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGVhZCA9IHdpbmRvdy5kb2N1bWVudC5oZWFkO1xuICAgICAgICBpZiAoaGVhZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gQnVnICMxODIgQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIGluc3RhbmNlIG9mIGEgU3ludGF4RXJyb3IgaW5zdGVhZCBvZiBhIERPTUV4Y2VwdGlvbi5cbiAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzY3JpcHQgPSB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICAvLyBAdG9kbyBTYWZhcmkgZG9lc24ndCBsaWtlIFVSTHMgd2l0aCBhIHR5cGUgb2YgJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLTgnLlxuICAgICAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtzb3VyY2VdLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0JyB9KTtcbiAgICAgICAgICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyID0gd2luZG93Lm9uZXJyb3I7XG4gICAgICAgICAgICBjb25zdCByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgd2luZG93Lm9uZXJyb3IgPSBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyO1xuICAgICAgICAgICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwodXJsKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB3aW5kb3cub25lcnJvciA9IChtZXNzYWdlLCBzcmMsIGxpbmVubywgY29sbm8sIGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRWRnZSB0aGlua3MgdGhlIHNvdXJjZSBpcyB0aGUgb25lIG9mIHRoZSBodG1sIGRvY3VtZW50LlxuICAgICAgICAgICAgICAgIGlmIChzcmMgPT09IHVybCB8fCAoc3JjID09PSB3aW5kb3cubG9jYXRpb24uaHJlZiAmJiBsaW5lbm8gPT09IDEgJiYgY29sbm8gPT09IDEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUVycm9yRXZlbnRMaXN0ZW5lckFuZFJldm9rZVVybCgpO1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbE9uRXJyb3JIYW5kbGVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbE9uRXJyb3JIYW5kbGVyKG1lc3NhZ2UsIHNyYywgbGluZW5vLCBjb2xubywgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBzY3JpcHQub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE4MiBDaHJvbWUgYW5kIEVkZ2UgZG8gdGhyb3cgYW4gaW5zdGFuY2Ugb2YgYSBTeW50YXhFcnJvciBpbnN0ZWFkIG9mIGEgRE9NRXhjZXB0aW9uLlxuICAgICAgICAgICAgICAgIHJlamVjdChuZXcgU3ludGF4RXJyb3IoKSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0Lm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICByZW1vdmVFcnJvckV2ZW50TGlzdGVuZXJBbmRSZXZva2VVcmwoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgc2NyaXB0LnNyYyA9IHVybDtcbiAgICAgICAgICAgIHNjcmlwdC50eXBlID0gJ21vZHVsZSc7XG4gICAgICAgICAgICBoZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmFsdWF0ZS1zb3VyY2UuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3IgPSAod3JhcEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgRXZlbnRUYXJnZXQge1xuICAgICAgICBjb25zdHJ1Y3RvcihfbmF0aXZlRXZlbnRUYXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0ID0gX25hdGl2ZUV2ZW50VGFyZ2V0O1xuICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICBhZGRFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBpZiAobGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgd3JhcHBlZEV2ZW50TGlzdGVuZXIgPSB0aGlzLl9saXN0ZW5lcnMuZ2V0KGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICBpZiAod3JhcHBlZEV2ZW50TGlzdGVuZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIGxpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fbGlzdGVuZXJzLnNldChsaXN0ZW5lciwgd3JhcHBlZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUV2ZW50VGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgd3JhcHBlZEV2ZW50TGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGRpc3BhdGNoRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCB3cmFwcGVkRXZlbnRMaXN0ZW5lciA9IGxpc3RlbmVyID09PSBudWxsID8gdW5kZWZpbmVkIDogdGhpcy5fbGlzdGVuZXJzLmdldChsaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVFdmVudFRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHdyYXBwZWRFdmVudExpc3RlbmVyID09PSB1bmRlZmluZWQgPyBudWxsIDogd3JhcHBlZEV2ZW50TGlzdGVuZXIsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ldmVudC10YXJnZXQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lID0gKHdpbmRvdykgPT4ge1xuICAgIHJldHVybiAoY3VycmVudFRpbWUsIHNhbXBsZVJhdGUsIGZuKSA9PiB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKHdpbmRvdywge1xuICAgICAgICAgICAgY3VycmVudEZyYW1lOiB7XG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIGdldCgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGgucm91bmQoY3VycmVudFRpbWUgKiBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY3VycmVudFRpbWU6IHtcbiAgICAgICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgZ2V0KCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY3VycmVudFRpbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBmbigpO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKHdpbmRvdyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuY3VycmVudEZyYW1lO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cuY3VycmVudFRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWV4cG9zZS1jdXJyZW50LWZyYW1lLWFuZC1jdXJyZW50LXRpbWUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUZldGNoU291cmNlID0gKGNyZWF0ZUFib3J0RXJyb3IpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKHVybCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFthd2FpdCByZXNwb25zZS50ZXh0KCksIHJlc3BvbnNlLnVybF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgLy8gSWdub3JlIGVycm9ycy5cbiAgICAgICAgfSAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWVtcHR5XG4gICAgICAgIHRocm93IGNyZWF0ZUFib3J0RXJyb3IoKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWZldGNoLXNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZ2FpbjogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVHYWluTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIEdhaW5Ob2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlR2Fpbk5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlR2Fpbk5vZGUsIGdhaW5Ob2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM3NDogU2FmYXJpIGRvZXMgbm90IGV4cG9ydCB0aGUgY29ycmVjdCB2YWx1ZXMgZm9yIG1heFZhbHVlIGFuZCBtaW5WYWx1ZS5cbiAgICAgICAgICAgIHRoaXMuX2dhaW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlR2Fpbk5vZGUuZ2FpbiwgTU9TVF9QT1NJVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfTkVHQVRJVkVfU0lOR0xFX0ZMT0FUKTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZ2FpbigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nYWluO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5leHBvcnQgY29uc3QgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVHYWluTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUdhaW5Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVHYWluTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZUdhaW5Ob2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlR2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGdhaW46IG5hdGl2ZUdhaW5Ob2RlLmdhaW4udmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUdhaW5Ob2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVHYWluTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LmdhaW4sIG5hdGl2ZUdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZ2FpbiwgbmF0aXZlR2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmVuZGVyKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVHYWluTm9kZSA9IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVHYWluTm9kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVuZGVyZWROYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBjcmVhdGVHYWluTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nYWluLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IChhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIGdldFZhbHVlRm9yS2V5KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlKSA9PiBnZXRWYWx1ZUZvcktleShhY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzU3RvcmUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIgPSAoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIGlmIChhdWRpb05vZGVDb25uZWN0aW9ucy5yZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSByZW5kZXJlciBvZiB0aGUgZ2l2ZW4gQXVkaW9Ob2RlIGluIHRoZSBhdWRpbyBncmFwaC4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYXVkaW9Ob2RlQ29ubmVjdGlvbnMucmVuZGVyZXI7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYXVkaW8tbm9kZS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSAoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlKSA9PiB7IHZhciBfYTsgcmV0dXJuIChfYSA9IGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUuZ2V0KGF1ZGlvTm9kZSkpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IDA7IH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVHZXRBdWRpb1BhcmFtUmVuZGVyZXIgPSAoZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1Db25uZWN0aW9ucyA9IGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyhhdWRpb1BhcmFtKTtcbiAgICAgICAgaWYgKGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5yZW5kZXJlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSByZW5kZXJlciBvZiB0aGUgZ2l2ZW4gQXVkaW9QYXJhbSBpbiB0aGUgYXVkaW8gZ3JhcGguJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5yZW5kZXJlcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWdldC1hdWRpby1wYXJhbS1yZW5kZXJlci5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtYmFja3VwLW9mZmxpbmUtYXVkaW8tY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgPSAoKSA9PiBuZXcgRE9NRXhjZXB0aW9uKCcnLCAnSW52YWxpZFN0YXRlRXJyb3InKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWludmFsaWQtc3RhdGUtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IgfSBmcm9tICcuL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUdldE5hdGl2ZUNvbnRleHQgPSAoY29udGV4dFN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChjb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBjb250ZXh0U3RvcmUuZ2V0KGNvbnRleHQpO1xuICAgICAgICBpZiAobmF0aXZlQ29udGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAobmF0aXZlQ29udGV4dCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtbmF0aXZlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgICAgICBsZXQgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHRTdG9yZS5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgIGlmIChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNDE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNyZWF0aW5nIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aCBsZXNzIHRoYW4gNDQxMDAgSHouXG4gICAgICAgIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlLnNldChuYXRpdmVDb250ZXh0LCBiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgcmV0dXJuIGJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9ICh1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyA9IHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUuZ2V0KG5hdGl2ZUNvbnRleHQpO1xuICAgICAgICBpZiAodW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNvbnRleHQgaGFzIG5vIHNldCBvZiBBdWRpb1dvcmtsZXROb2Rlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ0ludmFsaWRBY2Nlc3NFcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW52YWxpZC1hY2Nlc3MtZXJyb3IuanMubWFwIiwiaW1wb3J0IHsgY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtYWNjZXNzLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwSUlSRmlsdGVyTm9kZUdldEZyZXF1ZW5jeVJlc3BvbnNlTWV0aG9kID0gKG5hdGl2ZUlJUkZpbHRlck5vZGUpID0+IHtcbiAgICBuYXRpdmVJSVJGaWx0ZXJOb2RlLmdldEZyZXF1ZW5jeVJlc3BvbnNlID0gKChnZXRGcmVxdWVuY3lSZXNwb25zZSkgPT4ge1xuICAgICAgICByZXR1cm4gKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGZyZXF1ZW5jeUh6Lmxlbmd0aCAhPT0gbWFnUmVzcG9uc2UubGVuZ3RoIHx8IG1hZ1Jlc3BvbnNlLmxlbmd0aCAhPT0gcGhhc2VSZXNwb25zZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBnZXRGcmVxdWVuY3lSZXNwb25zZS5jYWxsKG5hdGl2ZUlJUkZpbHRlck5vZGUsIGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSk7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgd3JhcElJUkZpbHRlck5vZGVHZXRGcmVxdWVuY3lSZXNwb25zZU1ldGhvZCB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1paXItZmlsdGVyLW5vZGUtZ2V0LWZyZXF1ZW5jeS1yZXNwb25zZS1tZXRob2QnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2Vycydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlSUlSRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlLCBjcmVhdGVJSVJGaWx0ZXJOb2RlUmVuZGVyZXIsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgSUlSRmlsdGVyTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIGlzT2ZmbGluZSA/IG51bGwgOiBjb250ZXh0LmJhc2VMYXRlbmN5LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlpckZpbHRlck5vZGVSZW5kZXJlciA9ICgoaXNPZmZsaW5lID8gY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyKG1lcmdlZE9wdGlvbnMuZmVlZGJhY2ssIG1lcmdlZE9wdGlvbnMuZmVlZGZvcndhcmQpIDogbnVsbCkpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZUlJUkZpbHRlck5vZGUsIGlpckZpbHRlck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICAvLyBCdWcgIzIzICYgIzI0OiBGaXJlZm94RGV2ZWxvcGVyIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvci5cbiAgICAgICAgICAgIC8vIEB0b2RvIFdyaXRlIGEgdGVzdCB3aGljaCBhbGxvd3Mgb3RoZXIgYnJvd3NlcnMgdG8gcmVtYWluIHVucGF0Y2hlZC5cbiAgICAgICAgICAgIHdyYXBJSVJGaWx0ZXJOb2RlR2V0RnJlcXVlbmN5UmVzcG9uc2VNZXRob2QobmF0aXZlSUlSRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcXVlbmN5SHosIG1hZ1Jlc3BvbnNlLCBwaGFzZVJlc3BvbnNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlSUlSRmlsdGVyTm9kZS5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxdWVuY3lIeiwgbWFnUmVzcG9uc2UsIHBoYXNlUmVzcG9uc2UpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiLy8gVGhpcyBpbXBsZW1lbnRhdGlvbiBhcyBzaGFtZWxlc3NseSBpbnNwaXJlZCBieSBzb3VyY2UgY29kZSBvZlxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuLy8ge0BsaW5rIGh0dHBzOi8vY2hyb21pdW0uZ29vZ2xlc291cmNlLmNvbS9jaHJvbWl1bS9zcmMuZ2l0LysvbWFzdGVyL3RoaXJkX3BhcnR5L1dlYktpdC9Tb3VyY2UvcGxhdGZvcm0vYXVkaW8vSUlSRmlsdGVyLmNwcHxDaHJvbWl1bSdzIElJUkZpbHRlcn0uXG5leHBvcnQgY29uc3QgZmlsdGVyQnVmZmVyID0gKGZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXIsIHlCdWZmZXIsIGJ1ZmZlckluZGV4LCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpID0+IHtcbiAgICBjb25zdCBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aDtcbiAgICBsZXQgaSA9IGJ1ZmZlckluZGV4O1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRMZW5ndGg7IGogKz0gMSkge1xuICAgICAgICBsZXQgeSA9IGZlZWRmb3J3YXJkWzBdICogaW5wdXRbal07XG4gICAgICAgIGZvciAobGV0IGsgPSAxOyBrIDwgbWluTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHggPSAoaSAtIGspICYgKGJ1ZmZlckxlbmd0aCAtIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgICAgIHkgKz0gZmVlZGZvcndhcmRba10gKiB4QnVmZmVyW3hdO1xuICAgICAgICAgICAgeSAtPSBmZWVkYmFja1trXSAqIHlCdWZmZXJbeF07XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgayA9IG1pbkxlbmd0aDsgayA8IGZlZWRmb3J3YXJkTGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgICAgICAgIHkgKz0gZmVlZGZvcndhcmRba10gKiB4QnVmZmVyWyhpIC0gaykgJiAoYnVmZmVyTGVuZ3RoIC0gMSldOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBrID0gbWluTGVuZ3RoOyBrIDwgZmVlZGJhY2tMZW5ndGg7IGsgKz0gMSkge1xuICAgICAgICAgICAgeSAtPSBmZWVkYmFja1trXSAqIHlCdWZmZXJbKGkgLSBrKSAmIChidWZmZXJMZW5ndGggLSAxKV07IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6bm8tYml0d2lzZVxuICAgICAgICB9XG4gICAgICAgIHhCdWZmZXJbaV0gPSBpbnB1dFtqXTtcbiAgICAgICAgeUJ1ZmZlcltpXSA9IHk7XG4gICAgICAgIGkgPSAoaSArIDEpICYgKGJ1ZmZlckxlbmd0aCAtIDEpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLWJpdHdpc2VcbiAgICAgICAgb3V0cHV0W2pdID0geTtcbiAgICB9XG4gICAgcmV0dXJuIGk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZmlsdGVyLWJ1ZmZlci5qcy5tYXAiLCJpbXBvcnQgeyBmaWx0ZXJCdWZmZXIgfSBmcm9tICcuLi9oZWxwZXJzL2ZpbHRlci1idWZmZXInO1xuaW1wb3J0IHsgaXNPd25lZEJ5Q29udGV4dCB9IGZyb20gJy4uL2hlbHBlcnMvaXMtb3duZWQtYnktY29udGV4dCc7XG5jb25zdCBmaWx0ZXJGdWxsQnVmZmVyID0gKHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBmZWVkYmFjaywgZmVlZGZvcndhcmQpID0+IHtcbiAgICBjb25zdCBjb252ZXJ0ZWRGZWVkYmFjayA9IGZlZWRiYWNrIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGJhY2sgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRiYWNrKTtcbiAgICBjb25zdCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCA9IGZlZWRmb3J3YXJkIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGZvcndhcmQgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRmb3J3YXJkKTtcbiAgICBjb25zdCBmZWVkYmFja0xlbmd0aCA9IGNvbnZlcnRlZEZlZWRiYWNrLmxlbmd0aDtcbiAgICBjb25zdCBmZWVkZm9yd2FyZExlbmd0aCA9IGNvbnZlcnRlZEZlZWRmb3J3YXJkLmxlbmd0aDtcbiAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbihmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmRMZW5ndGgpO1xuICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSAhPT0gMSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZlZWRiYWNrTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnZlcnRlZEZlZWRmb3J3YXJkW2ldIC89IGNvbnZlcnRlZEZlZWRiYWNrWzBdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmVlZGZvcndhcmRMZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgY29udmVydGVkRmVlZGJhY2tbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgYnVmZmVyTGVuZ3RoID0gMzI7XG4gICAgY29uc3QgeEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICBjb25zdCB5QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShidWZmZXJMZW5ndGgpO1xuICAgIGNvbnN0IGZpbHRlcmVkQnVmZmVyID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jcmVhdGVCdWZmZXIocmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVscywgcmVuZGVyZWRCdWZmZXIubGVuZ3RoLCByZW5kZXJlZEJ1ZmZlci5zYW1wbGVSYXRlKTtcbiAgICBjb25zdCBudW1iZXJPZkNoYW5uZWxzID0gcmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mQ2hhbm5lbHM7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBpbnB1dCA9IHJlbmRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBmaWx0ZXJlZEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgeEJ1ZmZlci5maWxsKDApO1xuICAgICAgICB5QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgIGZpbHRlckJ1ZmZlcihjb252ZXJ0ZWRGZWVkYmFjaywgZmVlZGJhY2tMZW5ndGgsIGNvbnZlcnRlZEZlZWRmb3J3YXJkLCBmZWVkZm9yd2FyZExlbmd0aCwgbWluTGVuZ3RoLCB4QnVmZmVyLCB5QnVmZmVyLCAwLCBidWZmZXJMZW5ndGgsIGlucHV0LCBvdXRwdXQpO1xuICAgIH1cbiAgICByZXR1cm4gZmlsdGVyZWRCdWZmZXI7XG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gKGZlZWRiYWNrLCBmZWVkZm9yd2FyZCkgPT4ge1xuICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBsZXQgZmlsdGVyZWRCdWZmZXJQcm9taXNlID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlQXVkaW9Ob2RlID0gYXN5bmMgKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgICAgICBsZXQgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVJSVJGaWx0ZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlSUlSRmlsdGVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZUlJUkZpbHRlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICM5OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBJSVJGaWx0ZXJOb2Rlcy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUlJUkZpbHRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgICAgICAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIW5hdGl2ZUlJUkZpbHRlck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBkZWZpbmVzIHRoZSBwYXJhbWV0ZXJzIG9mIGNyZWF0ZUlJUkZpbHRlcigpIGFzIGFycmF5cyBvZiBudW1iZXJzLlxuICAgICAgICAgICAgICAgIG5hdGl2ZUlJUkZpbHRlck5vZGUgPSBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmNyZWF0ZUlJUkZpbHRlcihmZWVkZm9yd2FyZCwgZmVlZGJhY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPT09IG51bGwgPyBuYXRpdmVJSVJGaWx0ZXJOb2RlIDogbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmlsdGVyZWRCdWZmZXJQcm9taXNlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIE9mZmxpbmVBdWRpb0NvbnRleHQgY29uc3RydWN0b3IuJyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzQ3OiBUaGUgQXVkaW9EZXN0aW5hdGlvbk5vZGUgaW4gU2FmYXJpIGdldHMgbm90IGluaXRpYWxpemVkIGNvcnJlY3RseS5cbiAgICAgICAgICAgICAgICAgICAgcHJveHkuY29udGV4dC5kZXN0aW5hdGlvbi5jaGFubmVsQ291bnQsIFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3OiBTYWZhcmkgZG9lcyBub3QgeWV0IGV4cG9zZSB0aGUgbGVuZ3RoLlxuICAgICAgICAgICAgICAgICAgICBwcm94eS5jb250ZXh0Lmxlbmd0aCwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWRCdWZmZXJQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCwgcGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVuZGVyZWRCdWZmZXIgPSBhd2FpdCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmaWx0ZXJGdWxsQnVmZmVyKHJlbmRlcmVkQnVmZmVyLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBmZWVkYmFjaywgZmVlZGZvcndhcmQpO1xuICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZEJ1ZmZlciA9IGF3YWl0IGZpbHRlcmVkQnVmZmVyUHJvbWlzZTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gZmlsdGVyZWRCdWZmZXI7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KDApO1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlSUlSRmlsdGVyTm9kZSk7XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlSUlSRmlsdGVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVBdWRpb05vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1paXItZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24gfSBmcm9tICcuLi9ndWFyZHMvYXVkaW8tbm9kZS1vdXRwdXQtY29ubmVjdGlvbic7XG5leHBvcnQgY29uc3QgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeSA9IChjeWNsZUNvdW50ZXJzLCBkaXNjb25uZWN0TmF0aXZlQXVkaW9Ob2RlRnJvbU5hdGl2ZUF1ZGlvTm9kZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgZ2V0TmF0aXZlQXVkaW9QYXJhbSwgaXNBY3RpdmVBdWRpb05vZGUpID0+IHtcbiAgICByZXR1cm4gKGlzT2ZmbGluZSkgPT4ge1xuICAgICAgICByZXR1cm4gKGF1ZGlvTm9kZSwgY291bnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGN5Y2xlQ291bnRlciA9IGN5Y2xlQ291bnRlcnMuZ2V0KGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICBpZiAoY3ljbGVDb3VudGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzT2ZmbGluZSAmJiBpc0FjdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShhdWRpb05vZGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB7IG91dHB1dHMgfSA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3Qgb3V0cHV0IG9mIG91dHB1dHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0F1ZGlvTm9kZU91dHB1dENvbm5lY3Rpb24ob3V0cHV0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9Ob2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKG91dHB1dFswXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUobmF0aXZlU291cmNlQXVkaW9Ob2RlLCBuYXRpdmVEZXN0aW5hdGlvbkF1ZGlvTm9kZSwgb3V0cHV0WzFdLCBvdXRwdXRbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlRGVzdGluYXRpb25BdWRpb1BhcmFtID0gZ2V0TmF0aXZlQXVkaW9QYXJhbShvdXRwdXRbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZVNvdXJjZUF1ZGlvTm9kZS5kaXNjb25uZWN0KG5hdGl2ZURlc3RpbmF0aW9uQXVkaW9QYXJhbSwgb3V0cHV0WzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjeWNsZUNvdW50ZXJzLnNldChhdWRpb05vZGUsIGNvdW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGN5Y2xlQ291bnRlcnMuc2V0KGF1ZGlvTm9kZSwgY3ljbGVDb3VudGVyICsgY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5jcmVtZW50LWN5Y2xlLWNvdW50ZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQgPSAoY29udGV4dFN0b3JlLCBpc05hdGl2ZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGNvbnRleHRTdG9yZS5nZXQoYW55dGhpbmcpO1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgfHwgaXNOYXRpdmVBdWRpb0NvbnRleHQoYW55dGhpbmcpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtYW55LWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzQW55QXVkaW9Ob2RlID0gKGF1ZGlvTm9kZVN0b3JlLCBpc05hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IGF1ZGlvTm9kZVN0b3JlLmhhcyhhbnl0aGluZykgfHwgaXNOYXRpdmVBdWRpb05vZGUoYW55dGhpbmcpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc0FueUF1ZGlvUGFyYW0gPSAoYXVkaW9QYXJhbVN0b3JlLCBpc05hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiBhdWRpb1BhcmFtU3RvcmUuaGFzKGFueXRoaW5nKSB8fCBpc05hdGl2ZUF1ZGlvUGFyYW0oYW55dGhpbmcpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1hdWRpby1wYXJhbS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNBbnlPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNvbnRleHRTdG9yZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gY29udGV4dFN0b3JlLmdldChhbnl0aGluZyk7XG4gICAgICAgIHJldHVybiBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkgfHwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGFueXRoaW5nKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWFueS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgIT09IG51bGwgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVJc05hdGl2ZUF1ZGlvTm9kZSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB3aW5kb3cgIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvdy5BdWRpb05vZGUgPT09ICdmdW5jdGlvbicgJiYgYW55dGhpbmcgaW5zdGFuY2VvZiB3aW5kb3cuQXVkaW9Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtbmF0aXZlLWF1ZGlvLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQXVkaW9QYXJhbSA9ICh3aW5kb3cpID0+IHtcbiAgICByZXR1cm4gKGFueXRoaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiB3aW5kb3cgIT09IG51bGwgJiYgdHlwZW9mIHdpbmRvdy5BdWRpb1BhcmFtID09PSAnZnVuY3Rpb24nICYmIGFueXRoaW5nIGluc3RhbmNlb2Ygd2luZG93LkF1ZGlvUGFyYW07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtYXVkaW8tcGFyYW0uanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzTmF0aXZlQ29udGV4dCA9IChpc05hdGl2ZUF1ZGlvQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChhbnl0aGluZykgPT4ge1xuICAgICAgICByZXR1cm4gaXNOYXRpdmVBdWRpb0NvbnRleHQoYW55dGhpbmcpIHx8IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChhbnl0aGluZyk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pcy1uYXRpdmUtY29udGV4dC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoYW55dGhpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBhbnl0aGluZyBpbnN0YW5jZW9mIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcjtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLW5hdGl2ZS1vZmZsaW5lLWF1ZGlvLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCA9ICh3aW5kb3cpID0+IHdpbmRvdyAhPT0gbnVsbCAmJiB3aW5kb3cuaXNTZWN1cmVDb250ZXh0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aXMtc2VjdXJlLWNvbnRleHQuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgIHJldHVybiBjbGFzcyBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgLy8gQnVnICMxNzE6IFNhZmFyaSBhbGxvd3MgdG8gY3JlYXRlIGEgTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSBuYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IG1lZGlhRWxlbWVudCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUubWVkaWFFbGVtZW50O1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2Vycydcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICAvLyBCdWcgIzE3MzogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlKG5hdGl2ZUNvbnRleHQsIG1lcmdlZE9wdGlvbnMpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSA9IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHN0cmVhbSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlLnN0cmVhbTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTcyOiBTYWZhcmkgYWxsb3dzIHRvIGNyZWF0ZSBhIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIHdpdGggYW4gT2ZmbGluZUF1ZGlvQ29udGV4dC5cbiAgICAgICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCB0cnVlLCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSwgbnVsbCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBtZWRpYVN0cmVhbSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZS5tZWRpYVN0cmVhbTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIHN1cGVyKGNvbnRleHQsIHRydWUsIG5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIG51bGwpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgaXNWYWxpZExhdGVuY3lIaW50IH0gZnJvbSAnLi4vaGVscGVycy9pcy12YWxpZC1sYXRlbmN5LWhpbnQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1pbmltYWxBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZVVua25vd25FcnJvciwgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgTWluaW1hbEF1ZGlvQ29udGV4dCBleHRlbmRzIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBuYXRpdmVBdWRpb0NvbnRleHQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzE5MiBTYWZhcmkgZG9lcyB0aHJvdyBhIFN5bnRheEVycm9yIGlmIHRoZSBzYW1wbGVSYXRlIGlzIG5vdCBzdXBwb3J0ZWQuXG4gICAgICAgICAgICAgICAgaWYgKGVyci5jb2RlID09PSAxMiAmJiBlcnIubWVzc2FnZSA9PT0gJ3NhbXBsZVJhdGUgaXMgbm90IGluIHJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzEzMSBTYWZhcmkgcmV0dXJucyBudWxsIHdoZW4gdGhlcmUgYXJlIGZvdXIgb3RoZXIgQXVkaW9Db250ZXh0cyBydW5uaW5nIGFscmVhZHkuXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0ID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlVW5rbm93bkVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzUxIE9ubHkgQ2hyb21lIGFuZCBFZGdlIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiBsYXRlbmN5SGludCBpcyBpbnZhbGlkLlxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkTGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgcHJvdmlkZWQgdmFsdWUgJyR7b3B0aW9ucy5sYXRlbmN5SGludH0nIGlzIG5vdCBhIHZhbGlkIGVudW0gdmFsdWUgb2YgdHlwZSBBdWRpb0NvbnRleHRMYXRlbmN5Q2F0ZWdvcnkuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBCdWcgIzE1MCBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBzZXR0aW5nIHRoZSBzYW1wbGVSYXRlLlxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2FtcGxlUmF0ZSAhPT0gdW5kZWZpbmVkICYmIG5hdGl2ZUF1ZGlvQ29udGV4dC5zYW1wbGVSYXRlICE9PSBvcHRpb25zLnNhbXBsZVJhdGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlQXVkaW9Db250ZXh0LCAyKTtcbiAgICAgICAgICAgIGNvbnN0IHsgbGF0ZW5jeUhpbnQgfSA9IG9wdGlvbnM7XG4gICAgICAgICAgICBjb25zdCB7IHNhbXBsZVJhdGUgfSA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEB0b2RvIFRoZSB2YWx1ZXMgZm9yICdiYWxhbmNlZCcsICdpbnRlcmFjdGl2ZScgYW5kICdwbGF5YmFjaycgYXJlIGp1c3QgY29waWVkIGZyb20gQ2hyb21lJ3MgaW1wbGVtZW50YXRpb24uXG4gICAgICAgICAgICB0aGlzLl9iYXNlTGF0ZW5jeSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIG5hdGl2ZUF1ZGlvQ29udGV4dC5iYXNlTGF0ZW5jeSA9PT0gJ251bWJlcidcbiAgICAgICAgICAgICAgICAgICAgPyBuYXRpdmVBdWRpb0NvbnRleHQuYmFzZUxhdGVuY3lcbiAgICAgICAgICAgICAgICAgICAgOiBsYXRlbmN5SGludCA9PT0gJ2JhbGFuY2VkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgPyA1MTIgLyBzYW1wbGVSYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAnaW50ZXJhY3RpdmUnIHx8IGxhdGVuY3lIaW50ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IDI1NiAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxhdGVuY3lIaW50ID09PSAncGxheWJhY2snXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gMTAyNCAvIHNhbXBsZVJhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAvKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIEB0b2RvIFRoZSBtaW4gKDI1NikgYW5kIG1heCAoMTYzODQpIHZhbHVlcyBhcmUgdGFrZW4gZnJvbSB0aGUgYWxsb3dlZCBidWZmZXJTaXplIHZhbHVlcyBvZiBhXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogU2NyaXB0UHJvY2Vzc29yTm9kZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChNYXRoLm1heCgyLCBNYXRoLm1pbigxMjgsIE1hdGgucm91bmQoKGxhdGVuY3lIaW50ICogc2FtcGxlUmF0ZSkgLyAxMjgpKSkgKiAxMjgpIC8gc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dCA9IG5hdGl2ZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTg4OiBTYWZhcmkgd2lsbCBzZXQgdGhlIGNvbnRleHQncyBzdGF0ZSB0byAnaW50ZXJydXB0ZWQnIGluIGNhc2UgdGhlIHVzZXIgc3dpdGNoZXMgdGFicy5cbiAgICAgICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUuZ2Fpbi52YWx1ZSA9IDFlLTM3O1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmNvbm5lY3QodGhpcy5fbmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQXVkaW9Db250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlR2Fpbk5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBCdWcgIzM0OiBDaHJvbWUgYW5kIEVkZ2UgcHJldGVuZCB0byBiZSBydW5uaW5nIHJpZ2h0IGF3YXksIGJ1dCBmaXJlIGFuIG9uc3RhdGVjaGFuZ2UgZXZlbnQgd2hlbiB0aGUgc3RhdGUgYWN0dWFsbHkgY2hhbmdlc1xuICAgICAgICAgICAgICogdG8gJ3J1bm5pbmcnLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBpZiAobmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9ICdzdXNwZW5kZWQnO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJldm9rZVN0YXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmV2b2tlU3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBiYXNlTGF0ZW5jeSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9iYXNlTGF0ZW5jeTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgIT09IG51bGwgPyB0aGlzLl9zdGF0ZSA6IHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBjbG9zZSgpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMzU6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIEF1ZGlvQ29udGV4dCB3YXMgY2xvc2VkIGJlZm9yZS5cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEJ1ZyAjMzQ6IElmIHRoZSBzdGF0ZSB3YXMgc2V0IHRvIHN1c3BlbmRlZCBiZWZvcmUgaXQgc2hvdWxkIGJlIHJldm9rZWQgbm93LlxuICAgICAgICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSAnc3VzcGVuZGVkJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuY2xvc2UoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlR2Fpbk5vZGUgIT09IG51bGwgJiYgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVhY3RpdmF0ZUF1ZGlvR3JhcGgodGhpcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bWUoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09ICdzdXNwZW5kZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzb2x2ZVByb21pc2UgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCByZXNvbHZlUHJvbWlzZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LnN0YXRlID09PSAncnVubmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc3VtZSgpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgcmVzb2x2ZVByb21pc2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUF1ZGlvQ29udGV4dC5yZXN1bWUoKS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM1NTogQ2hyb21lIGFuZCBFZGdlIGRvIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciBpbnN0ZWFkIG9mIGFuIEludmFsaWRTdGF0ZUVycm9yLlxuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjNTY6IFNhZmFyaSBpbnZva2VzIHRoZSBjYXRjaCBoYW5kbGVyIGJ1dCB3aXRob3V0IGFuIGVycm9yLlxuICAgICAgICAgICAgICAgIGlmIChlcnIgPT09IHVuZGVmaW5lZCB8fCBlcnIuY29kZSA9PT0gMTUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc3VzcGVuZCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVBdWRpb0NvbnRleHQuc3VzcGVuZCgpLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzU2OiBTYWZhcmkgaW52b2tlcyB0aGUgY2F0Y2ggaGFuZGxlciBidXQgd2l0aG91dCBhbiBlcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pbmltYWwtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBDT05URVhUX1NUT1JFIH0gZnJvbSAnLi4vZ2xvYmFscyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IChhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb0xpc3RlbmVyLCBldmVudFRhcmdldENvbnN0cnVjdG9yLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUsIHdyYXBFdmVudExpc3RlbmVyKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxCYXNlQXVkaW9Db250ZXh0IGV4dGVuZHMgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKF9uYXRpdmVDb250ZXh0LCBudW1iZXJPZkNoYW5uZWxzKSB7XG4gICAgICAgICAgICBzdXBlcihfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0ID0gX25hdGl2ZUNvbnRleHQ7XG4gICAgICAgICAgICBDT05URVhUX1NUT1JFLnNldCh0aGlzLCBfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KF9uYXRpdmVDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgIHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUuc2V0KF9uYXRpdmVDb250ZXh0LCBuZXcgU2V0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fZGVzdGluYXRpb24gPSBuZXcgYXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3Rvcih0aGlzLCBudW1iZXJPZkNoYW5uZWxzKTtcbiAgICAgICAgICAgIHRoaXMuX2xpc3RlbmVyID0gY3JlYXRlQXVkaW9MaXN0ZW5lcih0aGlzLCBfbmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLl9vbnN0YXRlY2hhbmdlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgY3VycmVudFRpbWUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5jdXJyZW50VGltZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgZGVzdGluYXRpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGVzdGluYXRpb247XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xpc3RlbmVyO1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbnN0YXRlY2hhbmdlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uc3RhdGVjaGFuZ2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uc3RhdGVjaGFuZ2UodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVDb250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSB3cmFwcGVkTGlzdGVuZXI7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPblN0YXRlQ2hhbmdlID0gdGhpcy5fbmF0aXZlQ29udGV4dC5vbnN0YXRlY2hhbmdlO1xuICAgICAgICAgICAgdGhpcy5fb25zdGF0ZWNoYW5nZSA9IG5hdGl2ZU9uU3RhdGVDaGFuZ2UgIT09IG51bGwgJiYgbmF0aXZlT25TdGF0ZUNoYW5nZSA9PT0gd3JhcHBlZExpc3RlbmVyID8gdmFsdWUgOiBuYXRpdmVPblN0YXRlQ2hhbmdlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlQ29udGV4dC5zdGF0ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RQcm9taXNlU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgLy8gVGhpcyAxMiBudW1iZXJzIHJlcHJlc2VudCB0aGUgNDggYnl0ZXMgb2YgYW4gZW1wdHkgV0FWRSBmaWxlIHdpdGggYSBzaW5nbGUgc2FtcGxlLlxuICAgIGNvbnN0IHVpbnQzMkFycmF5ID0gbmV3IFVpbnQzMkFycmF5KFsxMTc5MDExNDEwLCA0MCwgMTE2MzI4MDcyNywgNTQ0NTAxMDk0LCAxNiwgMTMxMDczLCA0NDEwMCwgMTc2NDAwLCAxMDQ4NTgwLCAxNjM1MDE3MDYwLCA0LCAwXSk7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gQnVnICMxOiBTYWZhcmkgcmVxdWlyZXMgYSBzdWNjZXNzQ2FsbGJhY2suXG4gICAgICAgIGNvbnN0IHByb21pc2UgPSBuYXRpdmVDb250ZXh0LmRlY29kZUF1ZGlvRGF0YSh1aW50MzJBcnJheS5idWZmZXIsICgpID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSB0aGUgc3VjY2VzcyBjYWxsYmFjay5cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwcm9taXNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBwcm9taXNlLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAgIC8vIElnbm9yZSByZWplY3RlZCBlcnJvcnMuXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1wcm9taXNlLXN1cHBvcnQuanMubWFwIiwiaW1wb3J0IHsgZGVhY3RpdmF0ZUF1ZGlvR3JhcGggfSBmcm9tICcuLi9oZWxwZXJzL2RlYWN0aXZhdGUtYXVkaW8tZ3JhcGgnO1xuaW1wb3J0IHsgdGVzdFByb21pc2VTdXBwb3J0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LXByb21pc2Utc3VwcG9ydCc7XG5jb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgbnVtYmVyT2ZDaGFubmVsczogMVxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHN0YXJ0UmVuZGVyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIE1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0IGV4dGVuZHMgbWluaW1hbEJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vICMyMSBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyBhbmQgdGhlcmVmb3JlIHdvdWxkIGZpcmUgdGhlIHN0YXRlY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgcHJvbWlzZSBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXlTdGF0ZUNoYW5nZUV2ZW50O1xuICAgICAgICAgICAgICAgIH0pKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IG51bGwgPyB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXRlIDogdGhpcy5fc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSZW5kZXJpbmcoKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5ICYgIzU5OiBJdCBpcyB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlIHRoYXQgc3RhcnRSZW5kZXJpbmcoKSB3aWxsIGZpcnN0IHJlbmRlciBhIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LiBUaGVyZWZvcmVcbiAgICAgICAgICAgICAqIHRoZSBzdGF0ZSBvZiB0aGUgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCBtaWdodCBubyB0cmFuc2l0aW9uIHRvIHJ1bm5pbmcgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAncnVubmluZyc7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnRSZW5kZXJpbmcodGhpcy5kZXN0aW5hdGlvbiwgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU1vbml0b3JDb25uZWN0aW9ucyA9IChpbnNlcnRFbGVtZW50SW5TZXQsIGlzTmF0aXZlQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb05vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpID0+IHtcbiAgICAgICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5jb25uZWN0ID0gKChjb25uZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6aW52YWxpZC12b2lkIG5vLWluZmVycmFibGUtdHlwZXNcbiAgICAgICAgICAgIHJldHVybiAoZGVzdGluYXRpb24sIG91dHB1dCA9IDAsIGlucHV0ID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHdhc0Rpc2Nvbm5lY3RlZCA9IGNvbm5lY3Rpb25zLnNpemUgPT09IDA7XG4gICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGNvbm5lY3Rpb25zLCBbZGVzdGluYXRpb24sIG91dHB1dCwgaW5wdXRdLCAoY29ubmVjdGlvbikgPT4gY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb24gJiYgY29ubmVjdGlvblsxXSA9PT0gb3V0cHV0ICYmIGNvbm5lY3Rpb25bMl0gPT09IGlucHV0LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdhc0Rpc2Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2hlbkNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXN0aW5hdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29ubmVjdC5jYWxsKG5hdGl2ZUF1ZGlvTm9kZSwgZGVzdGluYXRpb24sIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgaW5zZXJ0RWxlbWVudEluU2V0KGNvbm5lY3Rpb25zLCBbZGVzdGluYXRpb24sIG91dHB1dF0sIChjb25uZWN0aW9uKSA9PiBjb25uZWN0aW9uWzBdID09PSBkZXN0aW5hdGlvbiAmJiBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmICh3YXNEaXNjb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hlbkNvbm5lY3RlZCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShuYXRpdmVBdWRpb05vZGUuY29ubmVjdCk7XG4gICAgICAgIG5hdGl2ZUF1ZGlvTm9kZS5kaXNjb25uZWN0ID0gKChkaXNjb25uZWN0KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCwgaW5wdXQpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB3YXNDb25uZWN0ZWQgPSBjb25uZWN0aW9ucy5zaXplID4gMDtcbiAgICAgICAgICAgICAgICBpZiAoZGVzdGluYXRpb25Pck91dHB1dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuYXBwbHkobmF0aXZlQXVkaW9Ob2RlKTtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRlc3RpbmF0aW9uT3JPdXRwdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDEgYXJndW1lbnQgeWV0LlxuICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0KTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvblsxXSA9PT0gZGVzdGluYXRpb25Pck91dHB1dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25zLmRlbGV0ZShjb25uZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlKGRlc3RpbmF0aW9uT3JPdXRwdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9Ob2RlLCBkZXN0aW5hdGlvbk9yT3V0cHV0LCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEB0b2RvIFR5cGVTY3JpcHQgY2Fubm90IGluZmVyIHRoZSBvdmVybG9hZGVkIHNpZ25hdHVyZSB3aXRoIDIgYXJndW1lbnRzIHlldC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3QuY2FsbChuYXRpdmVBdWRpb05vZGUsIGRlc3RpbmF0aW9uT3JPdXRwdXQsIG91dHB1dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY29ubmVjdGlvblswXSA9PT0gZGVzdGluYXRpb25Pck91dHB1dCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvdXRwdXQgPT09IHVuZGVmaW5lZCB8fCBjb25uZWN0aW9uWzFdID09PSBvdXRwdXQpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlucHV0ID09PSB1bmRlZmluZWQgfHwgY29ubmVjdGlvblsyXSA9PT0gaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGlvbnMuZGVsZXRlKGNvbm5lY3Rpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGlzRGlzY29ubmVjdGVkID0gY29ubmVjdGlvbnMuc2l6ZSA9PT0gMDtcbiAgICAgICAgICAgICAgICBpZiAod2FzQ29ubmVjdGVkICYmIGlzRGlzY29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdoZW5EaXNjb25uZWN0ZWQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShuYXRpdmVBdWRpb05vZGUuZGlzY29ubmVjdCk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb05vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tb25pdG9yLWNvbm5lY3Rpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zLCBvcHRpb24pID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbb3B0aW9uXTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbmF0aXZlQXVkaW9Ob2RlW29wdGlvbl0pIHtcbiAgICAgICAgbmF0aXZlQXVkaW9Ob2RlW29wdGlvbl0gPSB2YWx1ZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgPSAobmF0aXZlQXVkaW9Ob2RlLCBvcHRpb25zKSA9PiB7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxDb3VudCcpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsICdjaGFubmVsQ291bnRNb2RlJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUF1ZGlvTm9kZSwgb3B0aW9ucywgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWFzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zLmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQgPSAobmF0aXZlQW5hbHlzZXJOb2RlKSA9PiB7XG4gICAgcmV0dXJuIHR5cGVvZiBuYXRpdmVBbmFseXNlck5vZGUuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YSA9PT0gJ2Z1bmN0aW9uJztcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kID0gKG5hdGl2ZUFuYWx5c2VyTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRGbG9hdFRpbWVEb21haW5EYXRhID0gKGFycmF5KSA9PiB7XG4gICAgICAgIGNvbnN0IGJ5dGVUaW1lRG9tYWluRGF0YSA9IG5ldyBVaW50OEFycmF5KGFycmF5Lmxlbmd0aCk7XG4gICAgICAgIG5hdGl2ZUFuYWx5c2VyTm9kZS5nZXRCeXRlVGltZURvbWFpbkRhdGEoYnl0ZVRpbWVEb21haW5EYXRhKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5tYXgoYnl0ZVRpbWVEb21haW5EYXRhLmxlbmd0aCwgbmF0aXZlQW5hbHlzZXJOb2RlLmZmdFNpemUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBhcnJheVtpXSA9IChieXRlVGltZURvbWFpbkRhdGFbaV0gLSAxMjgpICogMC4wMDc4MTI1O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcnJheTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYW5hbHlzZXItbm9kZS1nZXQtZmxvYXQtdGltZS1kb21haW4tZGF0YS1tZXRob2QuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1hbmFseXNlci1ub2RlLWdldC1mbG9hdC10aW1lLWRvbWFpbi1kYXRhLW1ldGhvZC1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWFuYWx5c2VyLW5vZGUtZ2V0LWZsb2F0LXRpbWUtZG9tYWluLWRhdGEtbWV0aG9kJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5ID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5kZXhTaXplRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQW5hbHlzZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgICAgICAvLyBCdWcgIzM3OiBGaXJlZm94IGRvZXMgbm90IGNyZWF0ZSBhbiBBbmFseXNlck5vZGUgd2l0aCB0aGUgZGVmYXVsdCBwcm9wZXJ0aWVzLlxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIEJ1ZyAjMTE4OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgbWF4RGVjaWJlbHMgaXMgbm90IG1vcmUgdGhhbiBtaW5EZWNpYmVscy5cbiAgICAgICAgaWYgKCEob3B0aW9ucy5tYXhEZWNpYmVscyA+IG9wdGlvbnMubWluRGVjaWJlbHMpKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdmZnRTaXplJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBbmFseXNlck5vZGUsIG9wdGlvbnMsICdtYXhEZWNpYmVscycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQW5hbHlzZXJOb2RlLCBvcHRpb25zLCAnbWluRGVjaWJlbHMnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUFuYWx5c2VyTm9kZSwgb3B0aW9ucywgJ3Ntb290aGluZ1RpbWVDb25zdGFudCcpO1xuICAgICAgICAvLyBCdWcgIzM2OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBnZXRGbG9hdFRpbWVEb21haW5EYXRhKCkgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QW5hbHlzZXJOb2RlR2V0RmxvYXRUaW1lRG9tYWluRGF0YU1ldGhvZFN1cHBvcnQsICgpID0+IHRlc3RBbmFseXNlck5vZGVHZXRGbG9hdFRpbWVEb21haW5EYXRhTWV0aG9kU3VwcG9ydChuYXRpdmVBbmFseXNlck5vZGUpKSkge1xuICAgICAgICAgICAgd3JhcEFuYWx5c2VyTm9kZUdldEZsb2F0VGltZURvbWFpbkRhdGFNZXRob2QobmF0aXZlQW5hbHlzZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmF0aXZlQW5hbHlzZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAod2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb0J1ZmZlcicpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuQXVkaW9CdWZmZXI7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1idWZmZXItY29uc3RydWN0b3IuanMubWFwIiwiZXhwb3J0IGNvbnN0IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSA9IChuYXRpdmVBdWRpb05vZGUsIG9wdGlvbnMsIGF1ZGlvUGFyYW0pID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbYXVkaW9QYXJhbV07XG4gICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG5hdGl2ZUF1ZGlvTm9kZVthdWRpb1BhcmFtXS52YWx1ZSkge1xuICAgICAgICBuYXRpdmVBdWRpb05vZGVbYXVkaW9QYXJhbV0udmFsdWUgPSB2YWx1ZTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9YXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yIH0gZnJvbSAnLi4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMgPSAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0ID0gKChzdGFydCkgPT4ge1xuICAgICAgICBsZXQgaXNTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGlmIChpc1NjaGVkdWxlZCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICBpc1NjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyA9IChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUpID0+IHtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RhcnQgPSAoKHN0YXJ0KSA9PiB7XG4gICAgICAgIHJldHVybiAod2hlbiA9IDAsIG9mZnNldCA9IDAsIGR1cmF0aW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAoKHR5cGVvZiBkdXJhdGlvbiA9PT0gJ251bWJlcicgJiYgZHVyYXRpb24gPCAwKSB8fCBvZmZzZXQgPCAwIHx8IHdoZW4gPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgcGFyYW1ldGVycyBjYW4ndCBiZSBuZWdhdGl2ZS5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBAdG9kbyBUeXBlU2NyaXB0IGNhbm5vdCBpbmZlciB0aGUgb3ZlcmxvYWRlZCBzaWduYXR1cmUgd2l0aCAzIGFyZ3VtZW50cyB5ZXQuXG4gICAgICAgICAgICBzdGFydC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbiwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgfSkobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0YXJ0KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgPSAobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlKSA9PiB7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLnN0b3AgPSAoKHN0b3ApID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCkgPT4ge1xuICAgICAgICAgICAgaWYgKHdoZW4gPCAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgcGFyYW1ldGVyIGNhbid0IGJlIG5lZ2F0aXZlLlwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wKTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjYWNoZVRlc3RSZXN1bHQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGxpbmcsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyLCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBvcHRpb25zLCAncGxheWJhY2tSYXRlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdidWZmZXInKTtcbiAgICAgICAgLy8gQnVnICMxNDk6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgc3VwcG9ydCB0aGUgZGV0dW5lIEF1ZGlvUGFyYW0uXG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wRW5kJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIG9wdGlvbnMsICdsb29wU3RhcnQnKTtcbiAgICAgICAgLy8gQnVnICM2OTogU2FmYXJpIGRvZXMgYWxsb3cgY2FsbHMgdG8gc3RhcnQoKSBvZiBhbiBhbHJlYWR5IHNjaGVkdWxlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE1NCAmICMxNTU6IFNhZmFyaSBkb2VzIG5vdCBoYW5kbGUgb2Zmc2V0cyB3aGljaCBhcmUgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1wbGluZyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTYyOiBTYWZhcmkgZG9lcyB0aHJvdyBhbiBlcnJvciB3aGVuIHN0b3AoKSBpcyBjYWxsZWQgb24gYW4gQXVkaW9CdWZmZXJTb3VyY2VOb2RlIHdoaWNoIGhhcyBubyBidWZmZXIgYXNzaWduZWQgdG8gaXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTk6IFNhZmFyaSBkb2VzIG5vdCBpZ25vcmUgY2FsbHMgdG8gc3RvcCgpIG9mIGFuIGFscmVhZHkgc3RvcHBlZCBBdWRpb0J1ZmZlclNvdXJjZU5vZGUuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCAoKSA9PiB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQobmF0aXZlQ29udGV4dCkpKSB7XG4gICAgICAgICAgICB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ0F1ZGlvQ29udGV4dCcpKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuQXVkaW9Db250ZXh0O1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCd3ZWJraXRBdWRpb0NvbnRleHQnKSA/IHdpbmRvdy53ZWJraXRBdWRpb0NvbnRleHQgOiBudWxsO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgY2hhbm5lbENvdW50LCBpc05vZGVPZk5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVDb250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICAvLyBCdWcgIzEzMjogU2FmYXJpIGRvZXMgbm90IGhhdmUgdGhlIGNvcnJlY3QgY2hhbm5lbENvdW50LlxuICAgICAgICBpZiAobmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ICE9PSBjaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY5OiBTYWZhcmkgdGhyb3dzIGFuIGVycm9yIG9uIGVhY2ggYXR0ZW1wdCB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzgzOiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnRNb2RlLlxuICAgICAgICBpZiAoaXNOb2RlT2ZOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ICYmIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgIT09ICdleHBsaWNpdCcpIHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDc6IFRoZSBBdWRpb0Rlc3RpbmF0aW9uTm9kZSBpbiBTYWZhcmkgZG9lcyBub3QgaW5pdGlhbGl6ZSB0aGUgbWF4Q2hhbm5lbENvdW50IHByb3BlcnR5IGNvcnJlY3RseS5cbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLCAnbWF4Q2hhbm5lbENvdW50Jywge1xuICAgICAgICAgICAgICAgIHZhbHVlOiBjaGFubmVsQ291bnRcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTY4OiBObyBicm93c2VyIGRvZXMgeWV0IGhhdmUgYW4gQXVkaW9EZXN0aW5hdGlvbk5vZGUgd2l0aCBhbiBvdXRwdXQuXG4gICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICB9KTtcbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKGdhaW5Ob2RlLCAnY2hhbm5lbENvdW50JywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwoZ2Fpbk5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKGdhaW5Ob2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTY5OiBTYWZhcmkgdGhyb3dzIGFuIGVycm9yIG9uIGVhY2ggYXR0ZW1wdCB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiBuYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZS5tYXhDaGFubmVsQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChnYWluTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgc2V0LmNhbGwoZ2Fpbk5vZGUsIHZhbHVlKTtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhnYWluTm9kZSwgJ2NoYW5uZWxJbnRlcnByZXRhdGlvbicsIChnZXQpID0+ICgpID0+IGdldC5jYWxsKGdhaW5Ob2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBzZXQuY2FsbChnYWluTm9kZSwgdmFsdWUpO1xuICAgICAgICAgICAgbmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2Fpbk5vZGUsICdtYXhDaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlLm1heENoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gQHRvZG8gVGhpcyBzaG91bGQgYmUgZGlzY29ubmVjdGVkIHdoZW4gdGhlIGNvbnRleHQgaXMgY2xvc2VkLlxuICAgICAgICBnYWluTm9kZS5jb25uZWN0KG5hdGl2ZUF1ZGlvRGVzdGluYXRpb25Ob2RlKTtcbiAgICAgICAgcmV0dXJuIGdhaW5Ob2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9ICh3aW5kb3cpID0+IHtcbiAgICBpZiAod2luZG93ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gd2luZG93Lmhhc093blByb3BlcnR5KCdBdWRpb1dvcmtsZXROb2RlJykgPyB3aW5kb3cuQXVkaW9Xb3JrbGV0Tm9kZSA6IG51bGw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdENsb25hYmlsaXR5T2ZBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEgfSA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDEucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICB9XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1jbG9uYWJpbGl0eS1vZi1hdWRpby13b3JrbGV0LW5vZGUtb3B0aW9ucy5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0Q2xvbmFiaWxpdHlPZkF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWNsb25hYmlsaXR5LW9mLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmFtZSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihuYXRpdmVDb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICAgICAgbGV0IG9ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHtcbiAgICAgICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgICAgICogQnVnICM2MTogT3ZlcndyaXRpbmcgdGhlIHByb3BlcnR5IGFjY2Vzc29ycyBmb3IgY2hhbm5lbENvdW50IGFuZCBjaGFubmVsQ291bnRNb2RlIGlzIG5lY2Vzc2FyeSBhcyBsb25nIGFzIHNvbWVcbiAgICAgICAgICAgICAgICAgICAgICogYnJvd3NlcnMgaGF2ZSBubyBuYXRpdmUgaW1wbGVtZW50YXRpb24gdG8gYWNoaWV2ZSBhIGNvbnNpc3RlbnQgYmVoYXZpb3IuXG4gICAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdldDogKCkgPT4gb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE1NjogQ2hyb21lIGFuZCBFZGdlIGRvIG5vdCB5ZXQgZmlyZSBhbiBFcnJvckV2ZW50LlxuICAgICAgICAgICAgICAgICAgICBvbnByb2Nlc3NvcmVycm9yOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IG9ucHJvY2Vzc29yZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ucHJvY2Vzc29yZXJyb3IgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbnByb2Nlc3NvcmVycm9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUuYWRkRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIgPSAoKGFkZEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc1swXSA9PT0gJ3Byb2Nlc3NvcmVycm9yJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSB0eXBlb2YgYXJnc1sxXSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiB0eXBlb2YgYXJnc1sxXSA9PT0gJ29iamVjdCcgJiYgYXJnc1sxXSAhPT0gbnVsbCAmJiB0eXBlb2YgYXJnc1sxXS5oYW5kbGVFdmVudCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBhcmdzWzFdLmhhbmRsZUV2ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IHBhdGNoZWRFdmVudExpc3RlbmVyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnc1sxXSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSAnZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKGV2ZW50LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiB7IHZhbHVlOiAncHJvY2Vzc29yZXJyb3InIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIoZXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lcihuZXcgRXJyb3JFdmVudChhcmdzWzBdLCB7IC4uLmV2ZW50IH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLnNldCh1bnBhdGNoZWRFdmVudExpc3RlbmVyLCBhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gZmlyZSBhbiBldmVudCBvZiB0eXBlIGVycm9yLlxuICAgICAgICAgICAgICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lci5jYWxsKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsICdlcnJvcicsIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFkZEV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KShuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmFkZEV2ZW50TGlzdGVuZXIpO1xuICAgICAgICAgICAgICAgIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lciA9ICgocmVtb3ZlRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAncHJvY2Vzc29yZXJyb3InKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXRjaGVkRXZlbnRMaXN0ZW5lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhdGNoZWRFdmVudExpc3RlbmVycy5kZWxldGUoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBCdWcgIzE3ODogQ2hyb21lIGFuZCBFZGdlIGRvIGZpcmUgYW4gZXZlbnQgb2YgdHlwZSBlcnJvci5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIuY2FsbChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCAnZXJyb3InLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZW1vdmVFdmVudExpc3RlbmVyLmNhbGwobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKTtcbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAqIEJ1ZyAjODY6IENocm9tZSBhbmQgRWRnZSBkbyBub3QgaW52b2tlIHRoZSBwcm9jZXNzKCkgZnVuY3Rpb24gaWYgdGhlIGNvcnJlc3BvbmRpbmcgQXVkaW9Xb3JrbGV0Tm9kZSBpcyB1bmNvbm5lY3RlZCBidXRcbiAgICAgICAgICAgICAgICAgKiBoYXMgYW4gb3V0cHV0LlxuICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLm51bWJlck9mT3V0cHV0cyAhPT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICBnYWluOiAwXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpLmNvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiBuYXRpdmVHYWluTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBuYXRpdmVHYWluTm9kZS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAvLyBAdG9kbyBEaXNjb25uZWN0IHRoZSBjb25uZWN0aW9uIHdoZW4gdGhlIHByb2Nlc3MoKSBmdW5jdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSByZXR1cm5zIGZhbHNlLlxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYwOiBDaHJvbWUgJiBFZGdlIHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIGluc3RlYWQgb2YgYSBOb3RTdXBwb3J0ZWRFcnJvci5cbiAgICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT09IDExKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzYxOiBPbmx5IENocm9tZSAmIEVkZ2UgaGF2ZSBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB5ZXQuXG4gICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHRlc3RDbG9uYWJpbGl0eU9mQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMob3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgYmFzZUxhdGVuY3ksIHByb2Nlc3NvckNvbnN0cnVjdG9yLCBvcHRpb25zKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY29tcHV0ZUJ1ZmZlclNpemUgPSAoYmFzZUxhdGVuY3ksIHNhbXBsZVJhdGUpID0+IHtcbiAgICBpZiAoYmFzZUxhdGVuY3kgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDUxMjtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGgubWF4KDUxMiwgTWF0aC5taW4oMTYzODQsIE1hdGgucG93KDIsIE1hdGgucm91bmQoTWF0aC5sb2cyKGJhc2VMYXRlbmN5ICogc2FtcGxlUmF0ZSkpKSkpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbXB1dGUtYnVmZmVyLXNpemUuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgICAgIHBvcnQxLm9ubWVzc2FnZSA9ICh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZXNvbHZlKGRhdGEpO1xuICAgICAgICB9O1xuICAgICAgICBwb3J0MS5vbm1lc3NhZ2VlcnJvciA9ICh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgICAgcG9ydDEuY2xvc2UoKTtcbiAgICAgICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgICAgICAgICByZWplY3QoZGF0YSk7XG4gICAgICAgIH07XG4gICAgICAgIC8vIFRoaXMgd2lsbCB0aHJvdyBhbiBlcnJvciBpZiB0aGUgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgYXJlIG5vdCBjbG9uYWJsZS5cbiAgICAgICAgcG9ydDIucG9zdE1lc3NhZ2UoYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpO1xuICAgIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zLmpzLm1hcCIsImltcG9ydCB7IGNsb25lQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgfSBmcm9tICcuL2Nsb25lLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlID0gYXN5bmMgKHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IGNsb25lZEF1ZGlvV29ya2xldE5vZGVPcHRpb25zID0gYXdhaXQgY2xvbmVBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyhhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgcmV0dXJuIG5ldyBwcm9jZXNzb3JDb25zdHJ1Y3RvcihjbG9uZWRBdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Y3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UuanMubWFwIiwiaW1wb3J0IHsgTk9ERV9UT19QUk9DRVNTT1JfTUFQUyB9IGZyb20gJy4uL2dsb2JhbHMnO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZSB9IGZyb20gJy4vY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLXByb21pc2UnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvciA9IChuYXRpdmVDb250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBwcm9jZXNzb3JDb25zdHJ1Y3RvciwgYXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMpID0+IHtcbiAgICBsZXQgbm9kZVRvUHJvY2Vzc29yTWFwID0gTk9ERV9UT19QUk9DRVNTT1JfTUFQUy5nZXQobmF0aXZlQ29udGV4dCk7XG4gICAgaWYgKG5vZGVUb1Byb2Nlc3Nvck1hcCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIG5vZGVUb1Byb2Nlc3Nvck1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIE5PREVfVE9fUFJPQ0VTU09SX01BUFMuc2V0KG5hdGl2ZUNvbnRleHQsIG5vZGVUb1Byb2Nlc3Nvck1hcCk7XG4gICAgfVxuICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlKHByb2Nlc3NvckNvbnN0cnVjdG9yLCBhdWRpb1dvcmtsZXROb2RlT3B0aW9ucyk7XG4gICAgbm9kZVRvUHJvY2Vzc29yTWFwLnNldChuYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBhdWRpb1dvcmtsZXRQcm9jZXNzb3JQcm9taXNlKTtcbiAgICByZXR1cm4gYXVkaW9Xb3JrbGV0UHJvY2Vzc29yUHJvbWlzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jcmVhdGUtYXVkaW8td29ya2xldC1wcm9jZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmltcG9ydCB7IGNvbXB1dGVCdWZmZXJTaXplIH0gZnJvbSAnLi4vaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplJztcbmltcG9ydCB7IGNvcHlGcm9tQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS1mcm9tLWNoYW5uZWwnO1xuaW1wb3J0IHsgY29weVRvQ2hhbm5lbCB9IGZyb20gJy4uL2hlbHBlcnMvY29weS10by1jaGFubmVsJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldFByb2Nlc3NvciB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yJztcbmltcG9ydCB7IGNyZWF0ZU5lc3RlZEFycmF5cyB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlLW5lc3RlZC1hcnJheXMnO1xuaW1wb3J0IHsgUmVhZE9ubHlNYXAgfSBmcm9tICcuLi9yZWFkLW9ubHktbWFwJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5ID0gKGNvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGNyZWF0ZUluZGV4U2l6ZUVycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBkaXNjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSwgZ2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cywgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgcHJvY2Vzc29yQ29uc3RydWN0b3IsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZJbnB1dHMgPT09IDAgJiYgb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbENvdW50ID0gQXJyYXkuaXNBcnJheShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudClcbiAgICAgICAgICAgID8gb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnRcbiAgICAgICAgICAgIDogQXJyYXkuZnJvbShvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgIC8vIEB0b2RvIENoZWNrIGlmIGFueSBvZiB0aGUgY2hhbm5lbENvdW50IHZhbHVlcyBpcyBncmVhdGVyIHRoYW4gdGhlIGltcGxlbWVudGF0aW9uJ3MgbWF4aW11bSBudW1iZXIgb2YgY2hhbm5lbHMuXG4gICAgICAgIGlmIChvdXRwdXRDaGFubmVsQ291bnQuc29tZSgoY2hhbm5lbENvdW50KSA9PiBjaGFubmVsQ291bnQgPCAxKSkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3V0cHV0Q2hhbm5lbENvdW50Lmxlbmd0aCAhPT0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBudW1iZXJPZklucHV0Q2hhbm5lbHMgPSBvcHRpb25zLmNoYW5uZWxDb3VudCAqIG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgIGNvbnN0IG51bWJlck9mT3V0cHV0Q2hhbm5lbHMgPSBvdXRwdXRDaGFubmVsQ291bnQucmVkdWNlKChzdW0sIHZhbHVlKSA9PiBzdW0gKyB2YWx1ZSwgMCk7XG4gICAgICAgIGNvbnN0IG51bWJlck9mUGFyYW1ldGVycyA9IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzID09PSB1bmRlZmluZWQgPyAwIDogcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICBpZiAobnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzID4gNiB8fCBudW1iZXJPZk91dHB1dENoYW5uZWxzID4gNikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtZXNzYWdlQ2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICAgICAgICBjb25zdCBnYWluTm9kZXMgPSBbXTtcbiAgICAgICAgY29uc3QgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2RlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZJbnB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgZ2Fpbk5vZGVzLnB1c2goY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogb3B0aW9ucy5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgZ2FpbjogMVxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlcy5wdXNoKGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbnN0YW50U291cmNlTm9kZXMgPSBbXTtcbiAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgeyBkZWZhdWx0VmFsdWUsIG1heFZhbHVlLCBtaW5WYWx1ZSwgbmFtZSB9IG9mIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy5wYXJhbWV0ZXJEYXRhW25hbWVdICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gb3B0aW9ucy5wYXJhbWV0ZXJEYXRhW25hbWVdXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGRlZmF1bHRWYWx1ZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBkZWZhdWx0VmFsdWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhjb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0LCB7XG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAoZGVmYXVsdFZhbHVlID09PSB1bmRlZmluZWQgPyAwIDogZGVmYXVsdFZhbHVlKVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBtYXhWYWx1ZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2V0OiAoKSA9PiAobWF4VmFsdWUgPT09IHVuZGVmaW5lZCA/IE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIDogbWF4VmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIG1pblZhbHVlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnZXQ6ICgpID0+IChtaW5WYWx1ZSA9PT0gdW5kZWZpbmVkID8gTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQgOiBtaW5WYWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZXMucHVzaChjb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGlucHV0Q2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IE1hdGgubWF4KDEsIG51bWJlck9mSW5wdXRDaGFubmVscyArIG51bWJlck9mUGFyYW1ldGVycylcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlclNpemUgPSBjb21wdXRlQnVmZmVyU2l6ZShiYXNlTGF0ZW5jeSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlQ29udGV4dCwgYnVmZmVyU2l6ZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgbnVtYmVyT2ZQYXJhbWV0ZXJzLCBcbiAgICAgICAgLy8gQnVnICM4NzogT25seSBGaXJlZm94IHdpbGwgZmlyZSBhbiBBdWRpb1Byb2Nlc3NpbmdFdmVudCBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgb3V0cHV0LlxuICAgICAgICBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKSk7XG4gICAgICAgIGNvbnN0IG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogTWF0aC5tYXgoMSwgbnVtYmVyT2ZPdXRwdXRDaGFubmVscyksXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiBNYXRoLm1heCgxLCBudW1iZXJPZk91dHB1dENoYW5uZWxzKVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzLnB1c2goY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgICAgICBudW1iZXJPZklucHV0czogb3V0cHV0Q2hhbm5lbENvdW50W2ldXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGdhaW5Ob2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbFNwbGl0dGVyTm9kZXNbaV0pO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLmNoYW5uZWxDb3VudDsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5jb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGosIGkgKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGopO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlck1hcCA9IG5ldyBSZWFkT25seU1hcChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLm1hcCgoeyBuYW1lIH0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY29uc3RhbnRTb3VyY2VOb2Rlc1tpbmRleF07XG4gICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmNvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgpO1xuICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdGFydCgwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gW25hbWUsIGNvbnN0YW50U291cmNlTm9kZS5vZmZzZXRdO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICBpbnB1dENoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgIGxldCBjaGFubmVsSW50ZXJwcmV0YXRpb24gPSBvcHRpb25zLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgbGV0IG9ucHJvY2Vzc29yZXJyb3IgPSBudWxsO1xuICAgICAgICAvLyBCdWcgIzg3OiBFeHBvc2UgYXQgbGVhc3Qgb25lIG91dHB1dCB0byBtYWtlIHRoaXMgbm9kZSBjb25uZWN0YWJsZS5cbiAgICAgICAgY29uc3Qgb3V0cHV0QXVkaW9Ob2RlcyA9IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAwID8gW3NjcmlwdFByb2Nlc3Nvck5vZGVdIDogb3V0cHV0Q2hhbm5lbE1lcmdlck5vZGVzO1xuICAgICAgICBjb25zdCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmZmVyU2l6ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmNoYW5uZWxDb3VudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50KF8pIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzYxOiBUaGlzIGlzIG5vdCBwYXJ0IG9mIHRoZSBzdGFuZGFyZCBidXQgcmVxdWlyZWQgZm9yIHRoZSBmYWtlciB0byB3b3JrLlxuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudE1vZGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZShfKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICM2MTogVGhpcyBpcyBub3QgcGFydCBvZiB0aGUgc3RhbmRhcmQgYnV0IHJlcXVpcmVkIGZvciB0aGUgZmFrZXIgdG8gd29yay5cbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBnYWluTm9kZSBvZiBnYWluTm9kZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgZ2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGVzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb25wcm9jZXNzb3JlcnJvcigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb25wcm9jZXNzb3JlcnJvcjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb25wcm9jZXNzb3JlcnJvcih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25wcm9jZXNzb3JlcnJvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigncHJvY2Vzc29yZXJyb3InLCBvbnByb2Nlc3NvcmVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgb25wcm9jZXNzb3JlcnJvciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHZhbHVlIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIG9ucHJvY2Vzc29yZXJyb3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2Nlc3NvcmVycm9yJywgb25wcm9jZXNzb3JlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwYXJhbWV0ZXJzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYXJhbWV0ZXJNYXA7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvcnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1lc3NhZ2VDaGFubmVsLnBvcnQyO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29ubmVjdDogY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dEF1ZGlvTm9kZXMpLFxuICAgICAgICAgICAgZGlzY29ubmVjdDogZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cy5iaW5kKG51bGwsIG91dHB1dEF1ZGlvTm9kZXMpLFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLmFkZEV2ZW50TGlzdGVuZXIgPSAoKGFkZEV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5wYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHR5cGVvZiBhcmdzWzFdID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV1cbiAgICAgICAgICAgICAgICAgICAgICAgIDogdHlwZW9mIGFyZ3NbMV0gPT09ICdvYmplY3QnICYmIGFyZ3NbMV0gIT09IG51bGwgJiYgdHlwZW9mIGFyZ3NbMV0uaGFuZGxlRXZlbnQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGFyZ3NbMV0uaGFuZGxlRXZlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIGlmICh1bnBhdGNoZWRFdmVudExpc3RlbmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXRjaGVkRXZlbnRMaXN0ZW5lciA9IHBhdGNoZWRFdmVudExpc3RlbmVycy5nZXQoYXJnc1sxXSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUobmF0aXZlQ29udGV4dC5jdXJyZW50VGltZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiB1bnBhdGNoZWRFdmVudExpc3RlbmVyKGV2ZW50KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuc2V0KHVucGF0Y2hlZEV2ZW50TGlzdGVuZXIsIGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBhZGRFdmVudExpc3RlbmVyLmNhbGwobWVzc2FnZUNoYW5uZWwucG9ydDEsIGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfSkobWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lcik7XG4gICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSAoKHJlbW92ZUV2ZW50TGlzdGVuZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcmdzWzBdID09PSAnbWVzc2FnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGF0Y2hlZEV2ZW50TGlzdGVuZXIgPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcnMuZ2V0KGFyZ3NbMV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGF0Y2hlZEV2ZW50TGlzdGVuZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2hlZEV2ZW50TGlzdGVuZXJzLmRlbGV0ZShhcmdzWzFdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3NbMV0gPSBwYXRjaGVkRXZlbnRMaXN0ZW5lcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVtb3ZlRXZlbnRMaXN0ZW5lci5jYWxsKG1lc3NhZ2VDaGFubmVsLnBvcnQxLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pKG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIpO1xuICAgICAgICBsZXQgb25tZXNzYWdlID0gbnVsbDtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1lc3NhZ2VDaGFubmVsLnBvcnQxLCAnb25tZXNzYWdlJywge1xuICAgICAgICAgICAgZ2V0OiAoKSA9PiBvbm1lc3NhZ2UsXG4gICAgICAgICAgICBzZXQ6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2Ygb25tZXNzYWdlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBvbm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvbm1lc3NhZ2UgPSB0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicgPyB2YWx1ZSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBvbm1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUNoYW5uZWwucG9ydDEuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9ubWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VDaGFubmVsLnBvcnQxLnN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcHJvY2Vzc29yQ29uc3RydWN0b3IucHJvdG90eXBlLnBvcnQgPSBtZXNzYWdlQ2hhbm5lbC5wb3J0MTtcbiAgICAgICAgbGV0IGF1ZGlvV29ya2xldFByb2Nlc3NvciA9IG51bGw7XG4gICAgICAgIGNvbnN0IGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UgPSBjcmVhdGVBdWRpb1dvcmtsZXRQcm9jZXNzb3IobmF0aXZlQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyLCBwcm9jZXNzb3JDb25zdHJ1Y3Rvciwgb3B0aW9ucyk7XG4gICAgICAgIGF1ZGlvV29ya2xldFByb2Nlc3NvclByb21pc2UudGhlbigoZFdya2x0UHJjc3NyKSA9PiAoYXVkaW9Xb3JrbGV0UHJvY2Vzc29yID0gZFdya2x0UHJjc3NyKSk7XG4gICAgICAgIGNvbnN0IGlucHV0cyA9IGNyZWF0ZU5lc3RlZEFycmF5cyhvcHRpb25zLm51bWJlck9mSW5wdXRzLCBvcHRpb25zLmNoYW5uZWxDb3VudCk7XG4gICAgICAgIGNvbnN0IG91dHB1dHMgPSBjcmVhdGVOZXN0ZWRBcnJheXMob3B0aW9ucy5udW1iZXJPZk91dHB1dHMsIG91dHB1dENoYW5uZWxDb3VudCk7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IFtdXG4gICAgICAgICAgICA6IHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLnJlZHVjZSgocHJtdHJzLCB7IG5hbWUgfSkgPT4gKHsgLi4ucHJtdHJzLCBbbmFtZV06IG5ldyBGbG9hdDMyQXJyYXkoMTI4KSB9KSwge30pO1xuICAgICAgICBsZXQgaXNBY3RpdmUgPSB0cnVlO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0T3V0cHV0c0dyYXBoID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID4gMCkge1xuICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ID0gMDsgaSA8IG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG91dHB1dENoYW5uZWxDb3VudFtpXTsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGosIGopO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgYWN0aXZlSW5wdXRJbmRleGVzID0gbmV3IE1hcCgpO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyLCBvdXRwdXRCdWZmZXIgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKGF1ZGlvV29ya2xldFByb2Nlc3NvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUlucHV0cyA9IGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1ZmZlclNpemU7IGkgKz0gMTI4KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3B0aW9ucy5udW1iZXJPZklucHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5RnJvbUNoYW5uZWwoaW5wdXRCdWZmZXIsIGlucHV0c1tqXSwgaywgaywgaSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NvckNvbnN0cnVjdG9yLnBhcmFtZXRlckRlc2NyaXB0b3JzLmZvckVhY2goKHsgbmFtZSB9LCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcHlGcm9tQ2hhbm5lbChpbnB1dEJ1ZmZlciwgcGFyYW1ldGVycywgbmFtZSwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaW5kZXgsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgb3V0cHV0Q2hhbm5lbENvdW50W2pdOyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgYnl0ZUxlbmd0aCB3aWxsIGJlIDAgd2hlbiB0aGUgQXJyYXlCdWZmZXIgd2FzIHRyYW5zZmVycmVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRwdXRzW2pdW2tdLmJ5dGVMZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0c1tqXVtrXSA9IG5ldyBGbG9hdDMyQXJyYXkoMTI4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvdGVudGlhbGx5RW1wdHlJbnB1dHMgPSBpbnB1dHMubWFwKChpbnB1dCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbnB1dCA9IGFjdGl2ZUlucHV0c1tpbmRleF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUlucHV0LnNpemUgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5zZXQoaW5kZXgsIGJ1ZmZlclNpemUgLyAxMjgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gYWN0aXZlSW5wdXRJbmRleGVzLmdldChpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuZXZlcnkoKGNoYW5uZWxEYXRhKSA9PiBjaGFubmVsRGF0YS5ldmVyeSgoc2FtcGxlKSA9PiBzYW1wbGUgPT09IDApKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUlucHV0SW5kZXhlcy5kZWxldGUoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlSW5wdXRJbmRleGVzLnNldChpbmRleCwgY291bnQgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZVNvdXJjZUZsYWcgPSBleHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZShuYXRpdmVDb250ZXh0LmN1cnJlbnRUaW1lICsgaSAvIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSwgbmF0aXZlQ29udGV4dC5zYW1wbGVSYXRlLCAoKSA9PiBhdWRpb1dvcmtsZXRQcm9jZXNzb3IucHJvY2Vzcyhwb3RlbnRpYWxseUVtcHR5SW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IGFjdGl2ZVNvdXJjZUZsYWc7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMCwgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mT3V0cHV0czsgaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBvdXRwdXRDaGFubmVsQ291bnRbal07IGsgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3B5VG9DaGFubmVsKG91dHB1dEJ1ZmZlciwgb3V0cHV0c1tqXSwgaywgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArIGssIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICs9IG91dHB1dENoYW5uZWxDb3VudFtqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIuZGlzcGF0Y2hFdmVudChuZXcgRXJyb3JFdmVudCgncHJvY2Vzc29yZXJyb3InLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbm86IGVycm9yLmNvbG5vLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBlcnJvci5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lbm86IGVycm9yLmxpbmVubyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnJvci5tZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvcHRpb25zLm51bWJlck9mSW5wdXRzOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnYWluTm9kZXNbal0uZGlzY29ubmVjdChpbnB1dENoYW5uZWxTcGxpdHRlck5vZGVzW2pdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IG9wdGlvbnMuY2hhbm5lbENvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsU3BsaXR0ZXJOb2Rlc1tpXS5kaXNjb25uZWN0KGlucHV0Q2hhbm5lbE1lcmdlck5vZGUsIGssIGogKiBvcHRpb25zLmNoYW5uZWxDb3VudCArIGspO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcm9jZXNzb3JDb25zdHJ1Y3Rvci5wYXJhbWV0ZXJEZXNjcmlwdG9ycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gcHJvY2Vzc29yQ29uc3RydWN0b3IucGFyYW1ldGVyRGVzY3JpcHRvcnMubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbGVuZ3RoOyBqICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uc3RhbnRTb3VyY2VOb2RlID0gY29uc3RhbnRTb3VyY2VOb2Rlc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoaW5wdXRDaGFubmVsTWVyZ2VyTm9kZSwgMCwgbnVtYmVyT2ZJbnB1dENoYW5uZWxzICsgaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50U291cmNlTm9kZS5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRDaGFubmVsTWVyZ2VyTm9kZS5kaXNjb25uZWN0KHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0Nvbm5lY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgLy8gQnVnICM4NzogT25seSBGaXJlZm94IHdpbGwgZmlyZSBhbiBBdWRpb1Byb2Nlc3NpbmdFdmVudCBpZiB0aGVyZSBpcyBubyBjb25uZWN0ZWQgb3V0cHV0LlxuICAgICAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBjb25uZWN0RmFrZUdyYXBoID0gKCkgPT4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICBjb25zdCBkaXNjb25uZWN0RmFrZUdyYXBoID0gKCkgPT4ge1xuICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNjb25uZWN0KG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0FjdGl2ZSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5udW1iZXJPZk91dHB1dHMgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY29ubmVjdChvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIG91dHB1dENoYW5uZWxTcGxpdHRlck5vZGVPdXRwdXQgPSAwOyBpIDwgb3B0aW9ucy5udW1iZXJPZk91dHB1dHM7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvdXRwdXRDaGFubmVsTWVyZ2VyTm9kZSA9IG91dHB1dENoYW5uZWxNZXJnZXJOb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdXRwdXRDaGFubmVsQ291bnRbaV07IGogKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KG91dHB1dENoYW5uZWxNZXJnZXJOb2RlLCBvdXRwdXRDaGFubmVsU3BsaXR0ZXJOb2RlT3V0cHV0ICsgaiwgaik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0Q2hhbm5lbFNwbGl0dGVyTm9kZU91dHB1dCArPSBvdXRwdXRDaGFubmVsQ291bnRbaV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdEZha2VHcmFwaCgpO1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3RPdXRwdXRzR3JhcGgoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIGNvbm5lY3RGYWtlR3JhcGgoKTtcbiAgICAgICAgcmV0dXJuIG1vbml0b3JDb25uZWN0aW9ucyhuYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXIsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQmlxdWFkRmlsdGVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ1EnKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgb3B0aW9ucywgJ2RldHVuZScpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVCaXF1YWRGaWx0ZXJOb2RlLCBvcHRpb25zLCAnZnJlcXVlbmN5Jyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICdnYWluJyk7XG4gICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZUJpcXVhZEZpbHRlck5vZGUsIG9wdGlvbnMsICd0eXBlJyk7XG4gICAgcmV0dXJuIG5hdGl2ZUJpcXVhZEZpbHRlck5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWJpcXVhZC1maWx0ZXItbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGVGYWN0b3J5ID0gKG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIob3B0aW9ucy5udW1iZXJPZklucHV0cyk7XG4gICAgICAgIC8qXG4gICAgICAgICAqIEJ1ZyAjMjA6IFNhZmFyaSByZXF1aXJlcyBhIGNvbm5lY3Rpb24gb2YgYW55IGtpbmQgdG8gdHJlYXQgdGhlIGlucHV0IHNpZ25hbCBjb3JyZWN0bHkuXG4gICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGUgZXhpc3RlbmNlIG9mXG4gICAgICAgICAqIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJiBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvci5uYW1lID09PSAnd2Via2l0QXVkaW9Db250ZXh0Jykge1xuICAgICAgICAgICAgd3JhcENoYW5uZWxNZXJnZXJOb2RlKG5hdGl2ZUNvbnRleHQsIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWNoYW5uZWwtbWVyZ2VyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4uL2ZhY3Rvcmllcy9pbnZhbGlkLXN0YXRlLWVycm9yJztcbmV4cG9ydCBjb25zdCB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZSA9IChjaGFubmVsU3BsaXR0ZXJOb2RlKSA9PiB7XG4gICAgY29uc3QgY2hhbm5lbENvdW50ID0gY2hhbm5lbFNwbGl0dGVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgLy8gQnVnICM5NzogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHdoZW4gYXR0ZW1wdGluZyB0byBjaGFuZ2UgdGhlIGNoYW5uZWxDb3VudCB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBpdHMgaW5pdGlhbCB2YWx1ZS5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxDb3VudCcsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiBjaGFubmVsQ291bnQsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBCdWcgIzMwOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbENvdW50TW9kZSB0byBzb21ldGhpbmcgb3RoZXIgdGhhbiBleHBsaWNpdC5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbFNwbGl0dGVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCB7XG4gICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgc2V0OiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gJ2V4cGxpY2l0Jykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICAvLyBCdWcgIzMyOiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBhdHRlbXB0aW5nIHRvIGNoYW5nZSB0aGUgY2hhbm5lbEludGVycHJldGF0aW9uIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGRpc2NyZXRlLlxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjaGFubmVsU3BsaXR0ZXJOb2RlLCAnY2hhbm5lbEludGVycHJldGF0aW9uJywge1xuICAgICAgICBnZXQ6ICgpID0+ICdkaXNjcmV0ZScsXG4gICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09ICdkaXNjcmV0ZScpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1jaGFubmVsLXNwbGl0dGVyLW5vZGUuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuaW1wb3J0IHsgd3JhcENoYW5uZWxTcGxpdHRlck5vZGUgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtY2hhbm5lbC1zcGxpdHRlci1ub2RlJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIob3B0aW9ucy5udW1iZXJPZk91dHB1dHMpO1xuICAgIC8vIEJ1ZyAjOTY6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxDb3VudC5cbiAgICAvLyBCdWcgIzI5OiBTYWZhcmkgZG9lcyBub3QgaGF2ZSB0aGUgY29ycmVjdCBjaGFubmVsQ291bnRNb2RlLlxuICAgIC8vIEJ1ZyAjMzE6IFNhZmFyaSBkb2VzIG5vdCBoYXZlIHRoZSBjb3JyZWN0IGNoYW5uZWxJbnRlcnByZXRhdGlvbi5cbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIG9wdGlvbnMpO1xuICAgIC8vIEJ1ZyAjMjksICMzMCwgIzMxLCAjMzIsICM5NiAmICM5NzogT25seSBDaHJvbWUsIEVkZ2UgJiBGaXJlZm94IHBhcnRpYWxseSBzdXBwb3J0IHRoZSBzcGVjIHlldC5cbiAgICB3cmFwQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICByZXR1cm4gbmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY2hhbm5lbC1zcGxpdHRlci1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyB9IGZyb20gJy4uL2hlbHBlcnMvd3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNjI6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IENvbnN0YW50U291cmNlTm9kZXMuXG4gICAgICAgIGlmIChuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgb3B0aW9ucywgJ29mZnNldCcpO1xuICAgICAgICAvLyBCdWcgIzQ0OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjNDQ6IE9ubHkgRmlyZWZveCBkb2VzIG5vdCB0aHJvdyBhIFJhbmdlRXJyb3IgeWV0LlxuICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsICgpID0+IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzKG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxNzU6IFNhZmFyaSB3aWxsIG5vdCBmaXJlIGFuIGVuZGVkIGV2ZW50IGlmIHRoZSBDb25zdGFudFNvdXJjZU5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBpbnRlcmNlcHRDb25uZWN0aW9ucyA9IChvcmlnaW5hbCwgaW50ZXJjZXB0b3IpID0+IHtcbiAgICBvcmlnaW5hbC5jb25uZWN0ID0gaW50ZXJjZXB0b3IuY29ubmVjdC5iaW5kKGludGVyY2VwdG9yKTtcbiAgICBvcmlnaW5hbC5kaXNjb25uZWN0ID0gaW50ZXJjZXB0b3IuZGlzY29ubmVjdC5iaW5kKGludGVyY2VwdG9yKTtcbiAgICByZXR1cm4gb3JpZ2luYWw7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW50ZXJjZXB0LWNvbm5lY3Rpb25zLmpzLm1hcCIsImltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeSA9IChhZGRTaWxlbnRDb25uZWN0aW9uLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgb2Zmc2V0LCAuLi5hdWRpb05vZGVPcHRpb25zIH0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAyLCA0NDEwMCk7XG4gICAgICAgIGNvbnN0IGF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBidWZmZXI6IG51bGwsXG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgZ2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IG9mZnNldCB9KTtcbiAgICAgICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKDApO1xuICAgICAgICAvLyBCdWcgIzk1OiBTYWZhcmkgZG9lcyBub3QgcGxheSBvciBsb29wIG9uZSBzYW1wbGUgYnVmZmVycy5cbiAgICAgICAgY2hhbm5lbERhdGFbMF0gPSAxO1xuICAgICAgICBjaGFubmVsRGF0YVsxXSA9IDE7XG4gICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBhdWRpb0J1ZmZlcjtcbiAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmxvb3AgPSB0cnVlO1xuICAgICAgICBjb25zdCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBnYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZ2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbENvdW50TW9kZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb247XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLm51bWJlck9mSW5wdXRzO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZk91dHB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb2Zmc2V0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBnYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUub25lbmRlZDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb25lbmRlZCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5vbmVuZGVkID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF1ZGlvQnVmZmVyU291cmNlTm9kZS5hZGRFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc3BhdGNoRXZlbnQoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3RhcnQod2hlbiA9IDApIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQuY2FsbChhdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0b3Aod2hlbiA9IDApIHtcbiAgICAgICAgICAgICAgICBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcC5jYWxsKGF1ZGlvQnVmZmVyU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5Db25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiBhdWRpb0J1ZmZlclNvdXJjZU5vZGUuZGlzY29ubmVjdChnYWluTm9kZSk7XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIGlzIHVuY29ubmVjdGVkLlxuICAgICAgICBhZGRTaWxlbnRDb25uZWN0aW9uKG5hdGl2ZUNvbnRleHQsIGF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIGdhaW5Ob2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtY29uc3RhbnQtc291cmNlLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24gfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb24nO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5ID0gKGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlQ29udm9sdmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlQ29udm9sdmVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIFRoZSBub3JtYWxpemUgcHJvcGVydHkgbmVlZHMgdG8gYmUgc2V0IGJlZm9yZSBzZXR0aW5nIHRoZSBidWZmZXIuXG4gICAgICAgIGlmIChvcHRpb25zLmRpc2FibGVOb3JtYWxpemF0aW9uID09PSBuYXRpdmVDb252b2x2ZXJOb2RlLm5vcm1hbGl6ZSkge1xuICAgICAgICAgICAgbmF0aXZlQ29udm9sdmVyTm9kZS5ub3JtYWxpemUgPSAhb3B0aW9ucy5kaXNhYmxlTm9ybWFsaXphdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlQ29udm9sdmVyTm9kZSwgb3B0aW9ucywgJ2J1ZmZlcicpO1xuICAgICAgICAvLyBCdWcgIzExMzogU2FmYXJpIGRvZXMgYWxsb3cgdG8gc2V0IHRoZSBjaGFubmVsQ291bnQgdG8gYSB2YWx1ZSBsYXJnZXIgdGhhbiAyLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnQgPiAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVDb252b2x2ZXJOb2RlLCAnY2hhbm5lbENvdW50JywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSksIChzZXQpID0+ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHZhbHVlID4gMikge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc2V0LmNhbGwobmF0aXZlQ29udm9sdmVyTm9kZSwgdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxMTQ6IFNhZmFyaSBhbGxvd3MgdG8gc2V0IHRoZSBjaGFubmVsQ291bnRNb2RlIHRvICdtYXgnLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBvdmVyd3JpdGVBY2Nlc3NvcnMobmF0aXZlQ29udm9sdmVyTm9kZSwgJ2NoYW5uZWxDb3VudE1vZGUnLCAoZ2V0KSA9PiAoKSA9PiBnZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlKSwgKHNldCkgPT4gKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVDb252b2x2ZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbmF0aXZlQ29udm9sdmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1jb252b2x2ZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVEZWxheU5vZGUgPSAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZURlbGF5Tm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlRGVsYXkob3B0aW9ucy5tYXhEZWxheVRpbWUpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlRGVsYXlOb2RlLCBvcHRpb25zKTtcbiAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRGVsYXlOb2RlLCBvcHRpb25zLCAnZGVsYXlUaW1lJyk7XG4gICAgcmV0dXJuIG5hdGl2ZURlbGF5Tm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZGVsYXktbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkgPSAoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIC8vIEJ1ZyAjMTA4OiBTYWZhcmkgYWxsb3dzIGEgY2hhbm5lbENvdW50IG9mIHRocmVlIGFuZCBhYm92ZS5cbiAgICAgICAgaWYgKG9wdGlvbnMuY2hhbm5lbENvdW50ID4gMikge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzEwOTogT25seSBDaHJvbWUgYW5kIEZpcmVmb3ggZGlzYWxsb3cgYSBjaGFubmVsQ291bnRNb2RlIG9mICdtYXgnLlxuICAgICAgICBpZiAob3B0aW9ucy5jaGFubmVsQ291bnRNb2RlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ2F0dGFjaycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ2tuZWUnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICdyYXRpbycpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUobmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgb3B0aW9ucywgJ3JlbGVhc2UnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGUsIG9wdGlvbnMsICd0aHJlc2hvbGQnKTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlID0gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBuYXRpdmVHYWluTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlR2Fpbk5vZGUsIG9wdGlvbnMpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVHYWluTm9kZSwgb3B0aW9ucywgJ2dhaW4nKTtcbiAgICByZXR1cm4gbmF0aXZlR2Fpbk5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWdhaW4tbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZUZha2VyKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgb3B0aW9ucykgPT4ge1xuICAgICAgICAvLyBCdWcgIzk6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IElJUkZpbHRlck5vZGVzLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBiYXNlTGF0ZW5jeSwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBkZWZpbmVzIHRoZSBwYXJhbWV0ZXJzIG9mIGNyZWF0ZUlJUkZpbHRlcigpIGFzIGFycmF5cyBvZiBudW1iZXJzLlxuICAgICAgICBjb25zdCBuYXRpdmVJSVJGaWx0ZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVJSVJGaWx0ZXIob3B0aW9ucy5mZWVkZm9yd2FyZCwgb3B0aW9ucy5mZWVkYmFjayk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlSUlSRmlsdGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIHJldHVybiBuYXRpdmVJSVJGaWx0ZXJOb2RlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGNvbXB1dGVCdWZmZXJTaXplIH0gZnJvbSAnLi4vaGVscGVycy9jb21wdXRlLWJ1ZmZlci1zaXplJztcbmltcG9ydCB7IGZpbHRlckJ1ZmZlciB9IGZyb20gJy4uL2hlbHBlcnMvZmlsdGVyLWJ1ZmZlcic7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmZ1bmN0aW9uIGRpdmlkZShhLCBiKSB7XG4gICAgY29uc3QgZGVub21pbmF0b3IgPSBiWzBdICogYlswXSArIGJbMV0gKiBiWzFdO1xuICAgIHJldHVybiBbKGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0pIC8gZGVub21pbmF0b3IsIChhWzFdICogYlswXSAtIGFbMF0gKiBiWzFdKSAvIGRlbm9taW5hdG9yXTtcbn1cbmZ1bmN0aW9uIG11bHRpcGx5KGEsIGIpIHtcbiAgICByZXR1cm4gW2FbMF0gKiBiWzBdIC0gYVsxXSAqIGJbMV0sIGFbMF0gKiBiWzFdICsgYVsxXSAqIGJbMF1dO1xufVxuZnVuY3Rpb24gZXZhbHVhdGVQb2x5bm9taWFsKGNvZWZmaWNpZW50LCB6KSB7XG4gICAgbGV0IHJlc3VsdCA9IFswLCAwXTtcbiAgICBmb3IgKGxldCBpID0gY29lZmZpY2llbnQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcbiAgICAgICAgcmVzdWx0ID0gbXVsdGlwbHkocmVzdWx0LCB6KTtcbiAgICAgICAgcmVzdWx0WzBdICs9IGNvZWZmaWNpZW50W2ldO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkgPSAoY3JlYXRlSW52YWxpZEFjY2Vzc0Vycm9yLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIGJhc2VMYXRlbmN5LCB7IGNoYW5uZWxDb3VudCwgY2hhbm5lbENvdW50TW9kZSwgY2hhbm5lbEludGVycHJldGF0aW9uLCBmZWVkYmFjaywgZmVlZGZvcndhcmQgfSkgPT4ge1xuICAgICAgICBjb25zdCBidWZmZXJTaXplID0gY29tcHV0ZUJ1ZmZlclNpemUoYmFzZUxhdGVuY3ksIG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IGNvbnZlcnRlZEZlZWRiYWNrID0gZmVlZGJhY2sgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgPyBmZWVkYmFjayA6IG5ldyBGbG9hdDY0QXJyYXkoZmVlZGJhY2spO1xuICAgICAgICBjb25zdCBjb252ZXJ0ZWRGZWVkZm9yd2FyZCA9IGZlZWRmb3J3YXJkIGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5ID8gZmVlZGZvcndhcmQgOiBuZXcgRmxvYXQ2NEFycmF5KGZlZWRmb3J3YXJkKTtcbiAgICAgICAgY29uc3QgZmVlZGJhY2tMZW5ndGggPSBjb252ZXJ0ZWRGZWVkYmFjay5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGZlZWRmb3J3YXJkTGVuZ3RoID0gY29udmVydGVkRmVlZGZvcndhcmQubGVuZ3RoO1xuICAgICAgICBjb25zdCBtaW5MZW5ndGggPSBNYXRoLm1pbihmZWVkYmFja0xlbmd0aCwgZmVlZGZvcndhcmRMZW5ndGgpO1xuICAgICAgICBpZiAoZmVlZGJhY2tMZW5ndGggPT09IDAgfHwgZmVlZGJhY2tMZW5ndGggPiAyMCkge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udmVydGVkRmVlZGJhY2tbMF0gPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZlZWRmb3J3YXJkTGVuZ3RoID09PSAwIHx8IGZlZWRmb3J3YXJkTGVuZ3RoID4gMjApIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbnZlcnRlZEZlZWRmb3J3YXJkWzBdID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb252ZXJ0ZWRGZWVkYmFja1swXSAhPT0gMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmZWVkZm9yd2FyZExlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgY29udmVydGVkRmVlZGZvcndhcmRbaV0gLz0gY29udmVydGVkRmVlZGJhY2tbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZlZWRiYWNrTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb252ZXJ0ZWRGZWVkYmFja1tpXSAvPSBjb252ZXJ0ZWRGZWVkYmFja1swXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCBidWZmZXJTaXplLCBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudCk7XG4gICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50ID0gY2hhbm5lbENvdW50O1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSBjaGFubmVsQ291bnRNb2RlO1xuICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IGNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgY29uc3QgYnVmZmVyTGVuZ3RoID0gMzI7XG4gICAgICAgIGNvbnN0IGJ1ZmZlckluZGV4ZXMgPSBbXTtcbiAgICAgICAgY29uc3QgeEJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgY29uc3QgeUJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsQ291bnQ7IGkgKz0gMSkge1xuICAgICAgICAgICAgYnVmZmVySW5kZXhlcy5wdXNoKDApO1xuICAgICAgICAgICAgY29uc3QgeEJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyTGVuZ3RoKTtcbiAgICAgICAgICAgIGNvbnN0IHlCdWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1ZmZlckxlbmd0aCk7XG4gICAgICAgICAgICB4QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgICAgICB5QnVmZmVyLmZpbGwoMCk7XG4gICAgICAgICAgICB4QnVmZmVycy5wdXNoKHhCdWZmZXIpO1xuICAgICAgICAgICAgeUJ1ZmZlcnMucHVzaCh5QnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRCdWZmZXIgPSBldmVudC5pbnB1dEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IG91dHB1dEJ1ZmZlciA9IGV2ZW50Lm91dHB1dEJ1ZmZlcjtcbiAgICAgICAgICAgIGNvbnN0IG51bWJlck9mQ2hhbm5lbHMgPSBpbnB1dEJ1ZmZlci5udW1iZXJPZkNoYW5uZWxzO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNoYW5uZWxzOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnB1dCA9IGlucHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dEJ1ZmZlci5nZXRDaGFubmVsRGF0YShpKTtcbiAgICAgICAgICAgICAgICBidWZmZXJJbmRleGVzW2ldID0gZmlsdGVyQnVmZmVyKGNvbnZlcnRlZEZlZWRiYWNrLCBmZWVkYmFja0xlbmd0aCwgY29udmVydGVkRmVlZGZvcndhcmQsIGZlZWRmb3J3YXJkTGVuZ3RoLCBtaW5MZW5ndGgsIHhCdWZmZXJzW2ldLCB5QnVmZmVyc1tpXSwgYnVmZmVySW5kZXhlc1tpXSwgYnVmZmVyTGVuZ3RoLCBpbnB1dCwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgbnlxdWlzdCA9IG5hdGl2ZUNvbnRleHQuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICAgIGNvbnN0IG5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBidWZmZXJTaXplO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29udGV4dCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5jb250ZXh0O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtzY3JpcHRQcm9jZXNzb3JOb2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkRXZlbnRMaXN0ZW5lciguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgLy8gQHRvZG8gRGlzc2FsbG93IGFkZGluZyBhbiBhdWRpb3Byb2Nlc3MgbGlzdGVuZXIuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNjcmlwdFByb2Nlc3Nvck5vZGUuYWRkRXZlbnRMaXN0ZW5lcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNwYXRjaEV2ZW50KC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2NyaXB0UHJvY2Vzc29yTm9kZS5kaXNwYXRjaEV2ZW50KGFyZ3NbMF0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldEZyZXF1ZW5jeVJlc3BvbnNlKGZyZXF1ZW5jeUh6LCBtYWdSZXNwb25zZSwgcGhhc2VSZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmIChmcmVxdWVuY3lIei5sZW5ndGggIT09IG1hZ1Jlc3BvbnNlLmxlbmd0aCB8fCBtYWdSZXNwb25zZS5sZW5ndGggIT09IHBoYXNlUmVzcG9uc2UubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBsZW5ndGggPSBmcmVxdWVuY3lIei5sZW5ndGg7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbWVnYSA9IC1NYXRoLlBJICogKGZyZXF1ZW5jeUh6W2ldIC8gbnlxdWlzdCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHogPSBbTWF0aC5jb3Mob21lZ2EpLCBNYXRoLnNpbihvbWVnYSldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmF0b3IgPSBldmFsdWF0ZVBvbHlub21pYWwoY29udmVydGVkRmVlZGZvcndhcmQsIHopO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZW5vbWluYXRvciA9IGV2YWx1YXRlUG9seW5vbWlhbChjb252ZXJ0ZWRGZWVkYmFjaywgeik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZGl2aWRlKG51bWVyYXRvciwgZGVub21pbmF0b3IpO1xuICAgICAgICAgICAgICAgICAgICBtYWdSZXNwb25zZVtpXSA9IE1hdGguc3FydChyZXNwb25zZVswXSAqIHJlc3BvbnNlWzBdICsgcmVzcG9uc2VbMV0gKiByZXNwb25zZVsxXSk7XG4gICAgICAgICAgICAgICAgICAgIHBoYXNlUmVzcG9uc2VbaV0gPSBNYXRoLmF0YW4yKHJlc3BvbnNlWzFdLCByZXNwb25zZVswXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZUV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzY3JpcHRQcm9jZXNzb3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBpbnRlcmNlcHRDb25uZWN0aW9ucyhuYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIsIHNjcmlwdFByb2Nlc3Nvck5vZGUpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWtlci1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgPSAobmF0aXZlQXVkaW9Db250ZXh0LCBvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2Uob3B0aW9ucy5tZWRpYUVsZW1lbnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1lbGVtZW50LWF1ZGlvLXNvdXJjZS1ub2RlLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlID0gKG5hdGl2ZUF1ZGlvQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUgPSBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpO1xuICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSwgb3B0aW9ucyk7XG4gICAgLy8gQnVnICMxNzQ6IFNhZmFyaSBkb2VzIGV4cG9zZSBhIHdyb25nIG51bWJlck9mT3V0cHV0cy5cbiAgICBpZiAobmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZS5udW1iZXJPZk91dHB1dHMgPT09IDEpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsICdudW1iZXJPZk91dHB1dHMnLCB7IGdldDogKCkgPT4gMCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLW1lZGlhLXN0cmVhbS1hdWRpby1kZXN0aW5hdGlvbi1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IChuYXRpdmVBdWRpb0NvbnRleHQsIHsgbWVkaWFTdHJlYW0gfSkgPT4ge1xuICAgIGNvbnN0IGF1ZGlvU3RyZWFtVHJhY2tzID0gbWVkaWFTdHJlYW0uZ2V0QXVkaW9UcmFja3MoKTtcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTUxOiBTYWZhcmkgZG9lcyBub3QgdXNlIHRoZSBhdWRpbyB0cmFjayBhcyBpbnB1dCBhbnltb3JlIGlmIGl0IGdldHMgcmVtb3ZlZCBmcm9tIHRoZSBtZWRpYVN0cmVhbSBhZnRlciBjb25zdHJ1Y3Rpb24uXG4gICAgICogQnVnICMxNTk6IFNhZmFyaSBwaWNrcyB0aGUgZmlyc3QgYXVkaW8gdHJhY2sgaWYgdGhlIE1lZGlhU3RyZWFtIGhhcyBtb3JlIHRoYW4gb25lIGF1ZGlvIHRyYWNrLlxuICAgICAqL1xuICAgIGF1ZGlvU3RyZWFtVHJhY2tzLnNvcnQoKGEsIGIpID0+IChhLmlkIDwgYi5pZCA/IC0xIDogYS5pZCA+IGIuaWQgPyAxIDogMCkpO1xuICAgIGNvbnN0IGZpbHRlcmVkQXVkaW9TdHJlYW1UcmFja3MgPSBhdWRpb1N0cmVhbVRyYWNrcy5zbGljZSgwLCAxKTtcbiAgICBjb25zdCBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSA9IG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVNvdXJjZShuZXcgTWVkaWFTdHJlYW0oZmlsdGVyZWRBdWRpb1N0cmVhbVRyYWNrcykpO1xuICAgIC8qXG4gICAgICogQnVnICMxNTEgJiAjMTU5OiBUaGUgZ2l2ZW4gbWVkaWFTdHJlYW0gZ2V0cyByZWNvbnN0cnVjdGVkIGJlZm9yZSBpdCBnZXRzIHBhc3NlZCB0byB0aGUgbmF0aXZlIG5vZGUgd2hpY2ggaXMgd2h5IHRoZSBhY2Nlc3NvciBuZWVkc1xuICAgICAqIHRvIGJlIG92ZXJ3cml0dGVuIGFzIGl0IHdvdWxkIG90aGVyd2lzZSBleHBvc2UgdGhlIHJlY29uc3RydWN0ZWQgdmVyc2lvbi5cbiAgICAgKi9cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsICdtZWRpYVN0cmVhbScsIHsgdmFsdWU6IG1lZGlhU3RyZWFtIH0pO1xuICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtbWVkaWEtc3RyZWFtLWF1ZGlvLXNvdXJjZS1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlRmFjdG9yeSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVBdWRpb0NvbnRleHQsIHsgbWVkaWFTdHJlYW1UcmFjayB9KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTIxOiBPbmx5IEZpcmVmb3ggZG9lcyB5ZXQgc3VwcG9ydCB0aGUgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZS5cbiAgICAgICAgaWYgKHR5cGVvZiBuYXRpdmVBdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1UcmFja1NvdXJjZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUF1ZGlvQ29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbVRyYWNrU291cmNlKG1lZGlhU3RyZWFtVHJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1lZGlhU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFttZWRpYVN0cmVhbVRyYWNrXSk7XG4gICAgICAgIGNvbnN0IG5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlID0gbmF0aXZlQXVkaW9Db250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKG1lZGlhU3RyZWFtKTtcbiAgICAgICAgLy8gQnVnICMxMjA6IEZpcmVmb3ggZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG1lZGlhU3RyZWFtIGhhcyBubyBhdWRpbyB0cmFjay5cbiAgICAgICAgaWYgKG1lZGlhU3RyZWFtVHJhY2sua2luZCAhPT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzE3MjogU2FmYXJpIGFsbG93cyB0byBjcmVhdGUgYSBNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB3aXRoIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gICAgICAgIGlmIChpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQXVkaW9Db250ZXh0KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKHdpbmRvdykgPT4ge1xuICAgIGlmICh3aW5kb3cgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmICh3aW5kb3cuaGFzT3duUHJvcGVydHkoJ09mZmxpbmVBdWRpb0NvbnRleHQnKSkge1xuICAgICAgICByZXR1cm4gd2luZG93Lk9mZmxpbmVBdWRpb0NvbnRleHQ7XG4gICAgfVxuICAgIHJldHVybiB3aW5kb3cuaGFzT3duUHJvcGVydHkoJ3dlYmtpdE9mZmxpbmVBdWRpb0NvbnRleHQnKSA/IHdpbmRvdy53ZWJraXRPZmZsaW5lQXVkaW9Db250ZXh0IDogbnVsbDtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZSB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLWF1ZGlvLXBhcmFtLXZhbHVlJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvYXNzaWduLW5hdGl2ZS1hdWRpby1ub2RlLW9wdGlvbic7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMgfSBmcm9tICcuLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmltcG9ydCB7IHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1uZWdhdGl2ZS1wYXJhbWV0ZXJzJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkgPSAoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBvcHRpb25zLCAnZGV0dW5lJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZUF1ZGlvUGFyYW1WYWx1ZShuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ2ZyZXF1ZW5jeScpO1xuICAgICAgICBpZiAob3B0aW9ucy5wZXJpb2RpY1dhdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbmF0aXZlT3NjaWxsYXRvck5vZGUuc2V0UGVyaW9kaWNXYXZlKG9wdGlvbnMucGVyaW9kaWNXYXZlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVPc2NpbGxhdG9yTm9kZSwgb3B0aW9ucywgJ3R5cGUnKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBCdWcgIzQ0OiBPbmx5IENocm9tZSAmIEVkZ2UgdGhyb3cgYSBSYW5nZUVycm9yIHlldC5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVycyhuYXRpdmVPc2NpbGxhdG9yTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxOTogU2FmYXJpIGRvZXMgbm90IGlnbm9yZSBjYWxscyB0byBzdG9wKCkgb2YgYW4gYWxyZWFkeSBzdG9wcGVkIEF1ZGlvQnVmZmVyU291cmNlTm9kZS5cbiAgICAgICAgaWYgKCFjYWNoZVRlc3RSZXN1bHQodGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydChuYXRpdmVDb250ZXh0KSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyhuYXRpdmVPc2NpbGxhdG9yTm9kZSwgbmF0aXZlQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICM0NDogT25seSBGaXJlZm94IGRvZXMgbm90IHRocm93IGEgUmFuZ2VFcnJvciB5ZXQuXG4gICAgICAgIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0KG5hdGl2ZUNvbnRleHQpKSkge1xuICAgICAgICAgICAgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnMobmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEJ1ZyAjMTc1OiBTYWZhcmkgd2lsbCBub3QgZmlyZSBhbiBlbmRlZCBldmVudCBpZiB0aGUgT3NjaWxsYXRvck5vZGUgaXMgdW5jb25uZWN0ZWQuXG4gICAgICAgIGFkZFNpbGVudENvbm5lY3Rpb24obmF0aXZlQ29udGV4dCwgbmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICByZXR1cm4gbmF0aXZlT3NjaWxsYXRvck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtYXVkaW8tcGFyYW0tdmFsdWUnO1xuaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgICAgIC8vIEJ1ZyAjMTI0OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBtb2RpZnlpbmcgdGhlIG9yaWVudGF0aW9uIGFuZCB0aGUgcG9zaXRpb24gd2l0aCBBdWRpb1BhcmFtcy5cbiAgICAgICAgaWYgKG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25YID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblgnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblknKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdvcmllbnRhdGlvblonKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblgnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblknKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdwb3NpdGlvblonKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdjb25lSW5uZXJBbmdsZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2NvbmVPdXRlckFuZ2xlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAnY29uZU91dGVyR2FpbicpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ2Rpc3RhbmNlTW9kZWwnKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVBhbm5lck5vZGUsIG9wdGlvbnMsICdtYXhEaXN0YW5jZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3Bhbm5pbmdNb2RlbCcpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlUGFubmVyTm9kZSwgb3B0aW9ucywgJ3JlZkRpc3RhbmNlJyk7XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbihuYXRpdmVQYW5uZXJOb2RlLCBvcHRpb25zLCAncm9sbG9mZkZhY3RvcicpO1xuICAgICAgICByZXR1cm4gbmF0aXZlUGFubmVyTm9kZTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS1wYW5uZXItbm9kZS1mYWN0b3J5LmpzLm1hcCIsImltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IGludGVyY2VwdENvbm5lY3Rpb25zIH0gZnJvbSAnLi4vaGVscGVycy9pbnRlcmNlcHQtY29ubmVjdGlvbnMnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkgPSAoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRGaXJzdFNhbXBsZSwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCB7IGNvbmVJbm5lckFuZ2xlLCBjb25lT3V0ZXJBbmdsZSwgY29uZU91dGVyR2FpbiwgZGlzdGFuY2VNb2RlbCwgbWF4RGlzdGFuY2UsIG9yaWVudGF0aW9uWCwgb3JpZW50YXRpb25ZLCBvcmllbnRhdGlvblosIHBhbm5pbmdNb2RlbCwgcG9zaXRpb25YLCBwb3NpdGlvblksIHBvc2l0aW9uWiwgcmVmRGlzdGFuY2UsIHJvbGxvZmZGYWN0b3IsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBwYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQYW5uZXIoKTtcbiAgICAgICAgLy8gQnVnICMxMjU6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgIGlmIChhdWRpb05vZGVPcHRpb25zLmNoYW5uZWxDb3VudCA+IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMjY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgIGlmIChhdWRpb05vZGVPcHRpb25zLmNoYW5uZWxDb3VudE1vZGUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMocGFubmVyTm9kZSwgYXVkaW9Ob2RlT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX09QVElPTlMgPSB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnXG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IGNoYW5uZWxNZXJnZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiA2XG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBnYWluOiAxIH0pO1xuICAgICAgICBjb25zdCBvcmllbnRhdGlvblhHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3Qgb3JpZW50YXRpb25ZR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IG9yaWVudGF0aW9uWkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBwb3NpdGlvblhHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgY29uc3QgcG9zaXRpb25ZR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIGNvbnN0IHBvc2l0aW9uWkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICBjb25zdCBzY3JpcHRQcm9jZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZShuYXRpdmVDb250ZXh0LCAyNTYsIDYsIDEpO1xuICAgICAgICBjb25zdCB3YXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbmV3IEZsb2F0MzJBcnJheShbMSwgMV0pLFxuICAgICAgICAgICAgb3ZlcnNhbXBsZTogJ25vbmUnXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgbGFzdE9yaWVudGF0aW9uID0gW29yaWVudGF0aW9uWCwgb3JpZW50YXRpb25ZLCBvcmllbnRhdGlvblpdO1xuICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gW3Bvc2l0aW9uWCwgcG9zaXRpb25ZLCBwb3NpdGlvblpdO1xuICAgICAgICBjb25zdCBidWZmZXIgPSBuZXcgRmxvYXQzMkFycmF5KDEpO1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9ICh7IGlucHV0QnVmZmVyIH0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW1xuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDApLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDEpLFxuICAgICAgICAgICAgICAgIGdldEZpcnN0U2FtcGxlKGlucHV0QnVmZmVyLCBidWZmZXIsIDIpXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgaWYgKG9yaWVudGF0aW9uLnNvbWUoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgIT09IGxhc3RPcmllbnRhdGlvbltpbmRleF0pKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRPcmllbnRhdGlvbiguLi5vcmllbnRhdGlvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBsYXN0T3JpZW50YXRpb24gPSBvcmllbnRhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHBvc2l0b24gPSBbXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgMyksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNCksXG4gICAgICAgICAgICAgICAgZ2V0Rmlyc3RTYW1wbGUoaW5wdXRCdWZmZXIsIGJ1ZmZlciwgNSlcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBpZiAocG9zaXRvbi5zb21lKCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlICE9PSBsYXN0UG9zaXRpb25baW5kZXhdKSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0UG9zaXRpb24oLi4ucG9zaXRvbik7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICBsYXN0UG9zaXRpb24gPSBwb3NpdG9uO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3JpZW50YXRpb25ZR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob3JpZW50YXRpb25aR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25YR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25ZR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocG9zaXRpb25aR2Fpbk5vZGUuZ2FpbiwgJ2RlZmF1bHRWYWx1ZScsIHsgZ2V0OiAoKSA9PiAwIH0pO1xuICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlRmFrZXIgPSB7XG4gICAgICAgICAgICBnZXQgYnVmZmVyU2l6ZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY2hhbm5lbENvdW50O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyNTogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbENvdW50TW9kZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsQ291bnRNb2RlKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjY6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBlcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSAnbWF4Jykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5jb25lT3V0ZXJHYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjb25lT3V0ZXJHYWluKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMjc6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbnZhbGlkU3RhdGVFcnJvciB5ZXQuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5jb25lT3V0ZXJHYWluID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgZGlzdGFuY2VNb2RlbCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBtYXhEaXN0YW5jZSgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5tYXhEaXN0YW5jZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgbWF4RGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEyODogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUubWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhbm5lck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG9yaWVudGF0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gb3JpZW50YXRpb25YR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgb3JpZW50YXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcmllbnRhdGlvbllHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBvcmllbnRhdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9yaWVudGF0aW9uWkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBhbm5pbmdNb2RlbCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcGFubmVyTm9kZS5wYW5uaW5nTW9kZWw7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHBhbm5pbmdNb2RlbCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucGFubmluZ01vZGVsID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zaXRpb25YR2Fpbk5vZGUuZ2FpbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcG9zaXRpb25ZKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwb3NpdGlvbllHYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBwb3NpdGlvblooKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uWkdhaW5Ob2RlLmdhaW47XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnJlZkRpc3RhbmNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCByZWZEaXN0YW5jZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTI5OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgeWV0LlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA8IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFubmVyTm9kZS5yZWZEaXN0YW5jZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IHJvbGxvZmZGYWN0b3IodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEzMDogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIGVycm9yIHlldC5cbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBhbm5lck5vZGUucm9sbG9mZkZhY3RvciA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY29uZUlubmVyQW5nbGUgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lSW5uZXJBbmdsZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVJbm5lckFuZ2xlID0gY29uZUlubmVyQW5nbGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbmVPdXRlckFuZ2xlICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyQW5nbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5jb25lT3V0ZXJBbmdsZSA9IGNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb25lT3V0ZXJHYWluICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuY29uZU91dGVyR2Fpbikge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmNvbmVPdXRlckdhaW4gPSBjb25lT3V0ZXJHYWluO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXN0YW5jZU1vZGVsICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIuZGlzdGFuY2VNb2RlbCkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLmRpc3RhbmNlTW9kZWwgPSBkaXN0YW5jZU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXhEaXN0YW5jZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm1heERpc3RhbmNlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIubWF4RGlzdGFuY2UgPSBtYXhEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAob3JpZW50YXRpb25YICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25YLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIub3JpZW50YXRpb25YLnZhbHVlID0gb3JpZW50YXRpb25YO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcmllbnRhdGlvblkgIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblkudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5vcmllbnRhdGlvblkudmFsdWUgPSBvcmllbnRhdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9yaWVudGF0aW9uWiAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWi52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLm9yaWVudGF0aW9uWi52YWx1ZSA9IG9yaWVudGF0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFubmluZ01vZGVsICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucGFubmluZ01vZGVsKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucGFubmluZ01vZGVsID0gcGFubmluZ01vZGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvblggIT09IG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblgudmFsdWUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5wb3NpdGlvblgudmFsdWUgPSBwb3NpdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvc2l0aW9uWSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWS52YWx1ZSkge1xuICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZUZha2VyLnBvc2l0aW9uWS52YWx1ZSA9IHBvc2l0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zaXRpb25aICE9PSBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25aLnZhbHVlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucG9zaXRpb25aLnZhbHVlID0gcG9zaXRpb25aO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWZEaXN0YW5jZSAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnJlZkRpc3RhbmNlKSB7XG4gICAgICAgICAgICBuYXRpdmVQYW5uZXJOb2RlRmFrZXIucmVmRGlzdGFuY2UgPSByZWZEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocm9sbG9mZkZhY3RvciAhPT0gbmF0aXZlUGFubmVyTm9kZUZha2VyLnJvbGxvZmZGYWN0b3IpIHtcbiAgICAgICAgICAgIG5hdGl2ZVBhbm5lck5vZGVGYWtlci5yb2xsb2ZmRmFjdG9yID0gcm9sbG9mZkZhY3RvcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGFzdE9yaWVudGF0aW9uWzBdICE9PSAxIHx8IGxhc3RPcmllbnRhdGlvblsxXSAhPT0gMCB8fCBsYXN0T3JpZW50YXRpb25bMl0gIT09IDApIHtcbiAgICAgICAgICAgIHBhbm5lck5vZGUuc2V0T3JpZW50YXRpb24oLi4ubGFzdE9yaWVudGF0aW9uKTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICB9XG4gICAgICAgIGlmIChsYXN0UG9zaXRpb25bMF0gIT09IDAgfHwgbGFzdFBvc2l0aW9uWzFdICE9PSAwIHx8IGxhc3RQb3NpdGlvblsyXSAhPT0gMCkge1xuICAgICAgICAgICAgcGFubmVyTm9kZS5zZXRQb3NpdGlvbiguLi5sYXN0UG9zaXRpb24pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOmRlcHJlY2F0aW9uXG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChwYW5uZXJOb2RlKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgICAgICBjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUoaW5wdXRHYWluTm9kZSwgd2F2ZVNoYXBlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChvcmllbnRhdGlvblhHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KG9yaWVudGF0aW9uWUdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3Qob3JpZW50YXRpb25aR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDIpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuY29ubmVjdChwb3NpdGlvblhHYWluTm9kZSkuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMyk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5jb25uZWN0KHBvc2l0aW9uWUdhaW5Ob2RlKS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCA0KTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocG9zaXRpb25aR2Fpbk5vZGUpLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDUpO1xuICAgICAgICAgICAgY2hhbm5lbE1lcmdlck5vZGUuY29ubmVjdChzY3JpcHRQcm9jZXNzb3JOb2RlKS5jb25uZWN0KG5hdGl2ZUNvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHBhbm5lck5vZGUpO1xuICAgICAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlKGlucHV0R2Fpbk5vZGUsIHdhdmVTaGFwZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3JpZW50YXRpb25YR2Fpbk5vZGUpO1xuICAgICAgICAgICAgb3JpZW50YXRpb25YR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KG9yaWVudGF0aW9uWUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWUdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChvcmllbnRhdGlvblpHYWluTm9kZSk7XG4gICAgICAgICAgICBvcmllbnRhdGlvblpHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIHdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocG9zaXRpb25YR2Fpbk5vZGUpO1xuICAgICAgICAgICAgcG9zaXRpb25YR2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgICAgICB3YXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHBvc2l0aW9uWUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIHBvc2l0aW9uWUdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICAgICAgd2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwb3NpdGlvblpHYWluTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGlvblpHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlKTtcbiAgICAgICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmRpc2Nvbm5lY3Qoc2NyaXB0UHJvY2Vzc29yTm9kZSk7XG4gICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmRpc2Nvbm5lY3QobmF0aXZlQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlUGFubmVyTm9kZUZha2VyLCBwYW5uZXJOb2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeSA9IChjcmVhdGVJbmRleFNpemVFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgeyBkaXNhYmxlTm9ybWFsaXphdGlvbiwgaW1hZywgcmVhbCB9KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMTgwOiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gdXNlIG9yZGluYXJ5IGFycmF5cy5cbiAgICAgICAgY29uc3QgY29udmVydGVkSW1hZyA9IGltYWcgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBpbWFnIDogbmV3IEZsb2F0MzJBcnJheShpbWFnKTtcbiAgICAgICAgY29uc3QgY29udmVydGVkUmVhbCA9IHJlYWwgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyByZWFsIDogbmV3IEZsb2F0MzJBcnJheShyZWFsKTtcbiAgICAgICAgY29uc3QgbmF0aXZlUGVyaW9kaWNXYXZlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUoY29udmVydGVkUmVhbCwgY29udmVydGVkSW1hZywgeyBkaXNhYmxlTm9ybWFsaXphdGlvbiB9KTtcbiAgICAgICAgLy8gQnVnICMxODE6IFNhZmFyaSBkb2VzIG5vdCB0aHJvdyBhbiBJbmRleFNpemVFcnJvciBzbyBmYXIgaWYgdGhlIGdpdmVuIGFycmF5cyBoYXZlIGxlc3MgdGhhbiB0d28gdmFsdWVzLlxuICAgICAgICBpZiAoQXJyYXkuZnJvbShpbWFnKS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuYXRpdmVQZXJpb2RpY1dhdmU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtcGVyaW9kaWMtd2F2ZS1mYWN0b3J5LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlID0gKG5hdGl2ZUNvbnRleHQsIGJ1ZmZlclNpemUsIG51bWJlck9mSW5wdXRDaGFubmVscywgbnVtYmVyT2ZPdXRwdXRDaGFubmVscykgPT4ge1xuICAgIHJldHVybiBuYXRpdmVDb250ZXh0LmNyZWF0ZVNjcmlwdFByb2Nlc3NvcihidWZmZXJTaXplLCBudW1iZXJPZklucHV0Q2hhbm5lbHMsIG51bWJlck9mT3V0cHV0Q2hhbm5lbHMpOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lIGRlcHJlY2F0aW9uXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXNjcmlwdC1wcm9jZXNzb3Itbm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVBdWRpb1BhcmFtVmFsdWUgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1hdWRpby1wYXJhbS12YWx1ZSc7XG5pbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvcikgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQ29udGV4dCwgb3B0aW9ucykgPT4ge1xuICAgICAgICBjb25zdCBjaGFubmVsQ291bnRNb2RlID0gb3B0aW9ucy5jaGFubmVsQ291bnRNb2RlO1xuICAgICAgICAvKlxuICAgICAgICAgKiBCdWcgIzEwNTogVGhlIGNoYW5uZWxDb3VudE1vZGUgb2YgJ2NsYW1wZWQtbWF4JyBzaG91bGQgYmUgc3VwcG9ydGVkLiBIb3dldmVyIGl0IGlzIG5vdCBwb3NzaWJsZSB0byB3cml0ZSBhIHBvbHlmaWxsIGZvciBTYWZhcmlcbiAgICAgICAgICogd2hpY2ggc3VwcG9ydHMgaXQgYW5kIHRoZXJlZm9yZSBpdCBjYW4ndCBiZSBzdXBwb3J0ZWQgYXQgYWxsLlxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudE1vZGUgPT09ICdjbGFtcGVkLW1heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQnVnICMxMDU6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBTdGVyZW9QYW5uZXJOb2RlLlxuICAgICAgICBpZiAobmF0aXZlQ29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlcihuYXRpdmVDb250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBvcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlQXVkaW9QYXJhbVZhbHVlKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIG9wdGlvbnMsICdwYW4nKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMDU6IFRoZSBjaGFubmVsQ291bnRNb2RlIG9mICdjbGFtcGVkLW1heCcgc2hvdWxkIGJlIHN1cHBvcnRlZC4gSG93ZXZlciBpdCBpcyBub3QgcG9zc2libGUgdG8gd3JpdGUgYSBwb2x5ZmlsbCBmb3IgU2FmYXJpXG4gICAgICAgICAqIHdoaWNoIHN1cHBvcnRzIGl0IGFuZCB0aGVyZWZvcmUgaXQgY2FuJ3QgYmUgc3VwcG9ydGVkIGF0IGFsbC5cbiAgICAgICAgICovXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIHNldDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBjaGFubmVsQ291bnRNb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGU7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgLy8gVGhlIGN1cnZlIGhhcyBhIHNpemUgb2YgMTRiaXQgcGx1cyAxIHZhbHVlIHRvIGhhdmUgYW4gZXhhY3QgcmVwcmVzZW50YXRpb24gZm9yIHplcm8uIFRoaXMgdmFsdWUgaGFzIGJlZW4gZGV0ZXJtaW5lZCBleHBlcmltZW50YWxseS5cbiAgICBjb25zdCBDVVJWRV9TSVpFID0gMTYzODU7XG4gICAgY29uc3QgRENfQ1VSVkUgPSBuZXcgRmxvYXQzMkFycmF5KFsxLCAxXSk7XG4gICAgY29uc3QgSEFMRl9QSSA9IE1hdGguUEkgLyAyO1xuICAgIGNvbnN0IFNJTkdMRV9DSEFOTkVMX09QVElPTlMgPSB7IGNoYW5uZWxDb3VudDogMSwgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JywgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnIH07XG4gICAgY29uc3QgU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUyA9IHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgb3ZlcnNhbXBsZTogJ25vbmUnIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoRm9yTW9ubyA9IChuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgbGVmdFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBDVVJWRV9TSVpFOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHggPSAoaSAvIChDVVJWRV9TSVpFIC0gMSkpICogSEFMRl9QSTtcbiAgICAgICAgICAgIGxlZnRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbGVmdEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCBsZWZ0V2F2ZVNoYXBlck5vZGUgPSAoY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9XQVZFX1NIQVBFUl9PUFRJT05TLCBjdXJ2ZTogbGVmdFdhdmVTaGFwZXJDdXJ2ZSB9KSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHBhbldhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IERDX0NVUlZFIH0pKTtcbiAgICAgICAgY29uc3QgcmlnaHRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRXYXZlU2hhcGVyTm9kZSA9IChjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsIGN1cnZlOiByaWdodFdhdmVTaGFwZXJDdXJ2ZSB9KSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGxlZnRHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KHBhbldhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcGFuV2F2ZVNoYXBlck5vZGUgOiBwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChyaWdodEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5XYXZlU2hhcGVyTm9kZS5jb25uZWN0KHBhbkdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IGxlZnRXYXZlU2hhcGVyTm9kZSA6IGxlZnRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHJpZ2h0V2F2ZVNoYXBlck5vZGUgOiByaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICByaWdodEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc2Nvbm5lY3RHcmFwaCgpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdEdhaW5Ob2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KHJpZ2h0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QobGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gbGVmdFdhdmVTaGFwZXJOb2RlIDogbGVmdFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkID8gcmlnaHRXYXZlU2hhcGVyTm9kZSA6IHJpZ2h0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbiAgICBjb25zdCBidWlsZEludGVybmFsR3JhcGhGb3JTdGVyZW8gPSAobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KENVUlZFX1NJWkUpO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoQ1VSVkVfU0laRSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlID0gbmV3IEZsb2F0MzJBcnJheShDVVJWRV9TSVpFKTtcbiAgICAgICAgY29uc3QgY2VudGVySW5kZXggPSBNYXRoLmZsb29yKENVUlZFX1NJWkUgLyAyKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBDVVJWRV9TSVpFOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmIChpID4gY2VudGVySW5kZXgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gKChpIC0gY2VudGVySW5kZXgpIC8gKENVUlZFX1NJWkUgLSAxIC0gY2VudGVySW5kZXgpKSAqIEhBTEZfUEk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IE1hdGguY29zKHgpO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gTWF0aC5zaW4oeCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSAwO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCB4ID0gKGkgLyAoQ1VSVkVfU0laRSAtIDEgLSBjZW50ZXJJbmRleCkpICogSEFMRl9QSTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlckN1cnZlW2ldID0gMTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVtpXSA9IDA7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLmNvcyh4KTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVbaV0gPSBNYXRoLnNpbih4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFubmVsU3BsaXR0ZXJOb2RlID0gY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgbnVtYmVyT2ZPdXRwdXRzOiAyXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLlNJTkdMRV9DSEFOTkVMX09QVElPTlMsIGdhaW46IDAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IGxlZnRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJDdXJ2ZVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIEJ1ZyAjMTE5OiBTYWZhcmkgZG9lcyBub3QgZnVsbHkgc3VwcG9ydCB0aGUgV2F2ZVNoYXBlck5vZGUuXG4gICAgICAgIGNvbnN0IHBhbldhdmVTaGFwZXJOb2RlID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfV0FWRV9TSEFQRVJfT1BUSU9OUywgY3VydmU6IERDX0NVUlZFIH0pKTtcbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uU0lOR0xFX0NIQU5ORUxfT1BUSU9OUywgZ2FpbjogMCB9KTtcbiAgICAgICAgLy8gQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBmdWxseSBzdXBwb3J0IHRoZSBXYXZlU2hhcGVyTm9kZS5cbiAgICAgICAgY29uc3QgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyQ3VydmVcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5TSU5HTEVfQ0hBTk5FTF9PUFRJT05TLCBnYWluOiAwIH0pO1xuICAgICAgICAvLyBCdWcgIzExOTogU2FmYXJpIGRvZXMgbm90IGZ1bGx5IHN1cHBvcnQgdGhlIFdhdmVTaGFwZXJOb2RlLlxuICAgICAgICBjb25zdCByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlKG5hdGl2ZUNvbnRleHQsIHtcbiAgICAgICAgICAgIC4uLlNJTkdMRV9DSEFOTkVMX1dBVkVfU0hBUEVSX09QVElPTlMsXG4gICAgICAgICAgICBjdXJ2ZTogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlckN1cnZlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29ubmVjdEdyYXBoKCkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsU3BsaXR0ZXJOb2RlKTtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNvbm5lY3QocGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWQgPyBwYW5XYXZlU2hhcGVyTm9kZSA6IHBhbldhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5jb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDApO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAxKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIHBhbldhdmVTaGFwZXJOb2RlLmNvbm5lY3QocGFuR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0cyA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgID8gbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5jb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZVxuICAgICAgICAgICAgICAgICAgICA6IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuY29ubmVjdChyaWdodElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmdhaW4pO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlLmNvbm5lY3QocmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDApO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgICAgICByaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5jb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAxKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxTcGxpdHRlck5vZGUpO1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuZGlzY29ubmVjdChwYW5XYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZCA/IHBhbldhdmVTaGFwZXJOb2RlIDogcGFuV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yTGVmdE91dHB1dEdhaW5Ob2RlLCAwKTtcbiAgICAgICAgICAgICAgICBjaGFubmVsU3BsaXR0ZXJOb2RlLmRpc2Nvbm5lY3QobGVmdElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMCk7XG4gICAgICAgICAgICAgICAgY2hhbm5lbFNwbGl0dGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUsIDEpO1xuICAgICAgICAgICAgICAgIGNoYW5uZWxTcGxpdHRlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZSwgMSk7XG4gICAgICAgICAgICAgICAgcGFuV2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChwYW5HYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBwYW5HYWluTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgPyBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhbkdhaW5Ob2RlLmRpc2Nvbm5lY3QocmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGVcbiAgICAgICAgICAgICAgICAgICAgOiByaWdodElucHV0Rm9yTGVmdE91dHB1dFdhdmVTaGFwZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICAgICAgcGFuR2Fpbk5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5pbnB1dHMgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgICAgICA/IHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dFdhdmVTaGFwZXJOb2RlXG4gICAgICAgICAgICAgICAgICAgIDogcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgbGVmdElucHV0Rm9yUmlnaHRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KGxlZnRJbnB1dEZvclJpZ2h0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRXYXZlU2hhcGVyTm9kZS5kaXNjb25uZWN0KHJpZ2h0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvclJpZ2h0T3V0cHV0V2F2ZVNoYXBlck5vZGUuZGlzY29ubmVjdChyaWdodElucHV0Rm9yUmlnaHRPdXRwdXRHYWluTm9kZS5nYWluKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JMZWZ0T3V0cHV0R2Fpbk5vZGUuZGlzY29ubmVjdChjaGFubmVsTWVyZ2VyTm9kZSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgcmlnaHRJbnB1dEZvckxlZnRPdXRwdXRHYWluTm9kZS5kaXNjb25uZWN0KGNoYW5uZWxNZXJnZXJOb2RlLCAwLCAwKTtcbiAgICAgICAgICAgICAgICBsZWZ0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgICAgIHJpZ2h0SW5wdXRGb3JSaWdodE91dHB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgY29uc3QgYnVpbGRJbnRlcm5hbEdyYXBoID0gKG5hdGl2ZUNvbnRleHQsIGNoYW5uZWxDb3VudCwgaW5wdXRHYWluTm9kZSwgcGFuR2Fpbk5vZGUsIGNoYW5uZWxNZXJnZXJOb2RlKSA9PiB7XG4gICAgICAgIGlmIChjaGFubmVsQ291bnQgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBidWlsZEludGVybmFsR3JhcGhGb3JNb25vKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYW5uZWxDb3VudCA9PT0gMikge1xuICAgICAgICAgICAgcmV0dXJuIGJ1aWxkSW50ZXJuYWxHcmFwaEZvclN0ZXJlbyhuYXRpdmVDb250ZXh0LCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgfTtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY2hhbm5lbENvdW50LCBjaGFubmVsQ291bnRNb2RlLCBwYW4sIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBpZiAoY2hhbm5lbENvdW50TW9kZSA9PT0gJ21heCcpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZShuYXRpdmVDb250ZXh0LCB7XG4gICAgICAgICAgICAuLi5hdWRpb05vZGVPcHRpb25zLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIG51bWJlck9mSW5wdXRzOiAyXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBpbnB1dEdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwgeyAuLi5hdWRpb05vZGVPcHRpb25zLCBjaGFubmVsQ291bnQsIGNoYW5uZWxDb3VudE1vZGUsIGdhaW46IDEgfSk7XG4gICAgICAgIGNvbnN0IHBhbkdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlQ29udGV4dCwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgIGdhaW46IHBhblxuICAgICAgICB9KTtcbiAgICAgICAgbGV0IHsgY29ubmVjdEdyYXBoLCBkaXNjb25uZWN0R3JhcGggfSA9IGJ1aWxkSW50ZXJuYWxHcmFwaChuYXRpdmVDb250ZXh0LCBjaGFubmVsQ291bnQsIGlucHV0R2Fpbk5vZGUsIHBhbkdhaW5Ob2RlLCBjaGFubmVsTWVyZ2VyTm9kZSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnZGVmYXVsdFZhbHVlJywgeyBnZXQ6ICgpID0+IDAgfSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwYW5HYWluTm9kZS5nYWluLCAnbWF4VmFsdWUnLCB7IGdldDogKCkgPT4gMSB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHBhbkdhaW5Ob2RlLmdhaW4sICdtaW5WYWx1ZScsIHsgZ2V0OiAoKSA9PiAtMSB9KTtcbiAgICAgICAgY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAoeyBjb25uZWN0R3JhcGgsIGRpc2Nvbm5lY3RHcmFwaCB9ID0gYnVpbGRJbnRlcm5hbEdyYXBoKG5hdGl2ZUNvbnRleHQsIHZhbHVlLCBpbnB1dEdhaW5Ob2RlLCBwYW5HYWluTm9kZSwgY2hhbm5lbE1lcmdlck5vZGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25uZWN0R3JhcGgoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT09ICdjbGFtcGVkLW1heCcgfHwgdmFsdWUgPT09ICdtYXgnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsSW50ZXJwcmV0YXRpb24oKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBjaGFubmVsSW50ZXJwcmV0YXRpb24odmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmNvbnRleHQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGlucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW2lucHV0R2Fpbk5vZGVdO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBudW1iZXJPZklucHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZPdXRwdXRzKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLm51bWJlck9mT3V0cHV0cztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgcGFuKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBwYW5HYWluTm9kZS5nYWluO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgaXNDb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbm5lY3RHcmFwaCgpO1xuICAgICAgICAgICAgaXNDb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgZGlzY29ubmVjdEdyYXBoKCk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbW9uaXRvckNvbm5lY3Rpb25zKGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnksIGNoYW5uZWxNZXJnZXJOb2RlKSwgd2hlbkNvbm5lY3RlZCwgd2hlbkRpc2Nvbm5lY3RlZCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9uJztcbmltcG9ydCB7IGFzc2lnbk5hdGl2ZUF1ZGlvTm9kZU9wdGlvbnMgfSBmcm9tICcuLi9oZWxwZXJzL2Fzc2lnbi1uYXRpdmUtYXVkaW8tbm9kZS1vcHRpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkgPSAoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICMxMTk6IFNhZmFyaSBkb2VzIG5vdCBjb3JyZWN0bHkgbWFwIHRoZSB2YWx1ZXMuXG4gICAgICAgICAqIEB0b2RvIFVuZm9ydHVuYXRlbHkgdGhlcmUgaXMgbm8gd2F5IHRvIHRlc3QgZm9yIHRoaXMgYmVoYXZpb3IgaW4gYSBzeW5jaHJvbm91cyBmYXNoaW9uIHdoaWNoIGlzIHdoeSB0ZXN0aW5nIGZvciB0aGUgZXhpc3RlbmNlIG9mXG4gICAgICAgICAqIHRoZSB3ZWJraXRBdWRpb0NvbnRleHQgaXMgdXNlZCBhcyBhIHdvcmthcm91bmQgaGVyZS4gVGVzdGluZyBmb3IgdGhlIGF1dG9tYXRpb25SYXRlIHByb3BlcnR5IGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHRoaXMgd29ya2Fyb3VuZFxuICAgICAgICAgKiBpc24ndCBuZWNlc3NhcnkgYW55bW9yZSBzaW5jZSB2MTQuMC4yIG9mIFNhZmFyaS5cbiAgICAgICAgICovXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IubmFtZSA9PT0gJ3dlYmtpdEF1ZGlvQ29udGV4dCcgJiZcbiAgICAgICAgICAgIG5hdGl2ZUNvbnRleHQuY3JlYXRlR2FpbigpLmdhaW4uYXV0b21hdGlvblJhdGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIobmF0aXZlQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgb3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGN1cnZlID0gb3B0aW9ucy5jdXJ2ZSA9PT0gbnVsbCB8fCBvcHRpb25zLmN1cnZlIGluc3RhbmNlb2YgRmxvYXQzMkFycmF5ID8gb3B0aW9ucy5jdXJ2ZSA6IG5ldyBGbG9hdDMyQXJyYXkob3B0aW9ucy5jdXJ2ZSk7XG4gICAgICAgIC8vIEJ1ZyAjMTA0OiBDaHJvbWUgYW5kIEVkZ2Ugd2lsbCB0aHJvdyBhbiBJbnZhbGlkQWNjZXNzRXJyb3Igd2hlbiB0aGUgY3VydmUgaGFzIGxlc3MgdGhhbiB0d28gc2FtcGxlcy5cbiAgICAgICAgaWYgKGN1cnZlICE9PSBudWxsICYmIGN1cnZlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSB2YWx1ZXMgb2YgdHlwZSBGbG9hdDMyQXJyYXkgY2FuIGJlIGFzc2lnbmVkIHRvIHRoZSBjdXJ2ZSBwcm9wZXJ0eS5cbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9uKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB7IGN1cnZlIH0sICdjdXJ2ZScpO1xuICAgICAgICBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb24obmF0aXZlV2F2ZVNoYXBlck5vZGUsIG9wdGlvbnMsICdvdmVyc2FtcGxlJyk7XG4gICAgICAgIGxldCBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbnVsbDtcbiAgICAgICAgbGV0IGlzQ29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgIG92ZXJ3cml0ZUFjY2Vzc29ycyhuYXRpdmVXYXZlU2hhcGVyTm9kZSwgJ2N1cnZlJywgKGdldCkgPT4gKCkgPT4gZ2V0LmNhbGwobmF0aXZlV2F2ZVNoYXBlck5vZGUpLCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHNldC5jYWxsKG5hdGl2ZVdhdmVTaGFwZXJOb2RlLCB2YWx1ZSk7XG4gICAgICAgICAgICBpZiAoaXNDb25uZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNEQ0N1cnZlKHZhbHVlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICghaXNEQ0N1cnZlKHZhbHVlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChpc0RDQ3VydmUobmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUpKSB7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZShuYXRpdmVDb250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFjdG9yeS5qcy5tYXAiLCJpbXBvcnQgeyBhc3NpZ25OYXRpdmVBdWRpb05vZGVPcHRpb25zIH0gZnJvbSAnLi4vaGVscGVycy9hc3NpZ24tbmF0aXZlLWF1ZGlvLW5vZGUtb3B0aW9ucyc7XG5pbXBvcnQgeyBpbnRlcmNlcHRDb25uZWN0aW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvaW50ZXJjZXB0LWNvbm5lY3Rpb25zJztcbmV4cG9ydCBjb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyRmFjdG9yeSA9IChjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgaXNEQ0N1cnZlLCBtb25pdG9yQ29ubmVjdGlvbnMpID0+IHtcbiAgICByZXR1cm4gKG5hdGl2ZUNvbnRleHQsIHsgY3VydmUsIG92ZXJzYW1wbGUsIC4uLmF1ZGlvTm9kZU9wdGlvbnMgfSkgPT4ge1xuICAgICAgICBjb25zdCBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgICAgIGNvbnN0IHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZVdhdmVTaGFwZXIoKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgYXNzaWduTmF0aXZlQXVkaW9Ob2RlT3B0aW9ucyhwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLCBhdWRpb05vZGVPcHRpb25zKTtcbiAgICAgICAgY29uc3QgaW5wdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgaW52ZXJ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IC0xIH0pO1xuICAgICAgICBjb25zdCBvdXRwdXRHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZUNvbnRleHQsIHsgLi4uYXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMSB9KTtcbiAgICAgICAgY29uc3QgcmV2ZXJ0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVDb250ZXh0LCB7IC4uLmF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IC0xIH0pO1xuICAgICAgICBsZXQgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgIGxldCBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgdW5tb2RpZmllZEN1cnZlID0gbnVsbDtcbiAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciA9IHtcbiAgICAgICAgICAgIGdldCBidWZmZXJTaXplKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNoYW5uZWxDb3VudCgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaW52ZXJ0R2Fpbk5vZGUuY2hhbm5lbENvdW50ID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBvdXRwdXRHYWluTm9kZS5jaGFubmVsQ291bnQgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0IGNoYW5uZWxDb3VudE1vZGUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsQ291bnRNb2RlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgb3V0cHV0R2Fpbk5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHJldmVydEdhaW5Ob2RlLmNoYW5uZWxDb3VudE1vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY2hhbm5lbEludGVycHJldGF0aW9uKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbjtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBpbnZlcnRHYWluTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24gPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIG91dHB1dEdhaW5Ob2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uID0gdmFsdWU7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY29udGV4dDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVubW9kaWZpZWRDdXJ2ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgY3VydmUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VydmVMZW5ndGggPSB2YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5lZ2F0aXZlQ3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KGN1cnZlTGVuZ3RoICsgMiAtIChjdXJ2ZUxlbmd0aCAlIDIpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcG9zaXRpdmVDdXJ2ZSA9IG5ldyBGbG9hdDMyQXJyYXkoY3VydmVMZW5ndGggKyAyIC0gKGN1cnZlTGVuZ3RoICUgMikpO1xuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlWzBdID0gdmFsdWVbMF07XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aXZlQ3VydmVbMF0gPSAtdmFsdWVbY3VydmVMZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gTWF0aC5jZWlsKChjdXJ2ZUxlbmd0aCArIDEpIC8gMik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRlckluZGV4ID0gKGN1cnZlTGVuZ3RoICsgMSkgLyAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGhlb3JldGljSW5kZXggPSAoaSAvIGxlbmd0aCkgKiBjZW50ZXJJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvd2VySW5kZXggPSBNYXRoLmZsb29yKHRoZW9yZXRpY0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVwcGVySW5kZXggPSBNYXRoLmNlaWwodGhlb3JldGljSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmVnYXRpdmVDdXJ2ZVtpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHZhbHVlW2xvd2VySW5kZXhdXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZVtsb3dlckluZGV4XSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMSAtICh1cHBlckluZGV4IC0gdGhlb3JldGljSW5kZXgpKSAqIHZhbHVlW3VwcGVySW5kZXhdO1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpdmVDdXJ2ZVtpXSA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJJbmRleCA9PT0gdXBwZXJJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC12YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSBsb3dlckluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IC0oKDEgLSAodGhlb3JldGljSW5kZXggLSBsb3dlckluZGV4KSkgKiB2YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSBsb3dlckluZGV4XSkgLVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDEgLSAodXBwZXJJbmRleCAtIHRoZW9yZXRpY0luZGV4KSkgKiB2YWx1ZVtjdXJ2ZUxlbmd0aCAtIDEgLSB1cHBlckluZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBuZWdhdGl2ZUN1cnZlW2xlbmd0aF0gPSBjdXJ2ZUxlbmd0aCAlIDIgPT09IDEgPyB2YWx1ZVtsZW5ndGggLSAxXSA6ICh2YWx1ZVtsZW5ndGggLSAyXSArIHZhbHVlW2xlbmd0aCAtIDFdKSAvIDI7XG4gICAgICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBuZWdhdGl2ZUN1cnZlO1xuICAgICAgICAgICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmN1cnZlID0gcG9zaXRpdmVDdXJ2ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdW5tb2RpZmllZEN1cnZlID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKGlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodW5tb2RpZmllZEN1cnZlKSAmJiBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKG5hdGl2ZUNvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGdldCBpbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtpbnB1dEdhaW5Ob2RlXTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmVnYXRpdmVXYXZlU2hhcGVyTm9kZS5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZ2V0IG92ZXJzYW1wbGUoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgb3ZlcnNhbXBsZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIG5lZ2F0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgIHBvc2l0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZEV2ZW50TGlzdGVuZXIoLi4uYXJncykge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnB1dEdhaW5Ob2RlLmFkZEV2ZW50TGlzdGVuZXIoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZGlzcGF0Y2hFdmVudCguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGlucHV0R2Fpbk5vZGUuZGlzcGF0Y2hFdmVudChhcmdzWzBdKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZW1vdmVFdmVudExpc3RlbmVyKC4uLmFyZ3MpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRHYWluTm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoY3VydmUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIE9ubHkgdmFsdWVzIG9mIHR5cGUgRmxvYXQzMkFycmF5IGNhbiBiZSBhc3NpZ25lZCB0byB0aGUgY3VydmUgcHJvcGVydHkuXG4gICAgICAgICAgICBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLmN1cnZlID0gY3VydmUgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgPyBjdXJ2ZSA6IG5ldyBGbG9hdDMyQXJyYXkoY3VydmUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvdmVyc2FtcGxlICE9PSBuYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyLm92ZXJzYW1wbGUpIHtcbiAgICAgICAgICAgIG5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgd2hlbkNvbm5lY3RlZCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlKS5jb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlucHV0R2Fpbk5vZGUuY29ubmVjdChpbnZlcnRHYWluTm9kZSkuY29ubmVjdChwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlKS5jb25uZWN0KHJldmVydEdhaW5Ob2RlKS5jb25uZWN0KG91dHB1dEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmIChpc0RDQ3VydmUodW5tb2RpZmllZEN1cnZlKSkge1xuICAgICAgICAgICAgICAgIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUobmF0aXZlQ29udGV4dCwgaW5wdXRHYWluTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGNvbnN0IHdoZW5EaXNjb25uZWN0ZWQgPSAoKSA9PiB7XG4gICAgICAgICAgICBpbnB1dEdhaW5Ob2RlLmRpc2Nvbm5lY3QobmVnYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBuZWdhdGl2ZVdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3Qob3V0cHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5kaXNjb25uZWN0KGludmVydEdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGludmVydEdhaW5Ob2RlLmRpc2Nvbm5lY3QocG9zaXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBwb3NpdGl2ZVdhdmVTaGFwZXJOb2RlLmRpc2Nvbm5lY3QocmV2ZXJ0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgcmV2ZXJ0R2Fpbk5vZGUuZGlzY29ubmVjdChvdXRwdXRHYWluTm9kZSk7XG4gICAgICAgICAgICBpc0Nvbm5lY3RlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc2Nvbm5lY3ROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBkaXNjb25uZWN0TmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKCk7XG4gICAgICAgICAgICAgICAgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtb25pdG9yQ29ubmVjdGlvbnMoaW50ZXJjZXB0Q29ubmVjdGlvbnMobmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlciwgb3V0cHV0R2Fpbk5vZGUpLCB3aGVuQ29ubmVjdGVkLCB3aGVuRGlzY29ubmVjdGVkKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW5hdGl2ZS13YXZlLXNoYXBlci1ub2RlLWZha2VyLWZhY3RvcnkuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ05vdFN1cHBvcnRlZEVycm9yJyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ub3Qtc3VwcG9ydGVkLWVycm9yLmpzLm1hcCIsImltcG9ydCB7IGRlYWN0aXZhdGVBdWRpb0dyYXBoIH0gZnJvbSAnLi4vaGVscGVycy9kZWFjdGl2YXRlLWF1ZGlvLWdyYXBoJztcbmltcG9ydCB7IHRlc3RQcm9taXNlU3VwcG9ydCB9IGZyb20gJy4uL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIG51bWJlck9mQ2hhbm5lbHM6IDFcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gKGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY2FjaGVUZXN0UmVzdWx0LCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc3RhcnRSZW5kZXJpbmcpID0+IHtcbiAgICByZXR1cm4gY2xhc3MgT2ZmbGluZUF1ZGlvQ29udGV4dCBleHRlbmRzIGJhc2VBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGEsIGIsIGMpIHtcbiAgICAgICAgICAgIGxldCBvcHRpb25zO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhID09PSAnbnVtYmVyJyAmJiBiICE9PSB1bmRlZmluZWQgJiYgYyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IHsgbGVuZ3RoOiBiLCBudW1iZXJPZkNoYW5uZWxzOiBhLCBzYW1wbGVSYXRlOiBjIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gYTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGdpdmVuIHBhcmFtZXRlcnMgYXJlIG5vdCB2YWxpZC4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBudW1iZXJPZkNoYW5uZWxzLCBzYW1wbGVSYXRlIH0gPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vICMyMSBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyBhbmQgdGhlcmVmb3JlIHdvdWxkIGZpcmUgdGhlIHN0YXRlY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgcHJvbWlzZSBjYW4gYmUgcmVzb2x2ZWQuXG4gICAgICAgICAgICBpZiAoIWNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LmFkZEV2ZW50TGlzdGVuZXIoJ3N0YXRlY2hhbmdlJywgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQucmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RhdGVjaGFuZ2UnLCBkZWxheVN0YXRlQ2hhbmdlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fd2FpdEZvclRoZVByb21pc2VUb1NldHRsZShldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVsYXlTdGF0ZUNoYW5nZUV2ZW50O1xuICAgICAgICAgICAgICAgIH0pKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3VwZXIobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbnVtYmVyT2ZDaGFubmVscyk7XG4gICAgICAgICAgICB0aGlzLl9sZW5ndGggPSBsZW5ndGg7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dDtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICAgICAgLy8gQnVnICMxNzogU2FmYXJpIGRvZXMgbm90IHlldCBleHBvc2UgdGhlIGxlbmd0aC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IG51bGwgPyB0aGlzLl9uYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXRlIDogdGhpcy5fc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgc3RhcnRSZW5kZXJpbmcoKSB7XG4gICAgICAgICAgICAvKlxuICAgICAgICAgICAgICogQnVnICM5ICYgIzU5OiBJdCBpcyB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlIHRoYXQgc3RhcnRSZW5kZXJpbmcoKSB3aWxsIGZpcnN0IHJlbmRlciBhIHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LiBUaGVyZWZvcmVcbiAgICAgICAgICAgICAqIHRoZSBzdGF0ZSBvZiB0aGUgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCBtaWdodCBubyB0cmFuc2l0aW9uIHRvIHJ1bm5pbmcgaW1tZWRpYXRlbHkuXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gJ3J1bm5pbmcnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAncnVubmluZyc7XG4gICAgICAgICAgICByZXR1cm4gc3RhcnRSZW5kZXJpbmcodGhpcy5kZXN0aW5hdGlvbiwgdGhpcy5fbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkuZmluYWxseSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGRlYWN0aXZhdGVBdWRpb0dyYXBoKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGlzcGF0Y2hFdmVudChldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX3dhaXRGb3JUaGVQcm9taXNlVG9TZXR0bGUoZXZlbnQpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzQWN0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBzZXRJbnRlcm5hbFN0YXRlVG9BY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL3NldC1pbnRlcm5hbC1zdGF0ZS10by1hY3RpdmUnO1xuaW1wb3J0IHsgc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSB9IGZyb20gJy4uL2hlbHBlcnMvc2V0LWludGVybmFsLXN0YXRlLXRvLXBhc3NpdmUnO1xuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICBjaGFubmVsQ291bnRNb2RlOiAnbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgZGV0dW5lOiAwLFxuICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgIHBlcmlvZGljV2F2ZTogdW5kZWZpbmVkLFxuICAgIHR5cGU6ICdzaW5lJ1xufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yID0gKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiBjbGFzcyBPc2NpbGxhdG9yTm9kZSBleHRlbmRzIGF1ZGlvTm9kZUNvbnN0cnVjdG9yIHtcbiAgICAgICAgY29uc3RydWN0b3IoY29udGV4dCwgb3B0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29udGV4dCA9IGdldE5hdGl2ZUNvbnRleHQoY29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZWRPcHRpb25zID0geyAuLi5ERUZBVUxUX09QVElPTlMsIC4uLm9wdGlvbnMgfTtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZU9zY2lsbGF0b3JOb2RlID0gY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUobmF0aXZlQ29udGV4dCwgbWVyZ2VkT3B0aW9ucyk7XG4gICAgICAgICAgICBjb25zdCBpc09mZmxpbmUgPSBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQobmF0aXZlQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBvc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gKGlzT2ZmbGluZSA/IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgY29uc3QgbnlxdWlzdCA9IGNvbnRleHQuc2FtcGxlUmF0ZSAvIDI7XG4gICAgICAgICAgICBzdXBlcihjb250ZXh0LCBmYWxzZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUsIG9zY2lsbGF0b3JOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgLy8gQnVnICM4MTogRmlyZWZveCAmIFNhZmFyaSBkbyBub3QgZXhwb3J0IHRoZSBjb3JyZWN0IHZhbHVlcyBmb3IgbWF4VmFsdWUgYW5kIG1pblZhbHVlLlxuICAgICAgICAgICAgdGhpcy5fZGV0dW5lID0gY3JlYXRlQXVkaW9QYXJhbSh0aGlzLCBpc09mZmxpbmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSwgMTUzNjAwLCAtMTUzNjAwKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzY6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlT3NjaWxsYXRvck5vZGUuZnJlcXVlbmN5LCBueXF1aXN0LCAtbnlxdWlzdCk7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZSA9IG5hdGl2ZU9zY2lsbGF0b3JOb2RlO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gb3NjaWxsYXRvck5vZGVSZW5kZXJlcjtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsICYmIG1lcmdlZE9wdGlvbnMucGVyaW9kaWNXYXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9XG4gICAgICAgICAgICAgICAgICAgIG1lcmdlZE9wdGlvbnMucGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBkZXR1bmUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV0dW5lO1xuICAgICAgICB9XG4gICAgICAgIGdldCBmcmVxdWVuY3koKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICAgICAgICB9XG4gICAgICAgIGdldCBvbmVuZGVkKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29uZW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG9uZW5kZWQodmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHdyYXBwZWRMaXN0ZW5lciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJyA/IHdyYXBFdmVudExpc3RlbmVyKHRoaXMsIHZhbHVlKSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5vbmVuZGVkID0gd3JhcHBlZExpc3RlbmVyO1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlT25FbmRlZCA9IHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLm9uZW5kZWQ7XG4gICAgICAgICAgICB0aGlzLl9vbmVuZGVkID0gbmF0aXZlT25FbmRlZCAhPT0gbnVsbCAmJiBuYXRpdmVPbkVuZGVkID09PSB3cmFwcGVkTGlzdGVuZXIgPyB2YWx1ZSA6IG5hdGl2ZU9uRW5kZWQ7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgdHlwZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUudHlwZSA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyLnBlcmlvZGljV2F2ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JOb2RlUmVuZGVyZXIucGVyaW9kaWNXYXZlID0gcGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN0YXJ0KHdoZW4gPSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5zdGFydCA9IHdoZW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgICAgICAgICAgIHNldEludGVybmFsU3RhdGVUb0FjdGl2ZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNldEludGVybmFsU3RhdGVUb1Bhc3NpdmUgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX25hdGl2ZU9zY2lsbGF0b3JOb2RlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgcmVzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWN0aXZlQXVkaW9Ob2RlKHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZXRJbnRlcm5hbFN0YXRlVG9QYXNzaXZlKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVPc2NpbGxhdG9yTm9kZS5hZGRFdmVudExpc3RlbmVyKCdlbmRlZCcsIHJlc2V0SW50ZXJuYWxTdGF0ZVRvUGFzc2l2ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc3RvcCh3aGVuID0gMCkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlT3NjaWxsYXRvck5vZGUuc3RvcCh3aGVuKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yTm9kZVJlbmRlcmVyICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvck5vZGVSZW5kZXJlci5zdG9wID0gd2hlbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU9zY2lsbGF0b3JOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHBlcmlvZGljV2F2ZSA9IG51bGw7XG4gICAgICAgIGxldCBzdGFydCA9IG51bGw7XG4gICAgICAgIGxldCBzdG9wID0gbnVsbDtcbiAgICAgICAgY29uc3QgY3JlYXRlT3NjaWxsYXRvck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGdldE5hdGl2ZUF1ZGlvTm9kZShwcm94eSk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlT3NjaWxsYXRvck5vZGUgd2FzIG5vdCBjb25zdHJ1Y3RlZCBvbiB0aGUgc2FtZSBPZmZsaW5lQXVkaW9Db250ZXh0IGl0IG5lZWRzIHRvIGJlIGNyZWF0ZWQgYWdhaW4uXG4gICAgICAgICAgICBjb25zdCBuYXRpdmVPc2NpbGxhdG9yTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5jaGFubmVsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlT3NjaWxsYXRvck5vZGUuY2hhbm5lbEludGVycHJldGF0aW9uLFxuICAgICAgICAgICAgICAgICAgICBkZXR1bmU6IG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZnJlcXVlbmN5OiBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZTogcGVyaW9kaWNXYXZlID09PSBudWxsID8gdW5kZWZpbmVkIDogcGVyaW9kaWNXYXZlLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBuYXRpdmVPc2NpbGxhdG9yTm9kZS50eXBlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZSA9IGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIGlmIChzdGFydCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBuYXRpdmVPc2NpbGxhdG9yTm9kZS5zdGFydChzdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzdG9wICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLnN0b3Aoc3RvcCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVPc2NpbGxhdG9yTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlT3NjaWxsYXRvck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5mcmVxdWVuY3ksIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmZyZXF1ZW5jeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBjb25uZWN0QXVkaW9QYXJhbShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5kZXR1bmUsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkuZnJlcXVlbmN5LCBuYXRpdmVPc2NpbGxhdG9yTm9kZS5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZU9zY2lsbGF0b3JOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiBuYXRpdmVPc2NpbGxhdG9yTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNldCBwZXJpb2RpY1dhdmUodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBwZXJpb2RpY1dhdmUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQgc3RhcnQodmFsdWUpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldCBzdG9wKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgc3RvcCA9IHZhbHVlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUgPSByZW5kZXJlZE5hdGl2ZU9zY2lsbGF0b3JOb2Rlcy5nZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlbmRlcmVkTmF0aXZlT3NjaWxsYXRvck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlT3NjaWxsYXRvck5vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9b3NjaWxsYXRvci1ub2RlLXJlbmRlcmVyLWZhY3RvcnkuanMubWFwIiwiaW1wb3J0IHsgTU9TVF9ORUdBVElWRV9TSU5HTEVfRkxPQVQsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FUIH0gZnJvbSAnLi4vY29uc3RhbnRzJztcbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBjaGFubmVsQ291bnQ6IDIsXG4gICAgY2hhbm5lbENvdW50TW9kZTogJ2NsYW1wZWQtbWF4JyxcbiAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdzcGVha2VycycsXG4gICAgY29uZUlubmVyQW5nbGU6IDM2MCxcbiAgICBjb25lT3V0ZXJBbmdsZTogMzYwLFxuICAgIGNvbmVPdXRlckdhaW46IDAsXG4gICAgZGlzdGFuY2VNb2RlbDogJ2ludmVyc2UnLFxuICAgIG1heERpc3RhbmNlOiAxMDAwMCxcbiAgICBvcmllbnRhdGlvblg6IDEsXG4gICAgb3JpZW50YXRpb25ZOiAwLFxuICAgIG9yaWVudGF0aW9uWjogMCxcbiAgICBwYW5uaW5nTW9kZWw6ICdlcXVhbHBvd2VyJyxcbiAgICBwb3NpdGlvblg6IDAsXG4gICAgcG9zaXRpb25ZOiAwLFxuICAgIHBvc2l0aW9uWjogMCxcbiAgICByZWZEaXN0YW5jZTogMSxcbiAgICByb2xsb2ZmRmFjdG9yOiAxXG59O1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVBhbm5lck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFBhbm5lck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHBhbm5lck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZVBhbm5lck5vZGUsIHBhbm5lck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlID0gbmF0aXZlUGFubmVyTm9kZTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNzQ6IFNhZmFyaSBkb2VzIG5vdCBleHBvcnQgdGhlIGNvcnJlY3QgdmFsdWVzIGZvciBtYXhWYWx1ZSBhbmQgbWluVmFsdWUuXG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblggPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblgsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblkgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblksIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9vcmllbnRhdGlvblogPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblosIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblggPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblgsIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblkgPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblksIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICB0aGlzLl9wb3NpdGlvblogPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblosIE1PU1RfUE9TSVRJVkVfU0lOR0xFX0ZMT0FULCBNT1NUX05FR0FUSVZFX1NJTkdMRV9GTE9BVCk7XG4gICAgICAgICAgICAvLyBAdG9kbyBEZXRlcm1pbmUgYSBtZWFuaW5nZnVsIHRhaWwtdGltZSBpbnN0ZWFkIG9mIGp1c3QgdXNpbmcgb25lIHNlY29uZC5cbiAgICAgICAgICAgIHNldEF1ZGlvTm9kZVRhaWxUaW1lKHRoaXMsIDEpO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lSW5uZXJBbmdsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVJbm5lckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lSW5uZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lSW5uZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lT3V0ZXJBbmdsZSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmNvbmVPdXRlckFuZ2xlO1xuICAgICAgICB9XG4gICAgICAgIHNldCBjb25lT3V0ZXJBbmdsZSh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJBbmdsZSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGdldCBjb25lT3V0ZXJHYWluKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyR2FpbjtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY29uZU91dGVyR2Fpbih2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGRpc3RhbmNlTW9kZWwoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5kaXN0YW5jZU1vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLmRpc3RhbmNlTW9kZWwgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgbWF4RGlzdGFuY2UoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgbWF4RGlzdGFuY2UodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUubWF4RGlzdGFuY2UgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25YKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWDtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25ZKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWTtcbiAgICAgICAgfVxuICAgICAgICBnZXQgb3JpZW50YXRpb25aKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29yaWVudGF0aW9uWjtcbiAgICAgICAgfVxuICAgICAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsO1xuICAgICAgICB9XG4gICAgICAgIHNldCBwYW5uaW5nTW9kZWwodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWCgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblg7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWSgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHBvc2l0aW9uWigpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wb3NpdGlvblo7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVBhbm5lck5vZGUucmVmRGlzdGFuY2U7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IHJlZkRpc3RhbmNlKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IHJvbGxvZmZGYWN0b3IoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbmF0aXZlUGFubmVyTm9kZS5yb2xsb2ZmRmFjdG9yO1xuICAgICAgICB9XG4gICAgICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLl9uYXRpdmVQYW5uZXJOb2RlLnJvbGxvZmZGYWN0b3IgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGFubmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgY3JlYXRlTmF0aXZlUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGVzID0gbmV3IFdlYWtNYXAoKTtcbiAgICAgICAgbGV0IHJlbmRlcmVkQnVmZmVyUHJvbWlzZSA9IG51bGw7XG4gICAgICAgIGNvbnN0IGNyZWF0ZUF1ZGlvTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZUdhaW5Ob2RlID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBuYXRpdmVQYW5uZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgY2hhbm5lbENvdW50OiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVQYW5uZXJOb2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgY29uZUlubmVyQW5nbGU6IG5hdGl2ZVBhbm5lck5vZGUuY29uZUlubmVyQW5nbGUsXG4gICAgICAgICAgICAgICAgY29uZU91dGVyQW5nbGU6IG5hdGl2ZVBhbm5lck5vZGUuY29uZU91dGVyQW5nbGUsXG4gICAgICAgICAgICAgICAgY29uZU91dGVyR2FpbjogbmF0aXZlUGFubmVyTm9kZS5jb25lT3V0ZXJHYWluLFxuICAgICAgICAgICAgICAgIGRpc3RhbmNlTW9kZWw6IG5hdGl2ZVBhbm5lck5vZGUuZGlzdGFuY2VNb2RlbCxcbiAgICAgICAgICAgICAgICBtYXhEaXN0YW5jZTogbmF0aXZlUGFubmVyTm9kZS5tYXhEaXN0YW5jZSxcbiAgICAgICAgICAgICAgICBwYW5uaW5nTW9kZWw6IG5hdGl2ZVBhbm5lck5vZGUucGFubmluZ01vZGVsLFxuICAgICAgICAgICAgICAgIHJlZkRpc3RhbmNlOiBuYXRpdmVQYW5uZXJOb2RlLnJlZkRpc3RhbmNlLFxuICAgICAgICAgICAgICAgIHJvbGxvZmZGYWN0b3I6IG5hdGl2ZVBhbm5lck5vZGUucm9sbG9mZkZhY3RvclxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVQYW5uZXJOb2RlIHdhcyBub3QgY29uc3RydWN0ZWQgb24gdGhlIHNhbWUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpdCBuZWVkcyB0byBiZSBjcmVhdGVkIGFnYWluLlxuICAgICAgICAgICAgY29uc3QgbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQgPSBpc093bmVkQnlDb250ZXh0KG5hdGl2ZVBhbm5lck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgLy8gQnVnICMxMjQ6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IG1vZGlmeWluZyB0aGUgb3JpZW50YXRpb24gYW5kIHRoZSBwb3NpdGlvbiB3aXRoIEF1ZGlvUGFyYW1zLlxuICAgICAgICAgICAgaWYgKCdidWZmZXJTaXplJyBpbiBuYXRpdmVQYW5uZXJOb2RlKSB7XG4gICAgICAgICAgICAgICAgbmF0aXZlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghbmF0aXZlUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICAuLi5jb21tb25OYXRpdmVQYW5uZXJOb2RlT3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWi52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWC52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWS52YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWi52YWx1ZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlUGFubmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgb3B0aW9ucyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuc2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUdhaW5Ob2RlID09PSBudWxsID8gbmF0aXZlUGFubmVyTm9kZSA6IG5hdGl2ZUdhaW5Ob2RlKTtcbiAgICAgICAgICAgIGlmIChuYXRpdmVHYWluTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZEJ1ZmZlclByb21pc2UgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIHRoZSBuYXRpdmUgT2ZmbGluZUF1ZGlvQ29udGV4dCBjb25zdHJ1Y3Rvci4nKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCA9IG5ldyBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IoNiwgXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1ZyAjMTc6IFNhZmFyaSBkb2VzIG5vdCB5ZXQgZXhwb3NlIHRoZSBsZW5ndGguXG4gICAgICAgICAgICAgICAgICAgIHByb3h5LmNvbnRleHQubGVuZ3RoLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJbnB1dHM6IDZcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLmNvbm5lY3QocGFydGlhbE9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJlZEJ1ZmZlclByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlcyA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5vcmllbnRhdGlvblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkub3JpZW50YXRpb25ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5Lm9yaWVudGF0aW9uWixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm94eS5wb3NpdGlvblgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJveHkucG9zaXRpb25ZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3h5LnBvc2l0aW9uWlxuICAgICAgICAgICAgICAgICAgICAgICAgXS5tYXAoYXN5bmMgKGF1ZGlvUGFyYW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnZGlzY3JldGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQ6IGluZGV4ID09PSAwID8gMSA6IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKHBhcnRpYWxPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGUub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmVDb25zdGFudFNvdXJjZU5vZGVzW2ldLmNvbm5lY3QobmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIDAsIGkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdGl2ZUNvbnN0YW50U291cmNlTm9kZXNbaV0uc3RhcnQoMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChwYXJ0aWFsT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkQnVmZmVyID0gYXdhaXQgcmVuZGVyZWRCdWZmZXJQcm9taXNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0R2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIGlucHV0R2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhcyA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVuZGVyZWRCdWZmZXIubnVtYmVyT2ZDaGFubmVsczsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxEYXRhcy5wdXNoKHJlbmRlcmVkQnVmZmVyLmdldENoYW5uZWxEYXRhKGkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGxhc3RPcmllbnRhdGlvbiA9IFtjaGFubmVsRGF0YXNbMF1bMF0sIGNoYW5uZWxEYXRhc1sxXVswXSwgY2hhbm5lbERhdGFzWzJdWzBdXTtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdFBvc2l0aW9uID0gW2NoYW5uZWxEYXRhc1szXVswXSwgY2hhbm5lbERhdGFzWzRdWzBdLCBjaGFubmVsRGF0YXNbNV1bMF1dO1xuICAgICAgICAgICAgICAgIGxldCBnYXRlR2Fpbk5vZGUgPSBjcmVhdGVOYXRpdmVHYWluTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7IC4uLmNvbW1vbkF1ZGlvTm9kZU9wdGlvbnMsIGdhaW46IDEgfSk7XG4gICAgICAgICAgICAgICAgbGV0IHBhcnRpYWxQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmNvbW1vbk5hdGl2ZVBhbm5lck5vZGVPcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICBvcmllbnRhdGlvblg6IGxhc3RPcmllbnRhdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBsYXN0T3JpZW50YXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIG9yaWVudGF0aW9uWjogbGFzdE9yaWVudGF0aW9uWzJdLFxuICAgICAgICAgICAgICAgICAgICBwb3NpdGlvblg6IGxhc3RQb3NpdGlvblswXSxcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBsYXN0UG9zaXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uWjogbGFzdFBvc2l0aW9uWzJdXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGdhdGVHYWluTm9kZSkuY29ubmVjdChwYXJ0aWFsUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxMjg7IGkgPCByZW5kZXJlZEJ1ZmZlci5sZW5ndGg7IGkgKz0gMTI4KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG9yaWVudGF0aW9uID0gW2NoYW5uZWxEYXRhc1swXVtpXSwgY2hhbm5lbERhdGFzWzFdW2ldLCBjaGFubmVsRGF0YXNbMl1baV1dO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwb3NpdG9uID0gW2NoYW5uZWxEYXRhc1szXVtpXSwgY2hhbm5lbERhdGFzWzRdW2ldLCBjaGFubmVsRGF0YXNbNV1baV1dO1xuICAgICAgICAgICAgICAgICAgICBpZiAob3JpZW50YXRpb24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdE9yaWVudGF0aW9uW2luZGV4XSkgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0b24uc29tZSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSAhPT0gbGFzdFBvc2l0aW9uW2luZGV4XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RPcmllbnRhdGlvbiA9IG9yaWVudGF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFBvc2l0aW9uID0gcG9zaXRvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gaSAvIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIGN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdhdGVHYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHsgLi4uY29tbW9uQXVkaW9Ob2RlT3B0aW9ucywgZ2FpbjogMCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpYWxQYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlUGFubmVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uY29tbW9uTmF0aXZlUGFubmVyTm9kZU9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25YOiBsYXN0T3JpZW50YXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25ZOiBsYXN0T3JpZW50YXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZW50YXRpb25aOiBsYXN0T3JpZW50YXRpb25bMl0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25YOiBsYXN0UG9zaXRpb25bMF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25ZOiBsYXN0UG9zaXRpb25bMV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb25aOiBsYXN0UG9zaXRpb25bMl1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2F0ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMSwgY3VycmVudFRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5wdXRHYWluTm9kZS5jb25uZWN0KGdhdGVHYWluTm9kZSkuY29ubmVjdChwYXJ0aWFsUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGlhbFBhbm5lck5vZGUuY29ubmVjdChuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZUdhaW5Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuYXRpdmVQYW5uZXJOb2RlSXNPd25lZEJ5Q29udGV4dCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5vcmllbnRhdGlvblksIG5hdGl2ZVBhbm5lck5vZGUub3JpZW50YXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5Lm9yaWVudGF0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5vcmllbnRhdGlvblopO1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlckF1dG9tYXRpb24obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wb3NpdGlvblksIG5hdGl2ZVBhbm5lck5vZGUucG9zaXRpb25ZKTtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJBdXRvbWF0aW9uKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBvc2l0aW9uWiwgbmF0aXZlUGFubmVyTm9kZS5wb3NpdGlvblopO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkub3JpZW50YXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLm9yaWVudGF0aW9uWik7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25YLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25ZLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWSk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY29ubmVjdEF1ZGlvUGFyYW0obmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcHJveHkucG9zaXRpb25aLCBuYXRpdmVQYW5uZXJOb2RlLnBvc2l0aW9uWik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVQYW5uZXJOb2RlKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVQYW5uZXJOb2RlLmlucHV0c1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlUGFubmVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlUGFubmVyTm9kZTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbmRlcihwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlR2Fpbk5vZGVPck5hdGl2ZVBhbm5lck5vZGUgPSByZW5kZXJlZE5hdGl2ZUF1ZGlvTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZUdhaW5Ob2RlT3JOYXRpdmVQYW5uZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wYW5uZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5LmpzLm1hcCIsImNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICBkaXNhYmxlTm9ybWFsaXphdGlvbjogZmFsc2Vcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgPSAoY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlLCBnZXROYXRpdmVDb250ZXh0LCBwZXJpb2RpY1dhdmVTdG9yZSwgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFBlcmlvZGljV2F2ZSB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHNhbml0aXplUGVyaW9kaWNXYXZlT3B0aW9ucyh7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9KTtcbiAgICAgICAgICAgIGNvbnN0IHBlcmlvZGljV2F2ZSA9IGNyZWF0ZU5hdGl2ZVBlcmlvZGljV2F2ZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIHBlcmlvZGljV2F2ZVN0b3JlLmFkZChwZXJpb2RpY1dhdmUpO1xuICAgICAgICAgICAgLy8gVGhpcyBkb2VzIHZpb2xhdGUgYWxsIGdvb2QgcHJhdGljZXMgYnV0IGl0IGlzIHVzZWQgaGVyZSB0byBzaW1wbGlmeSB0aGUgaGFuZGxpbmcgb2YgcGVyaW9kaWMgd2F2ZXMuXG4gICAgICAgICAgICByZXR1cm4gcGVyaW9kaWNXYXZlO1xuICAgICAgICB9XG4gICAgICAgIHN0YXRpYyBbU3ltYm9sLmhhc0luc3RhbmNlXShpbnN0YW5jZSkge1xuICAgICAgICAgICAgcmV0dXJuICgoaW5zdGFuY2UgIT09IG51bGwgJiYgdHlwZW9mIGluc3RhbmNlID09PSAnb2JqZWN0JyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpID09PSBQZXJpb2RpY1dhdmUucHJvdG90eXBlKSB8fFxuICAgICAgICAgICAgICAgIHBlcmlvZGljV2F2ZVN0b3JlLmhhcyhpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wZXJpb2RpYy13YXZlLWNvbnN0cnVjdG9yLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJBdXRvbWF0aW9uID0gKGdldEF1ZGlvUGFyYW1SZW5kZXJlciwgcmVuZGVySW5wdXRzT2ZBdWRpb1BhcmFtKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBhdWRpb1BhcmFtLCBuYXRpdmVBdWRpb1BhcmFtKSA9PiB7XG4gICAgICAgIGNvbnN0IGF1ZGlvUGFyYW1SZW5kZXJlciA9IGdldEF1ZGlvUGFyYW1SZW5kZXJlcihhdWRpb1BhcmFtKTtcbiAgICAgICAgYXVkaW9QYXJhbVJlbmRlcmVyLnJlcGxheShuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICAgICAgcmV0dXJuIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbShhdWRpb1BhcmFtLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1BhcmFtKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1hdXRvbWF0aW9uLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSA9IChnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGlzUGFydE9mQUN5Y2xlKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChhdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvTm9kZSkgPT4ge1xuICAgICAgICBjb25zdCBhdWRpb05vZGVDb25uZWN0aW9ucyA9IGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zKGF1ZGlvTm9kZSk7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKGF1ZGlvTm9kZUNvbm5lY3Rpb25zLmFjdGl2ZUlucHV0c1xuICAgICAgICAgICAgLm1hcCgoY29ubmVjdGlvbnMsIGlucHV0KSA9PiBBcnJheS5mcm9tKGNvbm5lY3Rpb25zKS5tYXAoYXN5bmMgKFtzb3VyY2UsIG91dHB1dF0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF1ZGlvTm9kZVJlbmRlcmVyID0gZ2V0QXVkaW9Ob2RlUmVuZGVyZXIoc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlID0gYXdhaXQgYXVkaW9Ob2RlUmVuZGVyZXIucmVuZGVyKHNvdXJjZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IGF1ZGlvTm9kZS5jb250ZXh0LmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgaWYgKCFpc1BhcnRPZkFDeWNsZShzb3VyY2UpICYmIChhdWRpb05vZGUgIT09IGRlc3RpbmF0aW9uIHx8ICFpc1BhcnRPZkFDeWNsZShhdWRpb05vZGUpKSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9Ob2RlLCBvdXRwdXQsIGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpXG4gICAgICAgICAgICAucmVkdWNlKChhbGxSZW5kZXJpbmdQcm9taXNlcywgcmVuZGVyaW5nUHJvbWlzZXMpID0+IFsuLi5hbGxSZW5kZXJpbmdQcm9taXNlcywgLi4ucmVuZGVyaW5nUHJvbWlzZXNdLCBbXSkpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvUGFyYW0gPSAoZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucywgaXNQYXJ0T2ZBQ3ljbGUpID0+IHtcbiAgICByZXR1cm4gYXN5bmMgKGF1ZGlvUGFyYW0sIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvUGFyYW0pID0+IHtcbiAgICAgICAgY29uc3QgYXVkaW9QYXJhbUNvbm5lY3Rpb25zID0gZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zKGF1ZGlvUGFyYW0pO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChBcnJheS5mcm9tKGF1ZGlvUGFyYW1Db25uZWN0aW9ucy5hY3RpdmVJbnB1dHMpLm1hcChhc3luYyAoW3NvdXJjZSwgb3V0cHV0XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXVkaW9Ob2RlUmVuZGVyZXIgPSBnZXRBdWRpb05vZGVSZW5kZXJlcihzb3VyY2UpO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVBdWRpb05vZGUgPSBhd2FpdCBhdWRpb05vZGVSZW5kZXJlci5yZW5kZXIoc291cmNlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghaXNQYXJ0T2ZBQ3ljbGUoc291cmNlKSkge1xuICAgICAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlQXVkaW9Ob2RlLmNvbm5lY3QobmF0aXZlQXVkaW9QYXJhbSwgb3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cmVuZGVyLWlucHV0cy1vZi1hdWRpby1wYXJhbS5qcy5tYXAiLCJpbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuLi9oZWxwZXJzL3Rlc3QtcHJvbWlzZS1zdXBwb3J0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIHRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjMjE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IHByb21pc2VzIHlldC5cbiAgICAgICAgaWYgKGNhY2hlVGVzdFJlc3VsdCh0ZXN0UHJvbWlzZVN1cHBvcnQsICgpID0+IHRlc3RQcm9taXNlU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU4OiBDaHJvbWUgYW5kIEVkZ2UgZG8gbm90IGFkdmFuY2UgY3VycmVudFRpbWUgaWYgaXQgaXMgbm90IGFjY2Vzc2VkIHdoaWxlIHJlbmRlcmluZyB0aGUgYXVkaW8uXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlVGVzdFJlc3VsdCh0ZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCwgdGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQpKS50aGVuKChpc09mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnRlZCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghaXNPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2NyaXB0UHJvY2Vzc29yTm9kZSA9IGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgNTEyLCAwLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0UHJvY2Vzc29yTm9kZS5vbmF1ZGlvcHJvY2VzcyA9IG51bGw7IC8vIHRzbGludDpkaXNhYmxlLWxpbmU6ZGVwcmVjYXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdFByb2Nlc3Nvck5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLm9uYXVkaW9wcm9jZXNzID0gKCkgPT4gbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5jdXJyZW50VGltZTsgLy8gdHNsaW50OmRpc2FibGUtbGluZTpkZXByZWNhdGlvblxuICAgICAgICAgICAgICAgICAgICBzY3JpcHRQcm9jZXNzb3JOb2RlLmNvbm5lY3QobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LnN0YXJ0UmVuZGVyaW5nKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjNDg6IFNhZmFyaSBkb2VzIG5vdCByZW5kZXIgYW4gT2ZmbGluZUF1ZGlvQ29udGV4dCB3aXRob3V0IGFueSBjb25uZWN0ZWQgbm9kZS5cbiAgICAgICAgICAgIGNvbnN0IGdhaW5Ob2RlID0gY3JlYXRlTmF0aXZlR2Fpbk5vZGUobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwge1xuICAgICAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiAnZXhwbGljaXQnLFxuICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ2Rpc2NyZXRlJyxcbiAgICAgICAgICAgICAgICBnYWluOiAwXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQub25jb21wbGV0ZSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGV2ZW50LnJlbmRlcmVkQnVmZmVyKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBnYWluTm9kZS5jb25uZWN0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXJlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0LmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVTZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzID0gKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSkgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKSA9PiB7XG4gICAgICAgIGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZS5zZXQobmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZSwgYWN0aXZlSW5wdXRzKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cy5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUgPSAoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSkgPT4ge1xuICAgIHJldHVybiAoYXVkaW9Ob2RlLCB0YWlsVGltZSkgPT4gYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZS5zZXQoYXVkaW9Ob2RlLCB0YWlsVGltZSk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lLmpzLm1hcCIsImltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kIH0gZnJvbSAnLi4vaGVscGVycy93cmFwLWF1ZGlvLWJ1ZmZlci1nZXQtY2hhbm5lbC1kYXRhLW1ldGhvZCc7XG5leHBvcnQgY29uc3QgY3JlYXRlU3RhcnRSZW5kZXJpbmcgPSAoYXVkaW9CdWZmZXJTdG9yZSwgY2FjaGVUZXN0UmVzdWx0LCBnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzLCByZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB0ZXN0QXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpID0+IHtcbiAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiBnZXRBdWRpb05vZGVSZW5kZXJlcihkZXN0aW5hdGlvbilcbiAgICAgICAgLnJlbmRlcihkZXN0aW5hdGlvbiwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dClcbiAgICAgICAgLypcbiAgICAgICAgICogQnVnICM4NiAmICM4NzogSW52b2tpbmcgdGhlIHJlbmRlcmVyIG9mIGFuIEF1ZGlvV29ya2xldE5vZGUgbWlnaHQgYmUgbmVjZXNzYXJ5IGlmIGl0IGhhcyBubyBkaXJlY3Qgb3IgaW5kaXJlY3QgY29ubmVjdGlvbiB0byB0aGVcbiAgICAgICAgICogZGVzdGluYXRpb24uXG4gICAgICAgICAqL1xuICAgICAgICAudGhlbigoKSA9PiBQcm9taXNlLmFsbChBcnJheS5mcm9tKGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcyhuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSkubWFwKChhdWRpb1dvcmtsZXROb2RlKSA9PiBnZXRBdWRpb05vZGVSZW5kZXJlcihhdWRpb1dvcmtsZXROb2RlKS5yZW5kZXIoYXVkaW9Xb3JrbGV0Tm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkpKSlcbiAgICAgICAgLnRoZW4oKCkgPT4gcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSlcbiAgICAgICAgLnRoZW4oKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIC8vIEJ1ZyAjNTogU2FmYXJpIGRvZXMgbm90IHN1cHBvcnQgY29weUZyb21DaGFubmVsKCkgYW5kIGNvcHlUb0NoYW5uZWwoKS5cbiAgICAgICAgLy8gQnVnICMxMDA6IFNhZmFyaSBkb2VzIHRocm93IGEgd3JvbmcgZXJyb3Igd2hlbiBjYWxsaW5nIGdldENoYW5uZWxEYXRhKCkgd2l0aCBhbiBvdXQtb2YtYm91bmRzIHZhbHVlLlxuICAgICAgICBpZiAodHlwZW9mIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckdldENoYW5uZWxEYXRhTWV0aG9kKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU3OiBGaXJlZm94IGRvZXMgbm90IGFsbG93IHRoZSBidWZmZXJPZmZzZXQgdG8gYmUgb3V0LW9mLWJvdW5kcy5cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghY2FjaGVUZXN0UmVzdWx0KHRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzU3VwcG9ydCwgKCkgPT4gdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0KGF1ZGlvQnVmZmVyKSkpIHtcbiAgICAgICAgICAgIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKGF1ZGlvQnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICBhdWRpb0J1ZmZlclN0b3JlLmFkZChhdWRpb0J1ZmZlcik7XG4gICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICB9KTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGFydC1yZW5kZXJpbmcuanMubWFwIiwiY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGNoYW5uZWxDb3VudDogMixcbiAgICAvKlxuICAgICAqIEJ1ZyAjMTA1OiBUaGUgY2hhbm5lbENvdW50TW9kZSBzaG91bGQgYmUgJ2NsYW1wZWQtbWF4JyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgYnV0IGlzIHNldCB0byAnZXhwbGljaXQnIHRvIGFjaGlldmUgY29uc2lzdGVudFxuICAgICAqIGJlaGF2aW9yLlxuICAgICAqL1xuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgY2hhbm5lbEludGVycHJldGF0aW9uOiAnc3BlYWtlcnMnLFxuICAgIHBhbjogMFxufTtcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgPSAoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFN0ZXJlb1Bhbm5lck5vZGUgZXh0ZW5kcyBhdWRpb05vZGVDb25zdHJ1Y3RvciB7XG4gICAgICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUNvbnRleHQgPSBnZXROYXRpdmVDb250ZXh0KGNvbnRleHQpO1xuICAgICAgICAgICAgY29uc3QgbWVyZ2VkT3B0aW9ucyA9IHsgLi4uREVGQVVMVF9PUFRJT05TLCAuLi5vcHRpb25zIH07XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciA9IChpc09mZmxpbmUgPyBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXIoKSA6IG51bGwpO1xuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgZmFsc2UsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIHN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlcik7XG4gICAgICAgICAgICB0aGlzLl9wYW4gPSBjcmVhdGVBdWRpb1BhcmFtKHRoaXMsIGlzT2ZmbGluZSwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICB9XG4gICAgICAgIGdldCBwYW4oKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFuO1xuICAgICAgICB9XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUtY29uc3RydWN0b3IuanMubWFwIiwiaW1wb3J0IHsgaXNOYXRpdmVBdWRpb05vZGVGYWtlciB9IGZyb20gJy4uL2d1YXJkcy9uYXRpdmUtYXVkaW8tbm9kZS1mYWtlcic7XG5pbXBvcnQgeyBpc093bmVkQnlDb250ZXh0IH0gZnJvbSAnLi4vaGVscGVycy9pcy1vd25lZC1ieS1jb250ZXh0JztcbmV4cG9ydCBjb25zdCBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlcyA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIGNvbnN0IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGUgPSBhc3luYyAocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgKiBJZiB0aGUgaW5pdGlhbGx5IHVzZWQgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZFxuICAgICAgICAgICAgICogYWdhaW4uXG4gICAgICAgICAgICAgKi9cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0ID0gaXNPd25lZEJ5Q29udGV4dChuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIGlmICghbmF0aXZlU3RlcmVvUGFubmVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUuY2hhbm5lbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnRNb2RlOiBuYXRpdmVTdGVyZW9QYW5uZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIHBhbjogbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4udmFsdWVcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2Rlcy5zZXQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoIW5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVJc093bmVkQnlDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVyQXV0b21hdGlvbihuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBwcm94eS5wYW4sIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUucGFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IGNvbm5lY3RBdWRpb1BhcmFtKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHByb3h5LnBhbiwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5wYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzTmF0aXZlQXVkaW9Ob2RlRmFrZXIobmF0aXZlU3RlcmVvUGFubmVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlU3RlcmVvUGFubmVyTm9kZS5pbnB1dHNbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUgPSByZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVzLmdldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocmVuZGVyZWROYXRpdmVTdGVyZW9QYW5uZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlU3RlcmVvUGFubmVyTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCIvLyBCdWcgIzMzOiBTYWZhcmkgZXhwb3NlcyBhbiBBdWRpb0J1ZmZlciBidXQgaXQgY2FuJ3QgYmUgdXNlZCBhcyBhIGNvbnN0cnVjdG9yLlxuZXhwb3J0IGNvbnN0IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvbnN0cnVjdG9yU3VwcG9ydCA9IChuYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbmV3IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IoeyBsZW5ndGg6IDEsIHNhbXBsZVJhdGU6IDQ0MTAwIH0pOyAvLyB0c2xpbnQ6ZGlzYWJsZS1saW5lOm5vLXVudXNlZC1leHByZXNzaW9uXG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2gge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItY29uc3RydWN0b3Itc3VwcG9ydC5qcy5tYXAiLCIvLyBCdWcgIzE3OTogRmlyZWZveCBkb2VzIG5vdCBhbGxvdyB0byB0cmFuc2ZlciBhbnkgYnVmZmVyIHdoaWNoIGhhcyBiZWVuIHBhc3NlZCB0byB0aGUgcHJvY2VzcygpIG1ldGhvZCBhcyBhbiBhcmd1bWVudC5cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0ID0gKG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gQnVnICM2MTogSWYgdGhlcmUgaXMgbm8gbmF0aXZlIEF1ZGlvV29ya2xldE5vZGUgaXQgZ2V0cyBmYWtlZCBhbmQgdGhlcmVmb3JlIGl0IGlzIG5vIHByb2JsZW0gaWYgdGhlIGl0IGRvZXNuJ3QgZXhpc3QuXG4gICAgICAgIGlmIChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoWydjbGFzcyBBIGV4dGVuZHMgQXVkaW9Xb3JrbGV0UHJvY2Vzc29ye3Byb2Nlc3MoaSl7dGhpcy5wb3J0LnBvc3RNZXNzYWdlKGksW2lbMF1bMF0uYnVmZmVyXSl9fXJlZ2lzdGVyUHJvY2Vzc29yKFwiYVwiLEEpJ10sIHtcbiAgICAgICAgICAgIHR5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04J1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gQnVnICMxNDE6IFNhZmFyaSBkb2VzIG5vdCBzdXBwb3J0IGNyZWF0aW5nIGFuIE9mZmxpbmVBdWRpb0NvbnRleHQgd2l0aCBsZXNzIHRoYW4gNDQxMDAgSHouXG4gICAgICAgIGNvbnN0IG9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEyOCwgNDQxMDApO1xuICAgICAgICBjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBsZXQgaXNFbWl0dGluZ01lc3NhZ2VFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgbGV0IGlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cyA9IGZhbHNlO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgb2ZmbGluZUF1ZGlvQ29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCk7XG4gICAgICAgICAgICBjb25zdCBhdWRpb1dvcmtsZXROb2RlID0gbmV3IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvcihvZmZsaW5lQXVkaW9Db250ZXh0LCAnYScsIHsgbnVtYmVyT2ZPdXRwdXRzOiAwIH0pO1xuICAgICAgICAgICAgY29uc3Qgb3NjaWxsYXRvciA9IG9mZmxpbmVBdWRpb0NvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICAgICAgYXVkaW9Xb3JrbGV0Tm9kZS5wb3J0Lm9ubWVzc2FnZSA9ICgpID0+IChpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyA9IHRydWUpO1xuICAgICAgICAgICAgYXVkaW9Xb3JrbGV0Tm9kZS5vbnByb2Nlc3NvcmVycm9yID0gKCkgPT4gKGlzRW1pdHRpbmdQcm9jZXNzb3JFcnJvckV2ZW50cyA9IHRydWUpO1xuICAgICAgICAgICAgb3NjaWxsYXRvci5jb25uZWN0KGF1ZGlvV29ya2xldE5vZGUpO1xuICAgICAgICAgICAgb3NjaWxsYXRvci5zdGFydCgwKTtcbiAgICAgICAgICAgIGF3YWl0IG9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAvLyBJZ25vcmUgZXJyb3JzLlxuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpc0VtaXR0aW5nTWVzc2FnZUV2ZW50cyAmJiAhaXNFbWl0dGluZ1Byb2Nlc3NvckVycm9yRXZlbnRzO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlVGVzdE9mZmxpbmVBdWRpb0NvbnRleHRDdXJyZW50VGltZVN1cHBvcnQgPSAoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcikgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIGlmIChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBuZXcgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgLy8gQnVnICM0ODogU2FmYXJpIGRvZXMgbm90IHJlbmRlciBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IHdpdGhvdXQgYW55IGNvbm5lY3RlZCBub2RlLlxuICAgICAgICBjb25zdCBnYWluTm9kZSA9IGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHtcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6ICdleHBsaWNpdCcsXG4gICAgICAgICAgICBjaGFubmVsSW50ZXJwcmV0YXRpb246ICdkaXNjcmV0ZScsXG4gICAgICAgICAgICBnYWluOiAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzIxOiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBwcm9taXNlcyB5ZXQuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dC5vbmNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGdhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuY3VycmVudFRpbWUgIT09IDApO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQuc3RhcnRSZW5kZXJpbmcoKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LW9mZmxpbmUtYXVkaW8tY29udGV4dC1jdXJyZW50LXRpbWUtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlVW5rbm93bkVycm9yID0gKCkgPT4gbmV3IERPTUV4Y2VwdGlvbignJywgJ1Vua25vd25FcnJvcicpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dW5rbm93bi1lcnJvci5qcy5tYXAiLCJjb25zdCBERUZBVUxUX09QVElPTlMgPSB7XG4gICAgY2hhbm5lbENvdW50OiAyLFxuICAgIGNoYW5uZWxDb3VudE1vZGU6ICdtYXgnLFxuICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogJ3NwZWFrZXJzJyxcbiAgICBjdXJ2ZTogbnVsbCxcbiAgICBvdmVyc2FtcGxlOiAnbm9uZSdcbn07XG5leHBvcnQgY29uc3QgY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciA9IChhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzIFdhdmVTaGFwZXJOb2RlIGV4dGVuZHMgYXVkaW9Ob2RlQ29uc3RydWN0b3Ige1xuICAgICAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBuYXRpdmVDb250ZXh0ID0gZ2V0TmF0aXZlQ29udGV4dChjb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IG1lcmdlZE9wdGlvbnMgPSB7IC4uLkRFRkFVTFRfT1BUSU9OUywgLi4ub3B0aW9ucyB9O1xuICAgICAgICAgICAgY29uc3QgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVDb250ZXh0LCBtZXJnZWRPcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IGlzT2ZmbGluZSA9IGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dChuYXRpdmVDb250ZXh0KTtcbiAgICAgICAgICAgIGNvbnN0IHdhdmVTaGFwZXJOb2RlUmVuZGVyZXIgPSAoaXNPZmZsaW5lID8gY3JlYXRlV2F2ZVNoYXBlck5vZGVSZW5kZXJlcigpIDogbnVsbCk7XG4gICAgICAgICAgICAvLyBAdG9kbyBBZGQgYSBtZWNoYW5pc20gdG8gb25seSBzd2l0Y2ggYSBXYXZlU2hhcGVyTm9kZSB0byBhY3RpdmUgd2hpbGUgaXQgaXMgY29ubmVjdGVkLlxuICAgICAgICAgICAgc3VwZXIoY29udGV4dCwgdHJ1ZSwgbmF0aXZlV2F2ZVNoYXBlck5vZGUsIHdhdmVTaGFwZXJOb2RlUmVuZGVyZXIpO1xuICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBuYXRpdmVXYXZlU2hhcGVyTm9kZTtcbiAgICAgICAgICAgIC8vIEB0b2RvIERldGVybWluZSBhIG1lYW5pbmdmdWwgdGFpbC10aW1lIGluc3RlYWQgb2YganVzdCB1c2luZyBvbmUgc2Vjb25kLlxuICAgICAgICAgICAgc2V0QXVkaW9Ob2RlVGFpbFRpbWUodGhpcywgMSk7XG4gICAgICAgIH1cbiAgICAgICAgZ2V0IGN1cnZlKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZTtcbiAgICAgICAgfVxuICAgICAgICBzZXQgY3VydmUodmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTAzOiBTYWZhcmkgZG9lcyBub3QgYWxsb3cgdG8gc2V0IHRoZSBjdXJ2ZSB0byBudWxsLlxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5faXNDdXJ2ZU51bGxpZmllZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmF0aXZlV2F2ZVNoYXBlck5vZGUuY3VydmUgPSBuZXcgRmxvYXQzMkFycmF5KFswLCAwXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBCdWcgIzEwMjogU2FmYXJpIGRvZXMgbm90IHRocm93IGFuIEludmFsaWRTdGF0ZUVycm9yIHdoZW4gdGhlIGN1cnZlIGhhcyBsZXNzIHRoYW4gdHdvIHNhbXBsZXMuXG4gICAgICAgICAgICAgICAgLy8gQnVnICMxMDQ6IENocm9tZSBhbmQgRWRnZSB3aWxsIHRocm93IGFuIEludmFsaWRBY2Nlc3NFcnJvciB3aGVuIHRoZSBjdXJ2ZSBoYXMgbGVzcyB0aGFuIHR3byBzYW1wbGVzLlxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2lzQ3VydmVOdWxsaWZpZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0aGlzLl9uYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGU7XG4gICAgICAgIH1cbiAgICAgICAgc2V0IG92ZXJzYW1wbGUodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX25hdGl2ZVdhdmVTaGFwZXJOb2RlLm92ZXJzYW1wbGUgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d2F2ZS1zaGFwZXItbm9kZS1jb25zdHJ1Y3Rvci5qcy5tYXAiLCJpbXBvcnQgeyBpc05hdGl2ZUF1ZGlvTm9kZUZha2VyIH0gZnJvbSAnLi4vZ3VhcmRzL25hdGl2ZS1hdWRpby1ub2RlLWZha2VyJztcbmltcG9ydCB7IGlzT3duZWRCeUNvbnRleHQgfSBmcm9tICcuLi9oZWxwZXJzL2lzLW93bmVkLWJ5LWNvbnRleHQnO1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5ID0gKGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKSA9PiB7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMgPSBuZXcgV2Vha01hcCgpO1xuICAgICAgICBjb25zdCBjcmVhdGVXYXZlU2hhcGVyTm9kZSA9IGFzeW5jIChwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCkgPT4ge1xuICAgICAgICAgICAgbGV0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gZ2V0TmF0aXZlQXVkaW9Ob2RlKHByb3h5KTtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbml0aWFsbHkgdXNlZCBuYXRpdmVXYXZlU2hhcGVyTm9kZSB3YXMgbm90IGNvbnN0cnVjdGVkIG9uIHRoZSBzYW1lIE9mZmxpbmVBdWRpb0NvbnRleHQgaXQgbmVlZHMgdG8gYmUgY3JlYXRlZCBhZ2Fpbi5cbiAgICAgICAgICAgIGNvbnN0IG5hdGl2ZVdhdmVTaGFwZXJOb2RlSXNPd25lZEJ5Q29udGV4dCA9IGlzT3duZWRCeUNvbnRleHQobmF0aXZlV2F2ZVNoYXBlck5vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgaWYgKCFuYXRpdmVXYXZlU2hhcGVyTm9kZUlzT3duZWRCeUNvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsQ291bnQ6IG5hdGl2ZVdhdmVTaGFwZXJOb2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbENvdW50TW9kZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEludGVycHJldGF0aW9uOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlOiBuYXRpdmVXYXZlU2hhcGVyTm9kZS5jdXJ2ZSxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcnNhbXBsZTogbmF0aXZlV2F2ZVNoYXBlck5vZGUub3ZlcnNhbXBsZVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbmF0aXZlV2F2ZVNoYXBlck5vZGUgPSBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZShuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBvcHRpb25zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlbmRlcmVkTmF0aXZlV2F2ZVNoYXBlck5vZGVzLnNldChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICBpZiAoaXNOYXRpdmVBdWRpb05vZGVGYWtlcihuYXRpdmVXYXZlU2hhcGVyTm9kZSkpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShwcm94eSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlV2F2ZVNoYXBlck5vZGUuaW5wdXRzWzBdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVXYXZlU2hhcGVyTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbmF0aXZlV2F2ZVNoYXBlck5vZGU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZW5kZXIocHJveHksIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCByZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gcmVuZGVyZWROYXRpdmVXYXZlU2hhcGVyTm9kZXMuZ2V0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZW5kZXJlZE5hdGl2ZVdhdmVTaGFwZXJOb2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZVdhdmVTaGFwZXJOb2RlKHByb3h5LCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdhdmUtc2hhcGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeS5qcy5tYXAiLCJleHBvcnQgY29uc3QgY3JlYXRlV2luZG93ID0gKCkgPT4gKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IHdpbmRvdyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD13aW5kb3cuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyA9IChjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKSA9PiB7XG4gICAgcmV0dXJuIChhdWRpb0J1ZmZlcikgPT4ge1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPSAoZGVzdGluYXRpb24sIGNoYW5uZWxOdW1iZXJBc051bWJlciwgYnVmZmVyT2Zmc2V0QXNOdW1iZXIgPSAwKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgaWYgKGNoYW5uZWxOdW1iZXIgPj0gYXVkaW9CdWZmZXIubnVtYmVyT2ZDaGFubmVscykge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUluZGV4U2l6ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhdWRpb0J1ZmZlckxlbmd0aCA9IGF1ZGlvQnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcik7XG4gICAgICAgICAgICBjb25zdCBkZXN0aW5hdGlvbkxlbmd0aCA9IGRlc3RpbmF0aW9uLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBidWZmZXJPZmZzZXQgPCAwID8gLWJ1ZmZlck9mZnNldCA6IDA7IGkgKyBidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlckxlbmd0aCAmJiBpIDwgZGVzdGluYXRpb25MZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICAgIGRlc3RpbmF0aW9uW2ldID0gY2hhbm5lbERhdGFbaSArIGJ1ZmZlck9mZnNldF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlUb0NoYW5uZWwgPSAoc291cmNlLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyT2Zmc2V0ID0gY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKGJ1ZmZlck9mZnNldEFzTnVtYmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgIGlmIChjaGFubmVsTnVtYmVyID49IGF1ZGlvQnVmZmVyLm51bWJlck9mQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbmRleFNpemVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXJMZW5ndGggPSBhdWRpb0J1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IGF1ZGlvQnVmZmVyLmdldENoYW5uZWxEYXRhKGNoYW5uZWxOdW1iZXIpO1xuICAgICAgICAgICAgY29uc3Qgc291cmNlTGVuZ3RoID0gc291cmNlLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBidWZmZXJPZmZzZXQgPCAwID8gLWJ1ZmZlck9mZnNldCA6IDA7IGkgKyBidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlckxlbmd0aCAmJiBpIDwgc291cmNlTGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjaGFubmVsRGF0YVtpICsgYnVmZmVyT2Zmc2V0XSA9IHNvdXJjZVtpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLmpzLm1hcCIsImV4cG9ydCBjb25zdCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyA9IChjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcpID0+IHtcbiAgICByZXR1cm4gKGF1ZGlvQnVmZmVyKSA9PiB7XG4gICAgICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbCA9ICgoY29weUZyb21DaGFubmVsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKGRlc3RpbmF0aW9uLCBjaGFubmVsTnVtYmVyQXNOdW1iZXIsIGJ1ZmZlck9mZnNldEFzTnVtYmVyID0gMCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlck9mZnNldCA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhidWZmZXJPZmZzZXRBc051bWJlcik7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE51bWJlciA9IGNvbnZlcnROdW1iZXJUb1Vuc2lnbmVkTG9uZyhjaGFubmVsTnVtYmVyQXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGlmIChidWZmZXJPZmZzZXQgPCBhdWRpb0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNvcHlGcm9tQ2hhbm5lbC5jYWxsKGF1ZGlvQnVmZmVyLCBkZXN0aW5hdGlvbiwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwpO1xuICAgICAgICBhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsID0gKChjb3B5VG9DaGFubmVsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gKHNvdXJjZSwgY2hhbm5lbE51bWJlckFzTnVtYmVyLCBidWZmZXJPZmZzZXRBc051bWJlciA9IDApID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBidWZmZXJPZmZzZXQgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoYnVmZmVyT2Zmc2V0QXNOdW1iZXIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxOdW1iZXIgPSBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcoY2hhbm5lbE51bWJlckFzTnVtYmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyT2Zmc2V0IDwgYXVkaW9CdWZmZXIubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb3B5VG9DaGFubmVsLmNhbGwoYXVkaW9CdWZmZXIsIHNvdXJjZSwgY2hhbm5lbE51bWJlciwgYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KShhdWRpb0J1ZmZlci5jb3B5VG9DaGFubmVsKTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyID0gKG92ZXJ3cml0ZUFjY2Vzc29ycykgPT4ge1xuICAgIHJldHVybiAobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IG51bGxpZmllZEJ1ZmZlciA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyKDEsIDEsIDQ0MTAwKTtcbiAgICAgICAgaWYgKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBudWxsaWZpZWRCdWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgb3ZlcndyaXRlQWNjZXNzb3JzKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgJ2J1ZmZlcicsIChnZXQpID0+ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0LmNhbGwobmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlKTtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSA9PT0gbnVsbGlmaWVkQnVmZmVyID8gbnVsbCA6IHZhbHVlO1xuICAgICAgICB9LCAoc2V0KSA9PiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBzZXQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHZhbHVlID09PSBudWxsID8gbnVsbGlmaWVkQnVmZmVyIDogdmFsdWUpO1xuICAgICAgICB9KTtcbiAgICB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLW51bGxpZmllZC1idWZmZXIuanMubWFwIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZSA9IChjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgbW9uaXRvckNvbm5lY3Rpb25zKSA9PiB7XG4gICAgcmV0dXJuIChuYXRpdmVDb250ZXh0LCBjaGFubmVsTWVyZ2VyTm9kZSkgPT4ge1xuICAgICAgICAvLyBCdWcgIzE1OiBTYWZhcmkgZG9lcyBub3QgcmV0dXJuIHRoZSBkZWZhdWx0IHByb3BlcnRpZXMuXG4gICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgIGNoYW5uZWxNZXJnZXJOb2RlLmNoYW5uZWxDb3VudE1vZGUgPSAnZXhwbGljaXQnO1xuICAgICAgICAvLyBCdWcgIzE2OiBTYWZhcmkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3Igd2hlbiBzZXR0aW5nIGEgZGlmZmVyZW50IGNoYW5uZWxDb3VudCBvciBjaGFubmVsQ291bnRNb2RlLlxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2hhbm5lbE1lcmdlck5vZGUsICdjaGFubmVsQ291bnQnLCB7XG4gICAgICAgICAgICBnZXQ6ICgpID0+IDEsXG4gICAgICAgICAgICBzZXQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNoYW5uZWxNZXJnZXJOb2RlLCAnY2hhbm5lbENvdW50TW9kZScsIHtcbiAgICAgICAgICAgIGdldDogKCkgPT4gJ2V4cGxpY2l0JyxcbiAgICAgICAgICAgIHNldDogKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRocm93IGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBCdWcgIzIwOiBTYWZhcmkgcmVxdWlyZXMgYSBjb25uZWN0aW9uIG9mIGFueSBraW5kIHRvIHRyZWF0IHRoZSBpbnB1dCBzaWduYWwgY29ycmVjdGx5LlxuICAgICAgICBjb25zdCBhdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgICAgICBjb25zdCB3aGVuQ29ubmVjdGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGVuZ3RoID0gY2hhbm5lbE1lcmdlck5vZGUubnVtYmVyT2ZJbnB1dHM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICAgICAgYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmNvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUsIDAsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB3aGVuRGlzY29ubmVjdGVkID0gKCkgPT4gYXVkaW9CdWZmZXJTb3VyY2VOb2RlLmRpc2Nvbm5lY3QoY2hhbm5lbE1lcmdlck5vZGUpO1xuICAgICAgICBtb25pdG9yQ29ubmVjdGlvbnMoY2hhbm5lbE1lcmdlck5vZGUsIHdoZW5Db25uZWN0ZWQsIHdoZW5EaXNjb25uZWN0ZWQpO1xuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1jaGFubmVsLW1lcmdlci1ub2RlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBnZXRGaXJzdFNhbXBsZSA9IChhdWRpb0J1ZmZlciwgYnVmZmVyLCBjaGFubmVsTnVtYmVyKSA9PiB7XG4gICAgLy8gQnVnICM1OiBTYWZhcmkgZG9lcyBub3Qgc3VwcG9ydCBjb3B5RnJvbUNoYW5uZWwoKSBhbmQgY29weVRvQ2hhbm5lbCgpLlxuICAgIGlmIChhdWRpb0J1ZmZlci5jb3B5RnJvbUNoYW5uZWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gYXVkaW9CdWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE51bWJlcilbMF07XG4gICAgfVxuICAgIGF1ZGlvQnVmZmVyLmNvcHlGcm9tQ2hhbm5lbChidWZmZXIsIGNoYW5uZWxOdW1iZXIpO1xuICAgIHJldHVybiBidWZmZXJbMF07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2V0LWZpcnN0LXNhbXBsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgaXNEQ0N1cnZlID0gKGN1cnZlKSA9PiB7XG4gICAgaWYgKGN1cnZlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgbGVuZ3RoID0gY3VydmUubGVuZ3RoO1xuICAgIGlmIChsZW5ndGggJSAyICE9PSAwKSB7XG4gICAgICAgIHJldHVybiBjdXJ2ZVtNYXRoLmZsb29yKGxlbmd0aCAvIDIpXSAhPT0gMDtcbiAgICB9XG4gICAgcmV0dXJuIGN1cnZlW2xlbmd0aCAvIDIgLSAxXSArIGN1cnZlW2xlbmd0aCAvIDJdICE9PSAwO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzLWRjLWN1cnZlLmpzLm1hcCIsImV4cG9ydCBjb25zdCBvdmVyd3JpdGVBY2Nlc3NvcnMgPSAob2JqZWN0LCBwcm9wZXJ0eSwgY3JlYXRlR2V0dGVyLCBjcmVhdGVTZXR0ZXIpID0+IHtcbiAgICBsZXQgcHJvdG90eXBlID0gb2JqZWN0O1xuICAgIHdoaWxlICghcHJvdG90eXBlLmhhc093blByb3BlcnR5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG90eXBlKTtcbiAgICB9XG4gICAgY29uc3QgeyBnZXQsIHNldCB9ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwcm90b3R5cGUsIHByb3BlcnR5KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkob2JqZWN0LCBwcm9wZXJ0eSwgeyBnZXQ6IGNyZWF0ZUdldHRlcihnZXQpLCBzZXQ6IGNyZWF0ZVNldHRlcihzZXQpIH0pO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW92ZXJ3cml0ZS1hY2Nlc3NvcnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMgPSAob3B0aW9ucykgPT4ge1xuICAgIHJldHVybiB7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIG91dHB1dENoYW5uZWxDb3VudDogb3B0aW9ucy5vdXRwdXRDaGFubmVsQ291bnQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBvcHRpb25zLm91dHB1dENoYW5uZWxDb3VudFxuICAgICAgICAgICAgOiBvcHRpb25zLm51bWJlck9mSW5wdXRzID09PSAxICYmIG9wdGlvbnMubnVtYmVyT2ZPdXRwdXRzID09PSAxXG4gICAgICAgICAgICAgICAgPyAvKlxuICAgICAgICAgICAgICAgICAgICogQnVnICM2MTogVGhpcyBzaG91bGQgYmUgdGhlIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscywgYnV0IHVuZm9ydHVuYXRlbHkgdGhhdCBpcyBhbG1vc3QgaW1wb3NzaWJsZSB0byBmYWtlLiBUaGF0J3Mgd2h5XG4gICAgICAgICAgICAgICAgICAgKiB0aGUgY2hhbm5lbENvdW50TW9kZSBpcyByZXF1aXJlZCB0byBiZSAnZXhwbGljaXQnIGFzIGxvbmcgYXMgdGhlcmUgaXMgbm90IGEgbmF0aXZlIGltcGxlbWVudGF0aW9uIGluIGV2ZXJ5IGJyb3dzZXIuIFRoYXRcbiAgICAgICAgICAgICAgICAgICAqIG1ha2VzIHN1cmUgdGhlIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyBlcXVpdmlsYW50IHRvIHRoZSBjaGFubmVsQ291bnQgd2hpY2ggbWFrZXMgaXQgbXVjaCBlYXNpZXIgdG8gY29tcHV0ZS5cbiAgICAgICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICAgICAgICBbb3B0aW9ucy5jaGFubmVsQ291bnRdXG4gICAgICAgICAgICAgICAgOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyB9LCAoKSA9PiAxKVxuICAgIH07XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2FuaXRpemUtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7XG4gICAgcmV0dXJuIHsgLi4ub3B0aW9ucywgY2hhbm5lbENvdW50OiBvcHRpb25zLm51bWJlck9mT3V0cHV0cyB9O1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXNhbml0aXplLWNoYW5uZWwtc3BsaXR0ZXItb3B0aW9ucy5qcy5tYXAiLCJleHBvcnQgY29uc3Qgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zID0gKG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCB7IGltYWcsIHJlYWwgfSA9IG9wdGlvbnM7XG4gICAgaWYgKGltYWcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAocmVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnOiBbMCwgMF0sIHJlYWw6IFswLCAwXSB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWc6IEFycmF5LmZyb20ocmVhbCwgKCkgPT4gMCksIHJlYWwgfTtcbiAgICB9XG4gICAgaWYgKHJlYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4geyAuLi5vcHRpb25zLCBpbWFnLCByZWFsOiBBcnJheS5mcm9tKGltYWcsICgpID0+IDApIH07XG4gICAgfVxuICAgIHJldHVybiB7IC4uLm9wdGlvbnMsIGltYWcsIHJlYWwgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zYW5pdGl6ZS1wZXJpb2RpYy13YXZlLW9wdGlvbnMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHNldFZhbHVlQXRUaW1lVW50aWxQb3NzaWJsZSA9IChhdWRpb1BhcmFtLCB2YWx1ZSwgc3RhcnRUaW1lKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXVkaW9QYXJhbS5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lKTtcbiAgICB9XG4gICAgY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZXJyLmNvZGUgIT09IDkpIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUoYXVkaW9QYXJhbSwgdmFsdWUsIHN0YXJ0VGltZSArIDFlLTcpO1xuICAgIH1cbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1zZXQtdmFsdWUtYXQtdGltZS11bnRpbC1wb3NzaWJsZS5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgPSAobmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSA9IG5hdGl2ZUNvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kT2Zmc2V0Q2xhbXBpbmdTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlclNvdXJjZSgpO1xuICAgIGNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXIoMSwgMSwgNDQxMDApO1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXIgPSBuYXRpdmVBdWRpb0J1ZmZlcjtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoMCwgMSk7XG4gICAgfVxuICAgIGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD10ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2Qtb2Zmc2V0LWNsYW1waW5nLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgIH1cbiAgICBjYXRjaCB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbnVsbGlmaWVkLWJ1ZmZlci1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0ID0gKG5hdGl2ZUNvbnRleHQpID0+IHtcbiAgICBjb25zdCBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQoLTEpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiBlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW5lZ2F0aXZlLXBhcmFtZXRlcnMtc3VwcG9ydC5qcy5tYXAiLCJleHBvcnQgY29uc3QgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXIgPSBuYXRpdmVDb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxLCA0NDEwMCk7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuYnVmZmVyID0gbmF0aXZlQXVkaW9CdWZmZXI7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0YXJ0KCk7XG4gICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoKTtcbiAgICB0cnkge1xuICAgICAgICBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RvcCgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY2F0Y2gge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzLXN1cHBvcnQuanMubWFwIiwiZXhwb3J0IGNvbnN0IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCA9IChuYXRpdmVDb250ZXh0KSA9PiB7XG4gICAgY29uc3QgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgdHJ5IHtcbiAgICAgICAgbmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLnN0b3AoLTEpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHJldHVybiBlcnIgaW5zdGFuY2VvZiBSYW5nZUVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0LmpzLm1hcCIsImV4cG9ydCBjb25zdCB0ZXN0QXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnNDbG9uYWJpbGl0eSA9IChhdWRpb1dvcmtsZXROb2RlT3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcbiAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIHdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGF1ZGlvV29ya2xldE5vZGVPcHRpb25zIGFyZSBub3QgY2xvbmFibGUuXG4gICAgICAgIHBvcnQxLnBvc3RNZXNzYWdlKGF1ZGlvV29ya2xldE5vZGVPcHRpb25zKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAgIHBvcnQxLmNsb3NlKCk7XG4gICAgICAgIHBvcnQyLmNsb3NlKCk7XG4gICAgfVxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHkuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nID0gKG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSkgPT4ge1xuICAgIG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5zdGFydCA9ICgoc3RhcnQpID0+IHtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCwgb2Zmc2V0ID0gMCwgZHVyYXRpb24pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZS5idWZmZXI7XG4gICAgICAgICAgICAvLyBCdWcgIzE1NDogU2FmYXJpIGRvZXMgbm90IGNsYW1wIHRoZSBvZmZzZXQgaWYgaXQgaXMgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIHRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLlxuICAgICAgICAgICAgY29uc3QgY2xhbXBlZE9mZnNldCA9IGJ1ZmZlciA9PT0gbnVsbCA/IG9mZnNldCA6IE1hdGgubWluKGJ1ZmZlci5kdXJhdGlvbiwgb2Zmc2V0KTtcbiAgICAgICAgICAgIC8vIEJ1ZyAjMTU1OiBTYWZhcmkgZG9lcyBub3QgaGFuZGxlIHRoZSBvZmZzZXQgY29ycmVjdGx5IGlmIGl0IHdvdWxkIGNhdXNlIHRoZSBidWZmZXIgdG8gYmUgbm90IGJlIHBsYXllZCBhdCBhbGwuXG4gICAgICAgICAgICBpZiAoYnVmZmVyICE9PSBudWxsICYmIGNsYW1wZWRPZmZzZXQgPiBidWZmZXIuZHVyYXRpb24gLSAwLjUgLyBuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuY29udGV4dC5zYW1wbGVSYXRlKSB7XG4gICAgICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIDAsIDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhcnQuY2FsbChuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIHdoZW4sIGNsYW1wZWRPZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUuc3RhcnQpO1xufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXdyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcuanMubWFwIiwiaW1wb3J0IHsgaW50ZXJjZXB0Q29ubmVjdGlvbnMgfSBmcm9tICcuL2ludGVyY2VwdC1jb25uZWN0aW9ucyc7XG5leHBvcnQgY29uc3Qgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzID0gKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlQ29udGV4dCkgPT4ge1xuICAgIGNvbnN0IG5hdGl2ZUdhaW5Ob2RlID0gbmF0aXZlQ29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgbmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLmNvbm5lY3QobmF0aXZlR2Fpbk5vZGUpO1xuICAgIGNvbnN0IGRpc2Nvbm5lY3RHYWluTm9kZSA9ICgoZGlzY29ubmVjdCkgPT4ge1xuICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgLy8gQHRvZG8gVHlwZVNjcmlwdCBjYW5ub3QgaW5mZXIgdGhlIG92ZXJsb2FkZWQgc2lnbmF0dXJlIHdpdGggMSBhcmd1bWVudCB5ZXQuXG4gICAgICAgICAgICBkaXNjb25uZWN0LmNhbGwobmF0aXZlQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlLCBuYXRpdmVHYWluTm9kZSk7XG4gICAgICAgICAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0R2Fpbk5vZGUpO1xuICAgICAgICB9O1xuICAgIH0pKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5kaXNjb25uZWN0KTtcbiAgICBuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuYWRkRXZlbnRMaXN0ZW5lcignZW5kZWQnLCBkaXNjb25uZWN0R2Fpbk5vZGUpO1xuICAgIGludGVyY2VwdENvbm5lY3Rpb25zKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgbmF0aXZlR2Fpbk5vZGUpO1xuICAgIG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZS5zdG9wID0gKChzdG9wKSA9PiB7XG4gICAgICAgIGxldCBpc1N0b3BwZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICh3aGVuID0gMCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzU3RvcHBlZCkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHN0b3AuY2FsbChuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUsIHdoZW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXRjaCB7XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUdhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgd2hlbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RvcC5jYWxsKG5hdGl2ZUF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZSwgd2hlbik7XG4gICAgICAgICAgICAgICAgaXNTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9KShuYXRpdmVBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGUuc3RvcCk7XG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9d3JhcC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMuanMubWFwIiwiZXhwb3J0IGNvbnN0IHdyYXBFdmVudExpc3RlbmVyID0gKHRhcmdldCwgZXZlbnRMaXN0ZW5lcikgPT4ge1xuICAgIHJldHVybiAoZXZlbnQpID0+IHtcbiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsgdmFsdWU6IHRhcmdldCB9O1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhldmVudCwge1xuICAgICAgICAgICAgY3VycmVudFRhcmdldDogZGVzY3JpcHRvcixcbiAgICAgICAgICAgIHRhcmdldDogZGVzY3JpcHRvclxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHR5cGVvZiBldmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRMaXN0ZW5lci5jYWxsKHRhcmdldCwgZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBldmVudExpc3RlbmVyLmhhbmRsZUV2ZW50LmNhbGwodGFyZ2V0LCBldmVudCk7XG4gICAgfTtcbn07XG4vLyMgc291cmNlTWFwcGluZ1VSTD13cmFwLWV2ZW50LWxpc3RlbmVyLmpzLm1hcCIsImltcG9ydCB7IGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQgfSBmcm9tICdhdXRvbWF0aW9uLWV2ZW50cyc7XG5pbXBvcnQgeyBjcmVhdGVBYm9ydEVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWJvcnQtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlQWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYWN0aXZlLWlucHV0LWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby1ub2RlLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGNyZWF0ZUFkZEF1ZGlvUGFyYW1Db25uZWN0aW9ucyB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1hdWRpby1wYXJhbS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVBZGRBdWRpb1dvcmtsZXRNb2R1bGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtYXVkaW8td29ya2xldC1tb2R1bGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvYWRkLWNvbm5lY3Rpb24tdG8tYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9hZGQtcGFzc2l2ZS1pbnB1dC1jb25uZWN0aW9uLXRvLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlQWRkU2lsZW50Q29ubmVjdGlvbiB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC1zaWxlbnQtY29ubmVjdGlvbic7XG5pbXBvcnQgeyBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2FkZC11bnJlbmRlcmVkLWF1ZGlvLXdvcmtsZXQtbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVBbmFseXNlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2FuYWx5c2VyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYW5hbHlzZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1idWZmZXItc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvRGVzdGluYXRpb25Ob2RlUmVuZGVyZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1kZXN0aW5hdGlvbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby1saXN0ZW5lci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2F1ZGlvLXBhcmFtLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9QYXJhbVJlbmRlcmVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8tcGFyYW0tcmVuZGVyZXInO1xuaW1wb3J0IHsgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYXVkaW8td29ya2xldC1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUF1ZGlvV29ya2xldE5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9hdWRpby13b3JrbGV0LW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9iYXNlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvYmlxdWFkLWZpbHRlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUJpcXVhZEZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9iaXF1YWQtZmlsdGVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDYWNoZVRlc3RSZXN1bHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9jYWNoZS10ZXN0LXJlc3VsdCc7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY2hhbm5lbC1tZXJnZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtbWVyZ2VyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9jaGFubmVsLXNwbGl0dGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2NoYW5uZWwtc3BsaXR0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdC1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVDb25uZWN0TXVsdGlwbGVPdXRwdXRzIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29ubmVjdC1tdWx0aXBsZS1vdXRwdXRzJztcbmltcG9ydCB7IGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb25uZWN0ZWQtbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvY29uc3RhbnQtc291cmNlLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252ZXJ0LW51bWJlci10by11bnNpZ25lZC1sb25nJztcbmltcG9ydCB7IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL2NvbnZvbHZlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUNvbnZvbHZlck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9jb252b2x2ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9jcmVhdGUtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVEYXRhQ2xvbmVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2RhdGEtY2xvbmUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlRGVjb2RlQXVkaW9EYXRhIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVjb2RlLWF1ZGlvLWRhdGEnO1xuaW1wb3J0IHsgY3JlYXRlRGVjcmVtZW50Q3ljbGVDb3VudGVyIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVjcmVtZW50LWN5Y2xlLWNvdW50ZXInO1xuaW1wb3J0IHsgY3JlYXRlRGVsYXlOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9kZWxheS1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGF5LW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVEZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2RlbGV0ZS1hY3RpdmUtaW5wdXQtY29ubmVjdGlvbi10by1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZURlbGV0ZVVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvZGVsZXRlLXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZURldGVjdEN5Y2xlcyB9IGZyb20gJy4vZmFjdG9yaWVzL2RldGVjdC1jeWNsZXMnO1xuaW1wb3J0IHsgY3JlYXRlRGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2Rpc2Nvbm5lY3QtbXVsdGlwbGUtb3V0cHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9keW5hbWljcy1jb21wcmVzc29yLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2R5bmFtaWNzLWNvbXByZXNzb3Itbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUVuY29kaW5nRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9lbmNvZGluZy1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVFdmFsdWF0ZVNvdXJjZSB9IGZyb20gJy4vZmFjdG9yaWVzL2V2YWx1YXRlLXNvdXJjZSc7XG5pbXBvcnQgeyBjcmVhdGVFdmVudFRhcmdldENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXZlbnQtdGFyZ2V0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvZXhwb3NlLWN1cnJlbnQtZnJhbWUtYW5kLWN1cnJlbnQtdGltZSc7XG5pbXBvcnQgeyBjcmVhdGVGZXRjaFNvdXJjZSB9IGZyb20gJy4vZmFjdG9yaWVzL2ZldGNoLXNvdXJjZSc7XG5pbXBvcnQgeyBjcmVhdGVHYWluTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2Fpbi1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2Fpbi1ub2RlLXJlbmRlcmVyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlR2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hY3RpdmUtYXVkaW8td29ya2xldC1ub2RlLWlucHV0cyc7XG5pbXBvcnQgeyBjcmVhdGVHZXRBdWRpb05vZGVSZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1ub2RlLXJlbmRlcmVyJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvTm9kZVRhaWxUaW1lIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWF1ZGlvLW5vZGUtdGFpbC10aW1lJztcbmltcG9ydCB7IGNyZWF0ZUdldEF1ZGlvUGFyYW1SZW5kZXJlciB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1hdWRpby1wYXJhbS1yZW5kZXJlcic7XG5pbXBvcnQgeyBjcmVhdGVHZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0TmF0aXZlQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL2dldC1uYXRpdmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVHZXRPckNyZWF0ZUJhY2t1cE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9nZXQtb3ItY3JlYXRlLWJhY2t1cC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzIH0gZnJvbSAnLi9mYWN0b3JpZXMvZ2V0LXVucmVuZGVyZWQtYXVkaW8td29ya2xldC1ub2Rlcyc7XG5pbXBvcnQgeyBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9paXItZmlsdGVyLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlSUlSRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL2lpci1maWx0ZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUluY3JlbWVudEN5Y2xlQ291bnRlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbmNyZW1lbnQtY3ljbGUtY291bnRlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZUluZGV4U2l6ZUVycm9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvaW5kZXgtc2l6ZS1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkQWNjZXNzRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9pbnZhbGlkLWFjY2Vzcy1lcnJvcic7XG5pbXBvcnQgeyBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL2ludmFsaWQtc3RhdGUtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueUF1ZGlvTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZUlzQW55QXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL2lzLWFueS1hdWRpby1wYXJhbSc7XG5pbXBvcnQgeyBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1hbnktb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZUlzTmF0aXZlQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWF1ZGlvLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVBdWRpb05vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0gfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVDb250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLWNvbnRleHQnO1xuaW1wb3J0IHsgY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSAnLi9mYWN0b3JpZXMvaXMtbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc1NlY3VyZUNvbnRleHQgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1zZWN1cmUtY29udGV4dCc7XG5pbXBvcnQgeyBjcmVhdGVJc1N1cHBvcnRlZFByb21pc2UgfSBmcm9tICcuL2ZhY3Rvcmllcy9pcy1zdXBwb3J0ZWQtcHJvbWlzZSc7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWVkaWEtc3RyZWFtLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL21lZGlhLXN0cmVhbS1hdWRpby1zb3VyY2Utbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9tZWRpYS1zdHJlYW0tdHJhY2stYXVkaW8tc291cmNlLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9taW5pbWFsLWJhc2UtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbWluaW1hbC1vZmZsaW5lLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTW9uaXRvckNvbm5lY3Rpb25zIH0gZnJvbSAnLi9mYWN0b3JpZXMvbW9uaXRvci1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBbmFseXNlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWFuYWx5c2VyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWNvbnRleHQtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9EZXN0aW5hdGlvbk5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLWRlc3RpbmF0aW9uLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1hdWRpby13b3JrbGV0LW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUJpcXVhZEZpbHRlck5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtYmlxdWFkLWZpbHRlci1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLW1lcmdlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jaGFubmVsLXNwbGl0dGVyLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1jb25zdGFudC1zb3VyY2Utbm9kZS1mYWtlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWNvbnZvbHZlci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlRGVsYXlOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWRlbGF5LW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZHluYW1pY3MtY29tcHJlc3Nvci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlR2Fpbk5vZGUgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtZ2Fpbi1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLWlpci1maWx0ZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtaWlyLWZpbHRlci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFFbGVtZW50QXVkaW9Tb3VyY2VOb2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW1lZGlhLWVsZW1lbnQtYXVkaW8tc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tZGVzdGluYXRpb24tbm9kZSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtbWVkaWEtc3RyZWFtLXRyYWNrLWF1ZGlvLXNvdXJjZS1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLW9mZmxpbmUtYXVkaW8tY29udGV4dC1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtb3NjaWxsYXRvci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGFubmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtcGFubmVyLW5vZGUtZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXBhbm5lci1ub2RlLWZha2VyLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1wZXJpb2RpYy13YXZlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zY3JpcHQtcHJvY2Vzc29yLW5vZGUnO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtc3RlcmVvLXBhbm5lci1ub2RlLWZhY3RvcnknO1xuaW1wb3J0IHsgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSB9IGZyb20gJy4vZmFjdG9yaWVzL25hdGl2ZS1zdGVyZW8tcGFubmVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9uYXRpdmUtd2F2ZS1zaGFwZXItbm9kZS1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvbmF0aXZlLXdhdmUtc2hhcGVyLW5vZGUtZmFrZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciB9IGZyb20gJy4vZmFjdG9yaWVzL25vdC1zdXBwb3J0ZWQtZXJyb3InO1xuaW1wb3J0IHsgY3JlYXRlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvb2ZmbGluZS1hdWRpby1jb250ZXh0LWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZU9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9vc2NpbGxhdG9yLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy9wYW5uZXItbm9kZS1jb25zdHJ1Y3Rvcic7XG5pbXBvcnQgeyBjcmVhdGVQYW5uZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVQZXJpb2RpY1dhdmVDb25zdHJ1Y3RvciB9IGZyb20gJy4vZmFjdG9yaWVzL3BlcmlvZGljLXdhdmUtY29uc3RydWN0b3InO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVyQXV0b21hdGlvbiB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1hdXRvbWF0aW9uJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9Ob2RlIH0gZnJvbSAnLi9mYWN0b3JpZXMvcmVuZGVyLWlucHV0cy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbSB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1pbnB1dHMtb2YtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgY3JlYXRlUmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCB9IGZyb20gJy4vZmFjdG9yaWVzL3JlbmRlci1uYXRpdmUtb2ZmbGluZS1hdWRpby1jb250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgfSBmcm9tICcuL2ZhY3Rvcmllcy9zZXQtYWN0aXZlLWF1ZGlvLXdvcmtsZXQtbm9kZS1pbnB1dHMnO1xuaW1wb3J0IHsgY3JlYXRlU2V0QXVkaW9Ob2RlVGFpbFRpbWUgfSBmcm9tICcuL2ZhY3Rvcmllcy9zZXQtYXVkaW8tbm9kZS10YWlsLXRpbWUnO1xuaW1wb3J0IHsgY3JlYXRlU3RhcnRSZW5kZXJpbmcgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGFydC1yZW5kZXJpbmcnO1xuaW1wb3J0IHsgY3JlYXRlU3RlcmVvUGFubmVyTm9kZUNvbnN0cnVjdG9yIH0gZnJvbSAnLi9mYWN0b3JpZXMvc3RlcmVvLXBhbm5lci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlckZhY3RvcnkgfSBmcm9tICcuL2ZhY3Rvcmllcy9zdGVyZW8tcGFubmVyLW5vZGUtcmVuZGVyZXItZmFjdG9yeSc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9CdWZmZXJDb25zdHJ1Y3RvclN1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLWJ1ZmZlci1jb25zdHJ1Y3Rvci1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc1N1YmFycmF5U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLXN1YmFycmF5LXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dENsb3NlTWV0aG9kU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1jbG9zZS1tZXRob2Qtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Db250ZXh0RGVjb2RlQXVkaW9EYXRhTWV0aG9kVHlwZUVycm9yU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1kZWNvZGUtYXVkaW8tZGF0YS1tZXRob2QtdHlwZS1lcnJvci1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RBdWRpb0NvbnRleHRPcHRpb25zU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtYXVkaW8tY29udGV4dC1vcHRpb25zLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvTm9kZUNvbm5lY3RNZXRob2RTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby1ub2RlLWNvbm5lY3QtbWV0aG9kLXN1cHBvcnQnO1xuaW1wb3J0IHsgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3Nvck5vT3V0cHV0c1N1cHBvcnQgfSBmcm9tICcuL2ZhY3Rvcmllcy90ZXN0LWF1ZGlvLXdvcmtsZXQtcHJvY2Vzc29yLW5vLW91dHB1dHMtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0QXVkaW9Xb3JrbGV0UHJvY2Vzc29yUG9zdE1lc3NhZ2VTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1hdWRpby13b3JrbGV0LXByb2Nlc3Nvci1wb3N0LW1lc3NhZ2Utc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q2hhbm5lbE1lcmdlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1jaGFubmVsLW1lcmdlci1ub2RlLWNoYW5uZWwtY291bnQtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0Q29uc3RhbnRTb3VyY2VOb2RlQWNjdXJhdGVTY2hlZHVsaW5nU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29uc3RhbnQtc291cmNlLW5vZGUtYWNjdXJhdGUtc2NoZWR1bGluZy1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQnVmZmVyUmVhc3NpZ25hYmlsaXR5U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29udm9sdmVyLW5vZGUtYnVmZmVyLXJlYXNzaWduYWJpbGl0eS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RDb252b2x2ZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3QtY29udm9sdmVyLW5vZGUtY2hhbm5lbC1jb3VudC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RJc1NlY3VyZUNvbnRleHRTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1pcy1zZWN1cmUtY29udGV4dC1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZU1lZGlhU3RyZWFtV2l0aG91dEF1ZGlvVHJhY2tTdXBwb3J0IH0gZnJvbSAnLi9mYWN0b3JpZXMvdGVzdC1tZWRpYS1zdHJlYW0tYXVkaW8tc291cmNlLW5vZGUtbWVkaWEtc3RyZWFtLXdpdGhvdXQtYXVkaW8tdHJhY2stc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVUZXN0T2ZmbGluZUF1ZGlvQ29udGV4dEN1cnJlbnRUaW1lU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3Qtb2ZmbGluZS1hdWRpby1jb250ZXh0LWN1cnJlbnQtdGltZS1zdXBwb3J0JztcbmltcG9ydCB7IGNyZWF0ZVRlc3RTdGVyZW9QYW5uZXJOb2RlRGVmYXVsdFZhbHVlU3VwcG9ydCB9IGZyb20gJy4vZmFjdG9yaWVzL3Rlc3Qtc3RlcmVvLXBhbm5lci1ub2RlLWRlZmF1bHQtdmFsdWUtc3VwcG9ydCc7XG5pbXBvcnQgeyBjcmVhdGVVbmtub3duRXJyb3IgfSBmcm9tICcuL2ZhY3Rvcmllcy91bmtub3duLWVycm9yJztcbmltcG9ydCB7IGNyZWF0ZVdhdmVTaGFwZXJOb2RlQ29uc3RydWN0b3IgfSBmcm9tICcuL2ZhY3Rvcmllcy93YXZlLXNoYXBlci1ub2RlLWNvbnN0cnVjdG9yJztcbmltcG9ydCB7IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXJGYWN0b3J5IH0gZnJvbSAnLi9mYWN0b3JpZXMvd2F2ZS1zaGFwZXItbm9kZS1yZW5kZXJlci1mYWN0b3J5JztcbmltcG9ydCB7IGNyZWF0ZVdpbmRvdyB9IGZyb20gJy4vZmFjdG9yaWVzL3dpbmRvdyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1jb3B5LWNoYW5uZWwtbWV0aG9kcyc7XG5pbXBvcnQgeyBjcmVhdGVXcmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHNPdXRPZkJvdW5kcyB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMnO1xuaW1wb3J0IHsgY3JlYXRlV3JhcEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXIgfSBmcm9tICcuL2ZhY3Rvcmllcy93cmFwLWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyJztcbmltcG9ydCB7IGNyZWF0ZVdyYXBDaGFubmVsTWVyZ2VyTm9kZSB9IGZyb20gJy4vZmFjdG9yaWVzL3dyYXAtY2hhbm5lbC1tZXJnZXItbm9kZSc7XG5pbXBvcnQgeyBBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFLCBBVURJT19OT0RFX1NUT1JFLCBBVURJT19QQVJBTV9DT05ORUNUSU9OU19TVE9SRSwgQVVESU9fUEFSQU1fU1RPUkUsIENPTlRFWFRfU1RPUkUsIENZQ0xFX0NPVU5URVJTIH0gZnJvbSAnLi9nbG9iYWxzJztcbmltcG9ydCB7IGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9jb25uZWN0LW5hdGl2ZS1hdWRpby1ub2RlLXRvLW5hdGl2ZS1hdWRpby1ub2RlJztcbmltcG9ydCB7IGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2Rpc2Nvbm5lY3QtbmF0aXZlLWF1ZGlvLW5vZGUtZnJvbS1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXRBdWRpb05vZGVDb25uZWN0aW9ucyB9IGZyb20gJy4vaGVscGVycy9nZXQtYXVkaW8tbm9kZS1jb25uZWN0aW9ucyc7XG5pbXBvcnQgeyBnZXRBdWRpb1BhcmFtQ29ubmVjdGlvbnMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWF1ZGlvLXBhcmFtLWNvbm5lY3Rpb25zJztcbmltcG9ydCB7IGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LWV2ZW50LWxpc3RlbmVycy1vZi1hdWRpby1ub2RlJztcbmltcG9ydCB7IGdldEZpcnN0U2FtcGxlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1maXJzdC1zYW1wbGUnO1xuaW1wb3J0IHsgZ2V0TmF0aXZlQXVkaW9Ob2RlIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBnZXROYXRpdmVBdWRpb1BhcmFtIH0gZnJvbSAnLi9oZWxwZXJzL2dldC1uYXRpdmUtYXVkaW8tcGFyYW0nO1xuaW1wb3J0IHsgZ2V0VmFsdWVGb3JLZXkgfSBmcm9tICcuL2hlbHBlcnMvZ2V0LXZhbHVlLWZvci1rZXknO1xuaW1wb3J0IHsgaW5zZXJ0RWxlbWVudEluU2V0IH0gZnJvbSAnLi9oZWxwZXJzL2luc2VydC1lbGVtZW50LWluLXNldCc7XG5pbXBvcnQgeyBpc0FjdGl2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9pcy1hY3RpdmUtYXVkaW8tbm9kZSc7XG5pbXBvcnQgeyBpc0RDQ3VydmUgfSBmcm9tICcuL2hlbHBlcnMvaXMtZGMtY3VydmUnO1xuaW1wb3J0IHsgaXNQYXJ0T2ZBQ3ljbGUgfSBmcm9tICcuL2hlbHBlcnMvaXMtcGFydC1vZi1hLWN5Y2xlJztcbmltcG9ydCB7IGlzUGFzc2l2ZUF1ZGlvTm9kZSB9IGZyb20gJy4vaGVscGVycy9pcy1wYXNzaXZlLWF1ZGlvLW5vZGUnO1xuaW1wb3J0IHsgb3ZlcndyaXRlQWNjZXNzb3JzIH0gZnJvbSAnLi9oZWxwZXJzL292ZXJ3cml0ZS1hY2Nlc3NvcnMnO1xuaW1wb3J0IHsgcGlja0VsZW1lbnRGcm9tU2V0IH0gZnJvbSAnLi9oZWxwZXJzL3BpY2stZWxlbWVudC1mcm9tLXNldCc7XG5pbXBvcnQgeyBzYW5pdGl6ZUF1ZGlvV29ya2xldE5vZGVPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLWF1ZGlvLXdvcmtsZXQtbm9kZS1vcHRpb25zJztcbmltcG9ydCB7IHNhbml0aXplQ2hhbm5lbFNwbGl0dGVyT3B0aW9ucyB9IGZyb20gJy4vaGVscGVycy9zYW5pdGl6ZS1jaGFubmVsLXNwbGl0dGVyLW9wdGlvbnMnO1xuaW1wb3J0IHsgc2FuaXRpemVQZXJpb2RpY1dhdmVPcHRpb25zIH0gZnJvbSAnLi9oZWxwZXJzL3Nhbml0aXplLXBlcmlvZGljLXdhdmUtb3B0aW9ucyc7XG5pbXBvcnQgeyBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUgfSBmcm9tICcuL2hlbHBlcnMvc2V0LXZhbHVlLWF0LXRpbWUtdW50aWwtcG9zc2libGUnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8tYnVmZmVyLWNvcHktY2hhbm5lbC1tZXRob2RzLW91dC1vZi1ib3VuZHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RDb25zZWN1dGl2ZUNhbGxzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RhcnRNZXRob2RPZmZzZXRDbGFtcGluZ1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1idWZmZXItc291cmNlLW5vZGUtc3RhcnQtbWV0aG9kLW9mZnNldC1jbGFtcGluZy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdG9wTWV0aG9kTnVsbGlmaWVkQnVmZmVyU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLWJ1ZmZlci1zb3VyY2Utbm9kZS1zdG9wLW1ldGhvZC1udWxsaWZpZWQtYnVmZmVyLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0YXJ0TWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWF1ZGlvLXNjaGVkdWxlZC1zb3VyY2Utbm9kZS1zdGFydC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtY29uc2VjdXRpdmUtY2FsbHMtc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1hdWRpby1zY2hlZHVsZWQtc291cmNlLW5vZGUtc3RvcC1tZXRob2QtbmVnYXRpdmUtcGFyYW1ldGVycy1zdXBwb3J0JztcbmltcG9ydCB7IHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtYXVkaW8td29ya2xldC1ub2RlLW9wdGlvbnMtY2xvbmFiaWxpdHknO1xuaW1wb3J0IHsgdGVzdERvbUV4Y2VwdGlvbkNvbnN0cnVjdG9yU3VwcG9ydCB9IGZyb20gJy4vaGVscGVycy90ZXN0LWRvbS1leGNlcHRpb24tY29uc3RydWN0b3Itc3VwcG9ydCc7XG5pbXBvcnQgeyB0ZXN0UHJvbWlzZVN1cHBvcnQgfSBmcm9tICcuL2hlbHBlcnMvdGVzdC1wcm9taXNlLXN1cHBvcnQnO1xuaW1wb3J0IHsgdGVzdFRyYW5zZmVyYWJsZXNTdXBwb3J0IH0gZnJvbSAnLi9oZWxwZXJzL3Rlc3QtdHJhbnNmZXJhYmxlcy1zdXBwb3J0JztcbmltcG9ydCB7IHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtYXVkaW8tYnVmZmVyLXNvdXJjZS1ub2RlLXN0YXJ0LW1ldGhvZC1vZmZzZXQtY2xhbXBpbmcnO1xuaW1wb3J0IHsgd3JhcEF1ZGlvU2NoZWR1bGVkU291cmNlTm9kZVN0b3BNZXRob2RDb25zZWN1dGl2ZUNhbGxzIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtYXVkaW8tc2NoZWR1bGVkLXNvdXJjZS1ub2RlLXN0b3AtbWV0aG9kLWNvbnNlY3V0aXZlLWNhbGxzJztcbmltcG9ydCB7IHdyYXBFdmVudExpc3RlbmVyIH0gZnJvbSAnLi9oZWxwZXJzL3dyYXAtZXZlbnQtbGlzdGVuZXInO1xuLypcbiAqIEB0b2RvIEV4cGxpY2l0bHkgcmVmZXJlbmNpbmcgdGhlIGJhcnJlbCBmaWxlIHNlZW1zIHRvIGJlIG5lY2Vzc2FyeSB3aGVuIGVuYWJsaW5nIHRoZVxuICogaXNvbGF0ZWRNb2R1bGVzIGNvbXBpbGVyIG9wdGlvbi5cbiAqL1xuZXhwb3J0ICogZnJvbSAnLi9pbnRlcmZhY2VzL2luZGV4JztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMvaW5kZXgnO1xuY29uc3QgYWRkQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUgPSBjcmVhdGVBZGRBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZShpbnNlcnRFbGVtZW50SW5TZXQpO1xuY29uc3QgYWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlID0gY3JlYXRlQWRkUGFzc2l2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKGluc2VydEVsZW1lbnRJblNldCk7XG5jb25zdCBkZWxldGVBY3RpdmVJbnB1dENvbm5lY3Rpb25Ub0F1ZGlvTm9kZSA9IGNyZWF0ZURlbGV0ZUFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlKHBpY2tFbGVtZW50RnJvbVNldCk7XG5jb25zdCBhdWRpb05vZGVUYWlsVGltZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldEF1ZGlvTm9kZVRhaWxUaW1lID0gY3JlYXRlR2V0QXVkaW9Ob2RlVGFpbFRpbWUoYXVkaW9Ob2RlVGFpbFRpbWVTdG9yZSk7XG5jb25zdCBjYWNoZVRlc3RSZXN1bHQgPSBjcmVhdGVDYWNoZVRlc3RSZXN1bHQobmV3IE1hcCgpLCBuZXcgV2Vha01hcCgpKTtcbmNvbnN0IHdpbmRvdyA9IGNyZWF0ZVdpbmRvdygpO1xuY29uc3QgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlID0gY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlRmFjdG9yeShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IGdldEF1ZGlvTm9kZVJlbmRlcmVyID0gY3JlYXRlR2V0QXVkaW9Ob2RlUmVuZGVyZXIoZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMpO1xuY29uc3QgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUgPSBjcmVhdGVSZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZShnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGlzUGFydE9mQUN5Y2xlKTtcbmNvbnN0IGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyID0gY3JlYXRlQW5hbHlzZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUFuYWx5c2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBnZXROYXRpdmVDb250ZXh0ID0gY3JlYXRlR2V0TmF0aXZlQ29udGV4dChDT05URVhUX1NUT1JFKTtcbmNvbnN0IG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlSXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUgPSBuZXcgV2Vha01hcCgpO1xuY29uc3QgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciA9IGNyZWF0ZUV2ZW50VGFyZ2V0Q29uc3RydWN0b3Iod3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgbmF0aXZlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgaXNOYXRpdmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc05hdGl2ZUF1ZGlvQ29udGV4dChuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBpc05hdGl2ZUF1ZGlvTm9kZSA9IGNyZWF0ZUlzTmF0aXZlQXVkaW9Ob2RlKHdpbmRvdyk7XG5jb25zdCBpc05hdGl2ZUF1ZGlvUGFyYW0gPSBjcmVhdGVJc05hdGl2ZUF1ZGlvUGFyYW0od2luZG93KTtcbmNvbnN0IG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3Rvcih3aW5kb3cpO1xuY29uc3QgYXVkaW9Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb05vZGVDb25zdHJ1Y3RvcihjcmVhdGVBZGRBdWRpb05vZGVDb25uZWN0aW9ucyhBVURJT19OT0RFX0NPTk5FQ1RJT05TX1NUT1JFKSwgY3JlYXRlQWRkQ29ubmVjdGlvblRvQXVkaW9Ob2RlKGFkZEFjdGl2ZUlucHV0Q29ubmVjdGlvblRvQXVkaW9Ob2RlLCBhZGRQYXNzaXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGNvbm5lY3ROYXRpdmVBdWRpb05vZGVUb05hdGl2ZUF1ZGlvTm9kZSwgZGVsZXRlQWN0aXZlSW5wdXRDb25uZWN0aW9uVG9BdWRpb05vZGUsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QXVkaW9Ob2RlVGFpbFRpbWUsIGdldEV2ZW50TGlzdGVuZXJzT2ZBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgaW5zZXJ0RWxlbWVudEluU2V0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNQYXJ0T2ZBQ3ljbGUsIGlzUGFzc2l2ZUF1ZGlvTm9kZSksIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW5jcmVtZW50Q3ljbGVDb3VudGVyRmFjdG9yeShDWUNMRV9DT1VOVEVSUywgZGlzY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZUZyb21OYXRpdmVBdWRpb05vZGUsIGdldEF1ZGlvTm9kZUNvbm5lY3Rpb25zLCBnZXROYXRpdmVBdWRpb05vZGUsIGdldE5hdGl2ZUF1ZGlvUGFyYW0sIGlzQWN0aXZlQXVkaW9Ob2RlKSwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZURlY3JlbWVudEN5Y2xlQ291bnRlcihjb25uZWN0TmF0aXZlQXVkaW9Ob2RlVG9OYXRpdmVBdWRpb05vZGUsIENZQ0xFX0NPVU5URVJTLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0TmF0aXZlQXVkaW9Ob2RlLCBnZXROYXRpdmVBdWRpb1BhcmFtLCBnZXROYXRpdmVDb250ZXh0LCBpc0FjdGl2ZUF1ZGlvTm9kZSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KSwgY3JlYXRlRGV0ZWN0Q3ljbGVzKGF1ZGlvUGFyYW1BdWRpb05vZGVTdG9yZSwgZ2V0QXVkaW9Ob2RlQ29ubmVjdGlvbnMsIGdldFZhbHVlRm9yS2V5KSwgZXZlbnRUYXJnZXRDb25zdHJ1Y3RvciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlQXVkaW9Ob2RlLCBpc05hdGl2ZUF1ZGlvUGFyYW0sIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgbmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKTtcbmNvbnN0IGFuYWx5c2VyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQW5hbHlzZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUFuYWx5c2VyTm9kZVJlbmRlcmVyLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlTmF0aXZlQW5hbHlzZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IHsgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IgYXMgQW5hbHlzZXJOb2RlIH07XG5jb25zdCBhdWRpb0J1ZmZlclN0b3JlID0gbmV3IFdlYWtTZXQoKTtcbmNvbnN0IG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKHdpbmRvdyk7XG5jb25zdCBjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcgPSBjcmVhdGVDb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcobmV3IFVpbnQzMkFycmF5KDEpKTtcbmNvbnN0IHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyA9IGNyZWF0ZVdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcyhjb252ZXJ0TnVtYmVyVG9VbnNpZ25lZExvbmcsIGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzID0gY3JlYXRlV3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMoY29udmVydE51bWJlclRvVW5zaWduZWRMb25nKTtcbmNvbnN0IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0J1ZmZlckNvbnN0cnVjdG9yKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgY3JlYXRlVGVzdEF1ZGlvQnVmZmVyQ29uc3RydWN0b3JTdXBwb3J0KG5hdGl2ZUF1ZGlvQnVmZmVyQ29uc3RydWN0b3IpLCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmV4cG9ydCB7IGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IgYXMgQXVkaW9CdWZmZXIgfTtcbmNvbnN0IGFkZFNpbGVudENvbm5lY3Rpb24gPSBjcmVhdGVBZGRTaWxlbnRDb25uZWN0aW9uKGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlKTtcbmNvbnN0IHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSA9IGNyZWF0ZVJlbmRlcklucHV0c09mQXVkaW9QYXJhbShnZXRBdWRpb05vZGVSZW5kZXJlciwgZ2V0QXVkaW9QYXJhbUNvbm5lY3Rpb25zLCBpc1BhcnRPZkFDeWNsZSk7XG5jb25zdCBjb25uZWN0QXVkaW9QYXJhbSA9IGNyZWF0ZUNvbm5lY3RBdWRpb1BhcmFtKHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0YXJ0TWV0aG9kQ29uc2VjdXRpdmVDYWxsc1N1cHBvcnQsIHRlc3RBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nU3VwcG9ydCwgdGVzdEF1ZGlvQnVmZmVyU291cmNlTm9kZVN0b3BNZXRob2ROdWxsaWZpZWRCdWZmZXJTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlclNvdXJjZU5vZGVTdGFydE1ldGhvZE9mZnNldENsYW1waW5nLCBjcmVhdGVXcmFwQXVkaW9CdWZmZXJTb3VyY2VOb2RlU3RvcE1ldGhvZE51bGxpZmllZEJ1ZmZlcihvdmVyd3JpdGVBY2Nlc3NvcnMpLCB3cmFwQXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHMpO1xuY29uc3QgcmVuZGVyQXV0b21hdGlvbiA9IGNyZWF0ZVJlbmRlckF1dG9tYXRpb24oY3JlYXRlR2V0QXVkaW9QYXJhbVJlbmRlcmVyKGdldEF1ZGlvUGFyYW1Db25uZWN0aW9ucyksIHJlbmRlcklucHV0c09mQXVkaW9QYXJhbSk7XG5jb25zdCBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVSZW5kZXJlciA9IGNyZWF0ZUF1ZGlvQnVmZmVyU291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNyZWF0ZUF1ZGlvUGFyYW0gPSBjcmVhdGVBdWRpb1BhcmFtRmFjdG9yeShjcmVhdGVBZGRBdWRpb1BhcmFtQ29ubmVjdGlvbnMoQVVESU9fUEFSQU1fQ09OTkVDVElPTlNfU1RPUkUpLCBhdWRpb1BhcmFtQXVkaW9Ob2RlU3RvcmUsIEFVRElPX1BBUkFNX1NUT1JFLCBjcmVhdGVBdWRpb1BhcmFtUmVuZGVyZXIsIGNyZWF0ZUNhbmNlbEFuZEhvbGRBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZUNhbmNlbFNjaGVkdWxlZFZhbHVlc0F1dG9tYXRpb25FdmVudCwgY3JlYXRlRXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF1dG9tYXRpb25FdmVudCwgY3JlYXRlTGluZWFyUmFtcFRvVmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFRhcmdldEF1dG9tYXRpb25FdmVudCwgY3JlYXRlU2V0VmFsdWVBdXRvbWF0aW9uRXZlbnQsIGNyZWF0ZVNldFZhbHVlQ3VydmVBdXRvbWF0aW9uRXZlbnQsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBzZXRWYWx1ZUF0VGltZVVudGlsUG9zc2libGUpO1xuY29uc3QgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0J1ZmZlclNvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9CdWZmZXJTb3VyY2VOb2RlUmVuZGVyZXIsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuZXhwb3J0IHsgYXVkaW9CdWZmZXJTb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgQXVkaW9CdWZmZXJTb3VyY2VOb2RlIH07XG5jb25zdCBhdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9EZXN0aW5hdGlvbk5vZGVSZW5kZXJlciwgY3JlYXRlSW5kZXhTaXplRXJyb3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOYXRpdmVBdWRpb0Rlc3RpbmF0aW9uTm9kZUZhY3RvcnkoY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG92ZXJ3cml0ZUFjY2Vzc29ycyksIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBzZXRBdWRpb05vZGVUYWlsVGltZSA9IGNyZWF0ZVNldEF1ZGlvTm9kZVRhaWxUaW1lKGF1ZGlvTm9kZVRhaWxUaW1lU3RvcmUpO1xuY29uc3QgYmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQmlxdWFkRmlsdGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVCaXF1YWRGaWx0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlTmF0aXZlQmlxdWFkRmlsdGVyTm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBtb25pdG9yQ29ubmVjdGlvbnMgPSBjcmVhdGVNb25pdG9yQ29ubmVjdGlvbnMoaW5zZXJ0RWxlbWVudEluU2V0LCBpc05hdGl2ZUF1ZGlvTm9kZSk7XG5jb25zdCB3cmFwQ2hhbm5lbE1lcmdlck5vZGUgPSBjcmVhdGVXcmFwQ2hhbm5lbE1lcmdlck5vZGUoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlRmFjdG9yeShuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgd3JhcENoYW5uZWxNZXJnZXJOb2RlKTtcbmNvbnN0IGNyZWF0ZUNoYW5uZWxNZXJnZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDaGFubmVsTWVyZ2VyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBjaGFubmVsTWVyZ2VyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ2hhbm5lbE1lcmdlck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXJGYWN0b3J5KGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVDaGFubmVsU3BsaXR0ZXJOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2FuaXRpemVDaGFubmVsU3BsaXR0ZXJPcHRpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXJGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUgPSBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGVGYWN0b3J5KGFkZFNpbGVudENvbm5lY3Rpb24sIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlRmFrZXIsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdGFydE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHRlc3RBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kTmVnYXRpdmVQYXJhbWV0ZXJzU3VwcG9ydCk7XG5jb25zdCBjcmVhdGVDb25zdGFudFNvdXJjZU5vZGVSZW5kZXJlciA9IGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNvbnN0YW50U291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlQ29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUNvbnN0YW50U291cmNlTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlTmF0aXZlQ29udm9sdmVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUNvbnZvbHZlck5vZGVGYWN0b3J5KGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBvdmVyd3JpdGVBY2Nlc3NvcnMpO1xuY29uc3QgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZUNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQ29udm9sdmVyTm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVDb252b2x2ZXJOb2RlLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGNyZWF0ZURlbGF5Tm9kZVJlbmRlcmVyID0gY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVEZWxheU5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgcmVuZGVyQXV0b21hdGlvbiwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUpO1xuY29uc3QgZGVsYXlOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVEZWxheU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlRGVsYXlOb2RlUmVuZGVyZXIsIGNyZWF0ZU5hdGl2ZURlbGF5Tm9kZSwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVEeW5hbWljc0NvbXByZXNzb3JOb2RlID0gY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZUZhY3RvcnkoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyID0gY3JlYXRlRHluYW1pY3NDb21wcmVzc29yTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBkeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVEeW5hbWljc0NvbXByZXNzb3JOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZUR5bmFtaWNzQ29tcHJlc3Nvck5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlRHluYW1pY3NDb21wcmVzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgc2V0QXVkaW9Ob2RlVGFpbFRpbWUpO1xuY29uc3QgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciA9IGNyZWF0ZUdhaW5Ob2RlUmVuZGVyZXJGYWN0b3J5KGNvbm5lY3RBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBnYWluTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlR2Fpbk5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlR2Fpbk5vZGVSZW5kZXJlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXIgPSBjcmVhdGVOYXRpdmVJSVJGaWx0ZXJOb2RlRmFrZXJGYWN0b3J5KGNyZWF0ZUludmFsaWRBY2Nlc3NFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yKTtcbmNvbnN0IHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVSZW5kZXJOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVNjcmlwdFByb2Nlc3Nvck5vZGUsIGNyZWF0ZVRlc3RPZmZsaW5lQXVkaW9Db250ZXh0Q3VycmVudFRpbWVTdXBwb3J0KGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpKTtcbmNvbnN0IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciA9IGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlckZhY3RvcnkoY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciwgcmVuZGVySW5wdXRzT2ZBdWRpb05vZGUsIHJlbmRlck5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQpO1xuY29uc3QgY3JlYXRlTmF0aXZlSUlSRmlsdGVyTm9kZSA9IGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGVGYWtlcik7XG5jb25zdCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVJSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZUlJUkZpbHRlck5vZGUsIGNyZWF0ZUlJUkZpbHRlck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVBdWRpb0xpc3RlbmVyID0gY3JlYXRlQXVkaW9MaXN0ZW5lckZhY3RvcnkoY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlU2NyaXB0UHJvY2Vzc29yTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGdldEZpcnN0U2FtcGxlLCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG92ZXJ3cml0ZUFjY2Vzc29ycyk7XG5jb25zdCB1bnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZVN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvTGlzdGVuZXIsIGV2ZW50VGFyZ2V0Q29uc3RydWN0b3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVTdG9yZSwgd3JhcEV2ZW50TGlzdGVuZXIpO1xuY29uc3QgY3JlYXRlTmF0aXZlT3NjaWxsYXRvck5vZGUgPSBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZUZhY3RvcnkoYWRkU2lsZW50Q29ubmVjdGlvbiwgY2FjaGVUZXN0UmVzdWx0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RhcnRNZXRob2ROZWdhdGl2ZVBhcmFtZXRlcnNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZENvbnNlY3V0aXZlQ2FsbHNTdXBwb3J0LCB0ZXN0QXVkaW9TY2hlZHVsZWRTb3VyY2VOb2RlU3RvcE1ldGhvZE5lZ2F0aXZlUGFyYW1ldGVyc1N1cHBvcnQsIHdyYXBBdWRpb1NjaGVkdWxlZFNvdXJjZU5vZGVTdG9wTWV0aG9kQ29uc2VjdXRpdmVDYWxscyk7XG5jb25zdCBjcmVhdGVPc2NpbGxhdG9yTm9kZVJlbmRlcmVyID0gY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlckZhY3RvcnkoY29ubmVjdEF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZU9zY2lsbGF0b3JOb2RlLCBnZXROYXRpdmVBdWRpb05vZGUsIHJlbmRlckF1dG9tYXRpb24sIHJlbmRlcklucHV0c09mQXVkaW9Ob2RlKTtcbmNvbnN0IG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVPc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVBdWRpb1BhcmFtLCBjcmVhdGVOYXRpdmVPc2NpbGxhdG9yTm9kZSwgY3JlYXRlT3NjaWxsYXRvck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCB3cmFwRXZlbnRMaXN0ZW5lcik7XG5jb25zdCBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGUgPSBjcmVhdGVDb25uZWN0ZWROYXRpdmVBdWRpb0J1ZmZlclNvdXJjZU5vZGVGYWN0b3J5KGNyZWF0ZU5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZUZha2VyID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlQ29ubmVjdGVkTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlID0gY3JlYXRlTmF0aXZlV2F2ZVNoYXBlck5vZGVGYWN0b3J5KGNyZWF0ZUNvbm5lY3RlZE5hdGl2ZUF1ZGlvQnVmZmVyU291cmNlTm9kZSwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlRmFrZXIsIGlzRENDdXJ2ZSwgbW9uaXRvckNvbm5lY3Rpb25zLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvciwgb3ZlcndyaXRlQWNjZXNzb3JzKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlciA9IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGVGYWtlckZhY3RvcnkoY29ubmVjdE5hdGl2ZUF1ZGlvTm9kZVRvTmF0aXZlQXVkaW9Ob2RlLCBjcmVhdGVJbnZhbGlkU3RhdGVFcnJvciwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGRpc2Nvbm5lY3ROYXRpdmVBdWRpb05vZGVGcm9tTmF0aXZlQXVkaW9Ob2RlLCBnZXRGaXJzdFNhbXBsZSwgbW9uaXRvckNvbm5lY3Rpb25zKTtcbmNvbnN0IGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUgPSBjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFjdG9yeShjcmVhdGVOYXRpdmVQYW5uZXJOb2RlRmFrZXIpO1xuY29uc3QgY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNvbnN0YW50U291cmNlTm9kZSwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGdldE5hdGl2ZUF1ZGlvTm9kZSwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBwYW5uZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVQYW5uZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVBhbm5lck5vZGUsIGNyZWF0ZVBhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBzZXRBdWRpb05vZGVUYWlsVGltZSk7XG5jb25zdCBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmUgPSBjcmVhdGVOYXRpdmVQZXJpb2RpY1dhdmVGYWN0b3J5KGNyZWF0ZUluZGV4U2l6ZUVycm9yKTtcbmNvbnN0IHBlcmlvZGljV2F2ZUNvbnN0cnVjdG9yID0gY3JlYXRlUGVyaW9kaWNXYXZlQ29uc3RydWN0b3IoY3JlYXRlTmF0aXZlUGVyaW9kaWNXYXZlLCBnZXROYXRpdmVDb250ZXh0LCBuZXcgV2Vha1NldCgpLCBzYW5pdGl6ZVBlcmlvZGljV2F2ZU9wdGlvbnMpO1xuY29uc3QgbmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSA9IGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGVGYWtlckZhY3RvcnkoY3JlYXRlTmF0aXZlQ2hhbm5lbE1lcmdlck5vZGUsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxTcGxpdHRlck5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVTdGVyZW9QYW5uZXJOb2RlID0gY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZUZhY3RvcnkobmF0aXZlU3RlcmVvUGFubmVyTm9kZUZha2VyRmFjdG9yeSwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IpO1xuY29uc3QgY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyID0gY3JlYXRlU3RlcmVvUGFubmVyTm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY3JlYXRlTmF0aXZlU3RlcmVvUGFubmVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVTdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZUF1ZGlvUGFyYW0sIGNyZWF0ZU5hdGl2ZVN0ZXJlb1Bhbm5lck5vZGUsIGNyZWF0ZVN0ZXJlb1Bhbm5lck5vZGVSZW5kZXJlciwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmNvbnN0IGNyZWF0ZVdhdmVTaGFwZXJOb2RlUmVuZGVyZXIgPSBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyRmFjdG9yeShjcmVhdGVOYXRpdmVXYXZlU2hhcGVyTm9kZSwgZ2V0TmF0aXZlQXVkaW9Ob2RlLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSk7XG5jb25zdCB3YXZlU2hhcGVyTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlV2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZVdhdmVTaGFwZXJOb2RlLCBjcmVhdGVXYXZlU2hhcGVyTm9kZVJlbmRlcmVyLCBnZXROYXRpdmVDb250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHNldEF1ZGlvTm9kZVRhaWxUaW1lKTtcbmNvbnN0IGlzU2VjdXJlQ29udGV4dCA9IGNyZWF0ZUlzU2VjdXJlQ29udGV4dCh3aW5kb3cpO1xuY29uc3QgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUgPSBjcmVhdGVFeHBvc2VDdXJyZW50RnJhbWVBbmRDdXJyZW50VGltZSh3aW5kb3cpO1xuY29uc3QgYmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dFN0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUdldE9yQ3JlYXRlQmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG4vLyBUaGUgYWRkQXVkaW9Xb3JrbGV0TW9kdWxlKCkgZnVuY3Rpb24gaXMgb25seSBhdmFpbGFibGUgaW4gYSBTZWN1cmVDb250ZXh0LlxuZXhwb3J0IGNvbnN0IGFkZEF1ZGlvV29ya2xldE1vZHVsZSA9IGlzU2VjdXJlQ29udGV4dFxuICAgID8gY3JlYXRlQWRkQXVkaW9Xb3JrbGV0TW9kdWxlKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIGNyZWF0ZUV2YWx1YXRlU291cmNlKHdpbmRvdyksIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBjcmVhdGVGZXRjaFNvdXJjZShjcmVhdGVBYm9ydEVycm9yKSwgZ2V0TmF0aXZlQ29udGV4dCwgZ2V0T3JDcmVhdGVCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0LCBpc05hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmV3IFdlYWtNYXAoKSwgbmV3IFdlYWtNYXAoKSwgY3JlYXRlVGVzdEF1ZGlvV29ya2xldFByb2Nlc3NvclBvc3RNZXNzYWdlU3VwcG9ydChuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIFxuICAgIC8vIEB0b2RvIHdpbmRvdyBpcyBndWFyYW50ZWVkIHRvIGJlIGRlZmluZWQgYmVjYXVzZSBpc1NlY3VyZUNvbnRleHQgY2hlY2tzIHRoYXQgYXMgd2VsbC5cbiAgICB3aW5kb3cpXG4gICAgOiB1bmRlZmluZWQ7XG5jb25zdCBpc05hdGl2ZUNvbnRleHQgPSBjcmVhdGVJc05hdGl2ZUNvbnRleHQoaXNOYXRpdmVBdWRpb0NvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5leHBvcnQgY29uc3QgZGVjb2RlQXVkaW9EYXRhID0gY3JlYXRlRGVjb2RlQXVkaW9EYXRhKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlRGF0YUNsb25lRXJyb3IsIGNyZWF0ZUVuY29kaW5nRXJyb3IsIG5ldyBXZWFrU2V0KCksIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB0ZXN0UHJvbWlzZVN1cHBvcnQsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kcywgd3JhcEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHMpO1xuY29uc3QgYmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGFkZEF1ZGlvV29ya2xldE1vZHVsZSwgYW5hbHlzZXJOb2RlQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyQ29uc3RydWN0b3IsIGF1ZGlvQnVmZmVyU291cmNlTm9kZUNvbnN0cnVjdG9yLCBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxNZXJnZXJOb2RlQ29uc3RydWN0b3IsIGNoYW5uZWxTcGxpdHRlck5vZGVDb25zdHJ1Y3RvciwgY29uc3RhbnRTb3VyY2VOb2RlQ29uc3RydWN0b3IsIGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciwgZGVjb2RlQXVkaW9EYXRhLCBkZWxheU5vZGVDb25zdHJ1Y3RvciwgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yLCBnYWluTm9kZUNvbnN0cnVjdG9yLCBpSVJGaWx0ZXJOb2RlQ29uc3RydWN0b3IsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIG9zY2lsbGF0b3JOb2RlQ29uc3RydWN0b3IsIHBhbm5lck5vZGVDb25zdHJ1Y3RvciwgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IsIHN0ZXJlb1Bhbm5lck5vZGVDb25zdHJ1Y3Rvciwgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3Rvcik7XG5jb25zdCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciA9IGNyZWF0ZU1lZGlhRWxlbWVudEF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yKGF1ZGlvTm9kZUNvbnN0cnVjdG9yLCBjcmVhdGVOYXRpdmVNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yID0gY3JlYXRlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvcihhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1BdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBjcmVhdGVOYXRpdmVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlID0gY3JlYXRlTmF0aXZlTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZUZhY3RvcnkoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGlzTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgPSBjcmVhdGVNZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IoYXVkaW9Ob2RlQ29uc3RydWN0b3IsIGNyZWF0ZU5hdGl2ZU1lZGlhU3RyZWFtVHJhY2tBdWRpb1NvdXJjZU5vZGUsIGdldE5hdGl2ZUNvbnRleHQpO1xuY29uc3QgYXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciwgbWVkaWFTdHJlYW1BdWRpb0Rlc3RpbmF0aW9uTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yLCBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IsIG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKTtcbmV4cG9ydCB7IGF1ZGlvQ29udGV4dENvbnN0cnVjdG9yIGFzIEF1ZGlvQ29udGV4dCB9O1xuY29uc3QgZ2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzID0gY3JlYXRlR2V0VW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGVzKHVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlU3RvcmUpO1xuY29uc3QgYWRkVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVBZGRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpO1xuY29uc3QgY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IGNyZWF0ZUNvbm5lY3RNdWx0aXBsZU91dHB1dHMoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUgPSBjcmVhdGVEZWxldGVVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZShnZXRVbnJlbmRlcmVkQXVkaW9Xb3JrbGV0Tm9kZXMpO1xuY29uc3QgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cyA9IGNyZWF0ZURpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMoY3JlYXRlSW5kZXhTaXplRXJyb3IpO1xuY29uc3QgYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlID0gbmV3IFdlYWtNYXAoKTtcbmNvbnN0IGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMgPSBjcmVhdGVHZXRBY3RpdmVBdWRpb1dvcmtsZXROb2RlSW5wdXRzKGFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHNTdG9yZSwgZ2V0VmFsdWVGb3JLZXkpO1xuY29uc3QgY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZha2VyRmFjdG9yeShjb25uZWN0TXVsdGlwbGVPdXRwdXRzLCBjcmVhdGVJbmRleFNpemVFcnJvciwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUNoYW5uZWxNZXJnZXJOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsU3BsaXR0ZXJOb2RlLCBjcmVhdGVOYXRpdmVDb25zdGFudFNvdXJjZU5vZGUsIGNyZWF0ZU5hdGl2ZUdhaW5Ob2RlLCBjcmVhdGVOYXRpdmVTY3JpcHRQcm9jZXNzb3JOb2RlLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgZGlzY29ubmVjdE11bHRpcGxlT3V0cHV0cywgZXhwb3NlQ3VycmVudEZyYW1lQW5kQ3VycmVudFRpbWUsIGdldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIG1vbml0b3JDb25uZWN0aW9ucyk7XG5jb25zdCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlID0gY3JlYXRlTmF0aXZlQXVkaW9Xb3JrbGV0Tm9kZUZhY3RvcnkoY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZUF1ZGlvV29ya2xldE5vZGVGYWtlciwgY3JlYXRlTmF0aXZlR2Fpbk5vZGUsIGNyZWF0ZU5vdFN1cHBvcnRlZEVycm9yLCBtb25pdG9yQ29ubmVjdGlvbnMpO1xuY29uc3QgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyID0gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyRmFjdG9yeShjb25uZWN0QXVkaW9QYXJhbSwgY29ubmVjdE11bHRpcGxlT3V0cHV0cywgY3JlYXRlTmF0aXZlQXVkaW9CdWZmZXJTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVDaGFubmVsTWVyZ2VyTm9kZSwgY3JlYXRlTmF0aXZlQ2hhbm5lbFNwbGl0dGVyTm9kZSwgY3JlYXRlTmF0aXZlQ29uc3RhbnRTb3VyY2VOb2RlLCBjcmVhdGVOYXRpdmVHYWluTm9kZSwgZGVsZXRlVW5yZW5kZXJlZEF1ZGlvV29ya2xldE5vZGUsIGRpc2Nvbm5lY3RNdWx0aXBsZU91dHB1dHMsIGV4cG9zZUN1cnJlbnRGcmFtZUFuZEN1cnJlbnRUaW1lLCBnZXROYXRpdmVBdWRpb05vZGUsIG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCByZW5kZXJBdXRvbWF0aW9uLCByZW5kZXJJbnB1dHNPZkF1ZGlvTm9kZSwgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCk7XG5jb25zdCBnZXRCYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0ID0gY3JlYXRlR2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dChiYWNrdXBPZmZsaW5lQXVkaW9Db250ZXh0U3RvcmUpO1xuY29uc3Qgc2V0QWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0cyA9IGNyZWF0ZVNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMoYWN0aXZlQXVkaW9Xb3JrbGV0Tm9kZUlucHV0c1N0b3JlKTtcbi8vIFRoZSBBdWRpb1dvcmtsZXROb2RlIGNvbnN0cnVjdG9yIGlzIG9ubHkgYXZhaWxhYmxlIGluIGEgU2VjdXJlQ29udGV4dC5cbmNvbnN0IGF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciA9IGlzU2VjdXJlQ29udGV4dFxuICAgID8gY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZUNvbnN0cnVjdG9yKGFkZFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlLCBhdWRpb05vZGVDb25zdHJ1Y3RvciwgY3JlYXRlQXVkaW9QYXJhbSwgY3JlYXRlQXVkaW9Xb3JrbGV0Tm9kZVJlbmRlcmVyLCBjcmVhdGVOYXRpdmVBdWRpb1dvcmtsZXROb2RlLCBnZXRBdWRpb05vZGVDb25uZWN0aW9ucywgZ2V0QmFja3VwT2ZmbGluZUF1ZGlvQ29udGV4dCwgZ2V0TmF0aXZlQ29udGV4dCwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0LCBuYXRpdmVBdWRpb1dvcmtsZXROb2RlQ29uc3RydWN0b3IsIHNhbml0aXplQXVkaW9Xb3JrbGV0Tm9kZU9wdGlvbnMsIHNldEFjdGl2ZUF1ZGlvV29ya2xldE5vZGVJbnB1dHMsIHRlc3RBdWRpb1dvcmtsZXROb2RlT3B0aW9uc0Nsb25hYmlsaXR5LCB3cmFwRXZlbnRMaXN0ZW5lcilcbiAgICA6IHVuZGVmaW5lZDtcbmV4cG9ydCB7IGF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciBhcyBBdWRpb1dvcmtsZXROb2RlIH07XG5leHBvcnQgeyBiaXF1YWRGaWx0ZXJOb2RlQ29uc3RydWN0b3IgYXMgQmlxdWFkRmlsdGVyTm9kZSB9O1xuZXhwb3J0IHsgY2hhbm5lbE1lcmdlck5vZGVDb25zdHJ1Y3RvciBhcyBDaGFubmVsTWVyZ2VyTm9kZSB9O1xuZXhwb3J0IHsgY2hhbm5lbFNwbGl0dGVyTm9kZUNvbnN0cnVjdG9yIGFzIENoYW5uZWxTcGxpdHRlck5vZGUgfTtcbmV4cG9ydCB7IGNvbnZvbHZlck5vZGVDb25zdHJ1Y3RvciBhcyBDb252b2x2ZXJOb2RlIH07XG5leHBvcnQgeyBjb25zdGFudFNvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBDb25zdGFudFNvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IGRlbGF5Tm9kZUNvbnN0cnVjdG9yIGFzIERlbGF5Tm9kZSB9O1xuZXhwb3J0IHsgZHluYW1pY3NDb21wcmVzc29yTm9kZUNvbnN0cnVjdG9yIGFzIER5bmFtaWNzQ29tcHJlc3Nvck5vZGUgfTtcbmV4cG9ydCB7IGdhaW5Ob2RlQ29uc3RydWN0b3IgYXMgR2Fpbk5vZGUgfTtcbmV4cG9ydCB7IGlJUkZpbHRlck5vZGVDb25zdHJ1Y3RvciBhcyBJSVJGaWx0ZXJOb2RlIH07XG5leHBvcnQgeyBtZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYUVsZW1lbnRBdWRpb1NvdXJjZU5vZGUgfTtcbmV4cG9ydCB7IG1lZGlhU3RyZWFtQXVkaW9EZXN0aW5hdGlvbk5vZGVDb25zdHJ1Y3RvciBhcyBNZWRpYVN0cmVhbUF1ZGlvRGVzdGluYXRpb25Ob2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZUNvbnN0cnVjdG9yIGFzIE1lZGlhU3RyZWFtQXVkaW9Tb3VyY2VOb2RlIH07XG5leHBvcnQgeyBtZWRpYVN0cmVhbVRyYWNrQXVkaW9Tb3VyY2VOb2RlQ29uc3RydWN0b3IgYXMgTWVkaWFTdHJlYW1UcmFja0F1ZGlvU291cmNlTm9kZSB9O1xuY29uc3QgbWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yID0gY3JlYXRlTWluaW1hbEF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGNyZWF0ZUludmFsaWRTdGF0ZUVycm9yLCBjcmVhdGVOb3RTdXBwb3J0ZWRFcnJvciwgY3JlYXRlVW5rbm93bkVycm9yLCBtaW5pbWFsQmFzZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yLCBuYXRpdmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5leHBvcnQgeyBtaW5pbWFsQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgTWluaW1hbEF1ZGlvQ29udGV4dCB9O1xuY29uc3QgY3JlYXRlTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCA9IGNyZWF0ZUNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQoY3JlYXRlTm90U3VwcG9ydGVkRXJyb3IsIG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3Rvcik7XG5jb25zdCBzdGFydFJlbmRlcmluZyA9IGNyZWF0ZVN0YXJ0UmVuZGVyaW5nKGF1ZGlvQnVmZmVyU3RvcmUsIGNhY2hlVGVzdFJlc3VsdCwgZ2V0QXVkaW9Ob2RlUmVuZGVyZXIsIGdldFVucmVuZGVyZWRBdWRpb1dvcmtsZXROb2RlcywgcmVuZGVyTmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dCwgdGVzdEF1ZGlvQnVmZmVyQ29weUNoYW5uZWxNZXRob2RzT3V0T2ZCb3VuZHNTdXBwb3J0LCB3cmFwQXVkaW9CdWZmZXJDb3B5Q2hhbm5lbE1ldGhvZHMsIHdyYXBBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc091dE9mQm91bmRzKTtcbmNvbnN0IG1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgPSBjcmVhdGVNaW5pbWFsT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIG1pbmltYWxCYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIHN0YXJ0UmVuZGVyaW5nKTtcbmV4cG9ydCB7IG1pbmltYWxPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IgYXMgTWluaW1hbE9mZmxpbmVBdWRpb0NvbnRleHQgfTtcbmNvbnN0IG9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciA9IGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvcihiYXNlQXVkaW9Db250ZXh0Q29uc3RydWN0b3IsIGNhY2hlVGVzdFJlc3VsdCwgY3JlYXRlSW52YWxpZFN0YXRlRXJyb3IsIGNyZWF0ZU5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHQsIHN0YXJ0UmVuZGVyaW5nKTtcbmV4cG9ydCB7IG9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciBhcyBPZmZsaW5lQXVkaW9Db250ZXh0IH07XG5leHBvcnQgeyBvc2NpbGxhdG9yTm9kZUNvbnN0cnVjdG9yIGFzIE9zY2lsbGF0b3JOb2RlIH07XG5leHBvcnQgeyBwYW5uZXJOb2RlQ29uc3RydWN0b3IgYXMgUGFubmVyTm9kZSB9O1xuZXhwb3J0IHsgcGVyaW9kaWNXYXZlQ29uc3RydWN0b3IgYXMgUGVyaW9kaWNXYXZlIH07XG5leHBvcnQgeyBzdGVyZW9QYW5uZXJOb2RlQ29uc3RydWN0b3IgYXMgU3RlcmVvUGFubmVyTm9kZSB9O1xuZXhwb3J0IHsgd2F2ZVNoYXBlck5vZGVDb25zdHJ1Y3RvciBhcyBXYXZlU2hhcGVyTm9kZSB9O1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9Db250ZXh0ID0gY3JlYXRlSXNBbnlBdWRpb0NvbnRleHQoQ09OVEVYVF9TVE9SRSwgaXNOYXRpdmVBdWRpb0NvbnRleHQpO1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9Ob2RlID0gY3JlYXRlSXNBbnlBdWRpb05vZGUoQVVESU9fTk9ERV9TVE9SRSwgaXNOYXRpdmVBdWRpb05vZGUpO1xuZXhwb3J0IGNvbnN0IGlzQW55QXVkaW9QYXJhbSA9IGNyZWF0ZUlzQW55QXVkaW9QYXJhbShBVURJT19QQVJBTV9TVE9SRSwgaXNOYXRpdmVBdWRpb1BhcmFtKTtcbmV4cG9ydCBjb25zdCBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQgPSBjcmVhdGVJc0FueU9mZmxpbmVBdWRpb0NvbnRleHQoQ09OVEVYVF9TVE9SRSwgaXNOYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0KTtcbmV4cG9ydCBjb25zdCBpc1N1cHBvcnRlZCA9ICgpID0+IGNyZWF0ZUlzU3VwcG9ydGVkUHJvbWlzZShjYWNoZVRlc3RSZXN1bHQsIGNyZWF0ZVRlc3RBdWRpb0J1ZmZlckNvcHlDaGFubmVsTWV0aG9kc1N1YmFycmF5U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0QXVkaW9Db250ZXh0Q2xvc2VNZXRob2RTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dERlY29kZUF1ZGlvRGF0YU1ldGhvZFR5cGVFcnJvclN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvQ29udGV4dE9wdGlvbnNTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdEF1ZGlvTm9kZUNvbm5lY3RNZXRob2RTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIGNyZWF0ZVRlc3RBdWRpb1dvcmtsZXRQcm9jZXNzb3JOb091dHB1dHNTdXBwb3J0KG5hdGl2ZUF1ZGlvV29ya2xldE5vZGVDb25zdHJ1Y3RvciwgbmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENoYW5uZWxNZXJnZXJOb2RlQ2hhbm5lbENvdW50U3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29uc3RhbnRTb3VyY2VOb2RlQWNjdXJhdGVTY2hlZHVsaW5nU3VwcG9ydChuYXRpdmVPZmZsaW5lQXVkaW9Db250ZXh0Q29uc3RydWN0b3IpLCBjcmVhdGVUZXN0Q29udm9sdmVyTm9kZUJ1ZmZlclJlYXNzaWduYWJpbGl0eVN1cHBvcnQobmF0aXZlT2ZmbGluZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdENvbnZvbHZlck5vZGVDaGFubmVsQ291bnRTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIHRlc3REb21FeGNlcHRpb25Db25zdHJ1Y3RvclN1cHBvcnQsIGNyZWF0ZVRlc3RJc1NlY3VyZUNvbnRleHRTdXBwb3J0KHdpbmRvdyksIGNyZWF0ZVRlc3RNZWRpYVN0cmVhbUF1ZGlvU291cmNlTm9kZU1lZGlhU3RyZWFtV2l0aG91dEF1ZGlvVHJhY2tTdXBwb3J0KG5hdGl2ZUF1ZGlvQ29udGV4dENvbnN0cnVjdG9yKSwgY3JlYXRlVGVzdFN0ZXJlb1Bhbm5lck5vZGVEZWZhdWx0VmFsdWVTdXBwb3J0KG5hdGl2ZU9mZmxpbmVBdWRpb0NvbnRleHRDb25zdHJ1Y3RvciksIHRlc3RUcmFuc2ZlcmFibGVzU3VwcG9ydCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tb2R1bGUuanMubWFwIiwiLyoqXG4gKiBBc3NlcnQgdGhhdCB0aGUgc3RhdGVtZW50IGlzIHRydWUsIG90aGVyd2lzZSBpbnZva2UgdGhlIGVycm9yLlxuICogQHBhcmFtIHN0YXRlbWVudFxuICogQHBhcmFtIGVycm9yIFRoZSBtZXNzYWdlIHdoaWNoIGlzIHBhc3NlZCBpbnRvIGFuIEVycm9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoc3RhdGVtZW50LCBlcnJvcikge1xuICAgIGlmICghc3RhdGVtZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgfVxufVxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCB0aGUgZ2l2ZW4gdmFsdWUgaXMgd2l0aGluIHRoZSByYW5nZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UmFuZ2UodmFsdWUsIGd0ZSwgbHRlID0gSW5maW5pdHkpIHtcbiAgICBpZiAoIShndGUgPD0gdmFsdWUgJiYgdmFsdWUgPD0gbHRlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVmFsdWUgbXVzdCBiZSB3aXRoaW4gWyR7Z3RlfSwgJHtsdGV9XSwgZ290OiAke3ZhbHVlfWApO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGdpdmVuIHZhbHVlIGlzIHdpdGhpbiB0aGUgcmFuZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2VydENvbnRleHRSdW5uaW5nKGNvbnRleHQpIHtcbiAgICAvLyBhZGQgYSB3YXJuaW5nIGlmIHRoZSBjb250ZXh0IGlzIG5vdCBzdGFydGVkXG4gICAgaWYgKCFjb250ZXh0LmlzT2ZmbGluZSAmJiBjb250ZXh0LnN0YXRlICE9PSBcInJ1bm5pbmdcIikge1xuICAgICAgICB3YXJuKFwiVGhlIEF1ZGlvQ29udGV4dCBpcyBcXFwic3VzcGVuZGVkXFxcIi4gSW52b2tlIFRvbmUuc3RhcnQoKSBmcm9tIGEgdXNlciBhY3Rpb24gdG8gc3RhcnQgdGhlIGF1ZGlvLlwiKTtcbiAgICB9XG59XG4vKipcbiAqIFRoZSBkZWZhdWx0IGxvZ2dlciBpcyB0aGUgY29uc29sZVxuICovXG5sZXQgZGVmYXVsdExvZ2dlciA9IGNvbnNvbGU7XG4vKipcbiAqIFNldCB0aGUgbG9nZ2luZyBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihsb2dnZXIpIHtcbiAgICBkZWZhdWx0TG9nZ2VyID0gbG9nZ2VyO1xufVxuLyoqXG4gKiBMb2cgYW55dGhpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZyguLi5hcmdzKSB7XG4gICAgZGVmYXVsdExvZ2dlci5sb2coLi4uYXJncyk7XG59XG4vKipcbiAqIFdhcm4gYW55dGhpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdhcm4oLi4uYXJncykge1xuICAgIGRlZmF1bHRMb2dnZXIud2FybiguLi5hcmdzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlYnVnLmpzLm1hcCIsIi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIHVuZGVmaW5lZFxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNVbmRlZihhcmcpIHtcbiAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gXCJ1bmRlZmluZWRcIjtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIG5vdCB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVmaW5lZChhcmcpIHtcbiAgICByZXR1cm4gIWlzVW5kZWYoYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJnIGlzIGEgZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBhcmcgPT09IFwiZnVuY3Rpb25cIjtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBudW1iZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWJlcihhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwibnVtYmVyXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBnaXZlbiBhcmd1bWVudCBpcyBhbiBvYmplY3QgbGl0ZXJhbCAoaS5lLiBge31gKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0KGFyZykge1xuICAgIHJldHVybiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGFyZykgPT09IFwiW29iamVjdCBPYmplY3RdXCIgJiYgYXJnLmNvbnN0cnVjdG9yID09PSBPYmplY3QpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBhIGJvb2xlYW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Jvb2xlYW4oYXJnKSB7XG4gICAgcmV0dXJuICh0eXBlb2YgYXJnID09PSBcImJvb2xlYW5cIik7XG59XG4vKipcbiAqIFRlc3QgaWYgdGhlIGFyZ3VtZW50IGlzIGFuIEFycmF5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICAgIHJldHVybiAoQXJyYXkuaXNBcnJheShhcmcpKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgYXJndW1lbnQgaXMgYSBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N0cmluZyhhcmcpIHtcbiAgICByZXR1cm4gKHR5cGVvZiBhcmcgPT09IFwic3RyaW5nXCIpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmd1bWVudCBpcyBpbiB0aGUgZm9ybSBvZiBhIG5vdGUgaW4gc2NpZW50aWZpYyBwaXRjaCBub3RhdGlvbi5cbiAqIGUuZy4gXCJDNFwiXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vdGUoYXJnKSB7XG4gICAgcmV0dXJuIGlzU3RyaW5nKGFyZykgJiYgL14oW2EtZ117MX0oPzpifCN8eHxiYik/KSgtP1swLTldKykvaS50ZXN0KGFyZyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UeXBlQ2hlY2suanMubWFwIiwiaW1wb3J0IHsgQXVkaW9Db250ZXh0IGFzIHN0ZEF1ZGlvQ29udGV4dCwgQXVkaW9Xb3JrbGV0Tm9kZSBhcyBzdGRBdWRpb1dvcmtsZXROb2RlLCBPZmZsaW5lQXVkaW9Db250ZXh0IGFzIHN0ZE9mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwic3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogQ3JlYXRlIGEgbmV3IEF1ZGlvQ29udGV4dFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXVkaW9Db250ZXh0KG9wdGlvbnMpIHtcbiAgICByZXR1cm4gbmV3IHN0ZEF1ZGlvQ29udGV4dChvcHRpb25zKTtcbn1cbi8qKlxuICogQ3JlYXRlIGEgbmV3IE9mZmxpbmVBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU9mZmxpbmVBdWRpb0NvbnRleHQoY2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSkge1xuICAgIHJldHVybiBuZXcgc3RkT2ZmbGluZUF1ZGlvQ29udGV4dChjaGFubmVscywgbGVuZ3RoLCBzYW1wbGVSYXRlKTtcbn1cbi8qKlxuICogQSByZWZlcmVuY2UgdG8gdGhlIHdpbmRvdyBvYmplY3RcbiAqIEBoaWRkZW5cbiAqL1xuZXhwb3J0IGNvbnN0IHRoZVdpbmRvdyA9IHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiID8gc2VsZiA6IG51bGw7XG4vKipcbiAqIElmIHRoZSBicm93c2VyIGhhcyBhIHdpbmRvdyBvYmplY3Qgd2hpY2ggaGFzIGFuIEF1ZGlvQ29udGV4dFxuICogQGhpZGRlblxuICovXG5leHBvcnQgY29uc3QgaGFzQXVkaW9Db250ZXh0ID0gdGhlV2luZG93ICYmXG4gICAgKHRoZVdpbmRvdy5oYXNPd25Qcm9wZXJ0eShcIkF1ZGlvQ29udGV4dFwiKSB8fCB0aGVXaW5kb3cuaGFzT3duUHJvcGVydHkoXCJ3ZWJraXRBdWRpb0NvbnRleHRcIikpO1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUoY29udGV4dCwgbmFtZSwgb3B0aW9ucykge1xuICAgIGFzc2VydChpc0RlZmluZWQoc3RkQXVkaW9Xb3JrbGV0Tm9kZSksIFwiVGhpcyBub2RlIG9ubHkgd29ya3MgaW4gYSBzZWN1cmUgY29udGV4dCAoaHR0cHMgb3IgbG9jYWxob3N0KVwiKTtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIG5ldyBzdGRBdWRpb1dvcmtsZXROb2RlKGNvbnRleHQsIG5hbWUsIG9wdGlvbnMpO1xufVxuLyoqXG4gKiBUaGlzIHByb21pc2UgcmVzb2x2ZXMgdG8gYSBib29sZWFuIHdoaWNoIGluZGljYXRlcyBpZiB0aGVcbiAqIGZ1bmN0aW9uYWxpdHkgaXMgc3VwcG9ydGVkIHdpdGhpbiB0aGUgY3VycmVudGx5IHVzZWQgYnJvd3NlLlxuICogVGFrZW4gZnJvbSBbc3RhbmRhcmRpemVkLWF1ZGlvLWNvbnRleHRdKGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc2d1dHRhbmRpbi9zdGFuZGFyZGl6ZWQtYXVkaW8tY29udGV4dCNpc3N1cHBvcnRlZClcbiAqL1xuZXhwb3J0IHsgaXNTdXBwb3J0ZWQgYXMgc3VwcG9ydGVkIH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdWRpb0NvbnRleHQuanMubWFwIiwiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2VzRGVjb3JhdGUoY3RvciwgZGVzY3JpcHRvckluLCBkZWNvcmF0b3JzLCBjb250ZXh0SW4sIGluaXRpYWxpemVycywgZXh0cmFJbml0aWFsaXplcnMpIHtcclxuICAgIGZ1bmN0aW9uIGFjY2VwdChmKSB7IGlmIChmICE9PSB2b2lkIDAgJiYgdHlwZW9mIGYgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZ1bmN0aW9uIGV4cGVjdGVkXCIpOyByZXR1cm4gZjsgfVxyXG4gICAgdmFyIGtpbmQgPSBjb250ZXh0SW4ua2luZCwga2V5ID0ga2luZCA9PT0gXCJnZXR0ZXJcIiA/IFwiZ2V0XCIgOiBraW5kID09PSBcInNldHRlclwiID8gXCJzZXRcIiA6IFwidmFsdWVcIjtcclxuICAgIHZhciB0YXJnZXQgPSAhZGVzY3JpcHRvckluICYmIGN0b3IgPyBjb250ZXh0SW5bXCJzdGF0aWNcIl0gPyBjdG9yIDogY3Rvci5wcm90b3R5cGUgOiBudWxsO1xyXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBkZXNjcmlwdG9ySW4gfHwgKHRhcmdldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBjb250ZXh0SW4ubmFtZSkgOiB7fSk7XHJcbiAgICB2YXIgXywgZG9uZSA9IGZhbHNlO1xyXG4gICAgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcclxuICAgICAgICB2YXIgY29udGV4dCA9IHt9O1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluKSBjb250ZXh0W3BdID0gcCA9PT0gXCJhY2Nlc3NcIiA/IHt9IDogY29udGV4dEluW3BdO1xyXG4gICAgICAgIGZvciAodmFyIHAgaW4gY29udGV4dEluLmFjY2VzcykgY29udGV4dC5hY2Nlc3NbcF0gPSBjb250ZXh0SW4uYWNjZXNzW3BdO1xyXG4gICAgICAgIGNvbnRleHQuYWRkSW5pdGlhbGl6ZXIgPSBmdW5jdGlvbiAoZikgeyBpZiAoZG9uZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBhZGQgaW5pdGlhbGl6ZXJzIGFmdGVyIGRlY29yYXRpb24gaGFzIGNvbXBsZXRlZFwiKTsgZXh0cmFJbml0aWFsaXplcnMucHVzaChhY2NlcHQoZiB8fCBudWxsKSk7IH07XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9ICgwLCBkZWNvcmF0b3JzW2ldKShraW5kID09PSBcImFjY2Vzc29yXCIgPyB7IGdldDogZGVzY3JpcHRvci5nZXQsIHNldDogZGVzY3JpcHRvci5zZXQgfSA6IGRlc2NyaXB0b3Jba2V5XSwgY29udGV4dCk7XHJcbiAgICAgICAgaWYgKGtpbmQgPT09IFwiYWNjZXNzb3JcIikge1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSB2b2lkIDApIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHR5cGVvZiByZXN1bHQgIT09IFwib2JqZWN0XCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJPYmplY3QgZXhwZWN0ZWRcIik7XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5nZXQpKSBkZXNjcmlwdG9yLmdldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5zZXQpKSBkZXNjcmlwdG9yLnNldCA9IF87XHJcbiAgICAgICAgICAgIGlmIChfID0gYWNjZXB0KHJlc3VsdC5pbml0KSkgaW5pdGlhbGl6ZXJzLnB1c2goXyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKF8gPSBhY2NlcHQocmVzdWx0KSkge1xyXG4gICAgICAgICAgICBpZiAoa2luZCA9PT0gXCJmaWVsZFwiKSBpbml0aWFsaXplcnMucHVzaChfKTtcclxuICAgICAgICAgICAgZWxzZSBkZXNjcmlwdG9yW2tleV0gPSBfO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0YXJnZXQpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGNvbnRleHRJbi5uYW1lLCBkZXNjcmlwdG9yKTtcclxuICAgIGRvbmUgPSB0cnVlO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcnVuSW5pdGlhbGl6ZXJzKHRoaXNBcmcsIGluaXRpYWxpemVycywgdmFsdWUpIHtcclxuICAgIHZhciB1c2VWYWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPiAyO1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0aWFsaXplcnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICB2YWx1ZSA9IHVzZVZhbHVlID8gaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZywgdmFsdWUpIDogaW5pdGlhbGl6ZXJzW2ldLmNhbGwodGhpc0FyZyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdXNlVmFsdWUgPyB2YWx1ZSA6IHZvaWQgMDtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3Byb3BLZXkoeCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN5bWJvbFwiID8geCA6IFwiXCIuY29uY2F0KHgpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc2V0RnVuY3Rpb25OYW1lKGYsIG5hbWUsIHByZWZpeCkge1xyXG4gICAgaWYgKHR5cGVvZiBuYW1lID09PSBcInN5bWJvbFwiKSBuYW1lID0gbmFtZS5kZXNjcmlwdGlvbiA/IFwiW1wiLmNvbmNhdChuYW1lLmRlc2NyaXB0aW9uLCBcIl1cIikgOiBcIlwiO1xyXG4gICAgcmV0dXJuIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShmLCBcIm5hbWVcIiwgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiBwcmVmaXggPyBcIlwiLmNvbmNhdChwcmVmaXgsIFwiIFwiLCBuYW1lKSA6IG5hbWUgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxyXG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gZnVsZmlsbGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yLm5leHQodmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxyXG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XHJcbiAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2dlbmVyYXRvcih0aGlzQXJnLCBib2R5KSB7XHJcbiAgICB2YXIgXyA9IHsgbGFiZWw6IDAsIHNlbnQ6IGZ1bmN0aW9uKCkgeyBpZiAodFswXSAmIDEpIHRocm93IHRbMV07IHJldHVybiB0WzFdOyB9LCB0cnlzOiBbXSwgb3BzOiBbXSB9LCBmLCB5LCB0LCBnO1xyXG4gICAgcmV0dXJuIGcgPSB7IG5leHQ6IHZlcmIoMCksIFwidGhyb3dcIjogdmVyYigxKSwgXCJyZXR1cm5cIjogdmVyYigyKSB9LCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBmYWxzZSB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcclxuICAgIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRJbihzdGF0ZSwgcmVjZWl2ZXIpIHtcclxuICAgIGlmIChyZWNlaXZlciA9PT0gbnVsbCB8fCAodHlwZW9mIHJlY2VpdmVyICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZWNlaXZlciAhPT0gXCJmdW5jdGlvblwiKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB1c2UgJ2luJyBvcGVyYXRvciBvbiBub24tb2JqZWN0XCIpO1xyXG4gICAgcmV0dXJuIHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgPT09IHN0YXRlIDogc3RhdGUuaGFzKHJlY2VpdmVyKTtcclxufVxyXG4iLCIvKipcbiAqIEEgY2xhc3Mgd2hpY2ggcHJvdmlkZXMgYSByZWxpYWJsZSBjYWxsYmFjayB1c2luZyBlaXRoZXJcbiAqIGEgV2ViIFdvcmtlciwgb3IgaWYgdGhhdCBpc24ndCBzdXBwb3J0ZWQsIGZhbGxzIGJhY2sgdG8gc2V0VGltZW91dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tlciB7XG4gICAgY29uc3RydWN0b3IoY2FsbGJhY2ssIHR5cGUsIHVwZGF0ZUludGVydmFsKSB7XG4gICAgICAgIHRoaXMuX2NhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl91cGRhdGVJbnRlcnZhbCA9IHVwZGF0ZUludGVydmFsO1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGNsb2NrIHNvdXJjZSBmb3IgdGhlIGZpcnN0IHRpbWVcbiAgICAgICAgdGhpcy5fY3JlYXRlQ2xvY2soKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgYSB3ZWIgd29ya2VyXG4gICAgICovXG4gICAgX2NyZWF0ZVdvcmtlcigpIHtcbiAgICAgICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtcbiAgICAgICAgICAgIC8qIGphdmFzY3JpcHQgKi8gYFxuXHRcdFx0Ly8gdGhlIGluaXRpYWwgdGltZW91dCB0aW1lXG5cdFx0XHRsZXQgdGltZW91dFRpbWUgPSAgJHsodGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKS50b0ZpeGVkKDEpfTtcblx0XHRcdC8vIG9ubWVzc2FnZSBjYWxsYmFja1xuXHRcdFx0c2VsZi5vbm1lc3NhZ2UgPSBmdW5jdGlvbihtc2cpe1xuXHRcdFx0XHR0aW1lb3V0VGltZSA9IHBhcnNlSW50KG1zZy5kYXRhKTtcblx0XHRcdH07XG5cdFx0XHQvLyB0aGUgdGljayBmdW5jdGlvbiB3aGljaCBwb3N0cyBhIG1lc3NhZ2Vcblx0XHRcdC8vIGFuZCBzY2hlZHVsZXMgYSBuZXcgdGlja1xuXHRcdFx0ZnVuY3Rpb24gdGljaygpe1xuXHRcdFx0XHRzZXRUaW1lb3V0KHRpY2ssIHRpbWVvdXRUaW1lKTtcblx0XHRcdFx0c2VsZi5wb3N0TWVzc2FnZSgndGljaycpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gY2FsbCB0aWNrIGluaXRpYWxseVxuXHRcdFx0dGljaygpO1xuXHRcdFx0YFxuICAgICAgICBdLCB7IHR5cGU6IFwidGV4dC9qYXZhc2NyaXB0XCIgfSk7XG4gICAgICAgIGNvbnN0IGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKGJsb2IpO1xuICAgICAgICBjb25zdCB3b3JrZXIgPSBuZXcgV29ya2VyKGJsb2JVcmwpO1xuICAgICAgICB3b3JrZXIub25tZXNzYWdlID0gdGhpcy5fY2FsbGJhY2suYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5fd29ya2VyID0gd29ya2VyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSB0aW1lb3V0IGxvb3BcbiAgICAgKi9cbiAgICBfY3JlYXRlVGltZW91dCgpIHtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlVGltZW91dCgpO1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2soKTtcbiAgICAgICAgfSwgdGhpcy5fdXBkYXRlSW50ZXJ2YWwgKiAxMDAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHRoZSBjbG9jayBzb3VyY2UuXG4gICAgICovXG4gICAgX2NyZWF0ZUNsb2NrKCkge1xuICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3b3JrZXJcIikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jcmVhdGVXb3JrZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gd29ya2VycyBub3Qgc3VwcG9ydGVkLCBmYWxsYmFjayB0byB0aW1lb3V0XG4gICAgICAgICAgICAgICAgdGhpcy5fdHlwZSA9IFwidGltZW91dFwiO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJ0aW1lb3V0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZVRpbWVvdXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cCB0aGUgY3VycmVudCBjbG9jayBzb3VyY2VcbiAgICAgKi9cbiAgICBfZGlzcG9zZUNsb2NrKCkge1xuICAgICAgICBpZiAodGhpcy5fdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgICAgICAgICAgdGhpcy5fdGltZW91dCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3dvcmtlcikge1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLnRlcm1pbmF0ZSgpO1xuICAgICAgICAgICAgdGhpcy5fd29ya2VyLm9ubWVzc2FnZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHJhdGUgaW4gc2Vjb25kcyB0aGUgdGlja2VyIHdpbGwgdXBkYXRlXG4gICAgICovXG4gICAgZ2V0IHVwZGF0ZUludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdXBkYXRlSW50ZXJ2YWw7XG4gICAgfVxuICAgIHNldCB1cGRhdGVJbnRlcnZhbChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl91cGRhdGVJbnRlcnZhbCA9IE1hdGgubWF4KGludGVydmFsLCAxMjggLyA0NDEwMCk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcIndvcmtlclwiKSB7XG4gICAgICAgICAgICB0aGlzLl93b3JrZXIucG9zdE1lc3NhZ2UoTWF0aC5tYXgoaW50ZXJ2YWwgKiAxMDAwLCAxKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIHRpY2tlciwgZWl0aGVyIGEgd29ya2VyIG9yIGEgdGltZW91dFxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9kaXNwb3NlQ2xvY2soKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2NyZWF0ZUNsb2NrKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZUNsb2NrKCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja2VyLmpzLm1hcCIsImltcG9ydCB7IGlzQW55QXVkaW9Db250ZXh0LCBpc0FueUF1ZGlvTm9kZSwgaXNBbnlBdWRpb1BhcmFtLCBpc0FueU9mZmxpbmVBdWRpb0NvbnRleHQsIH0gZnJvbSBcInN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XCI7XG4vKipcbiAqIFRlc3QgaWYgdGhlIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlb2YgQXVkaW9QYXJhbVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb1BhcmFtKGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvUGFyYW0oYXJnKTtcbn1cbi8qKlxuICogVGVzdCBpZiB0aGUgZ2l2ZW4gdmFsdWUgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb05vZGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9Ob2RlKGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvTm9kZShhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgaW5zdGFuY2VvZiBhbiBPZmZsaW5lQXVkaW9Db250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJnKSB7XG4gICAgcmV0dXJuIGlzQW55T2ZmbGluZUF1ZGlvQ29udGV4dChhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgYW4gaW5zdGFuY2VvZiBBdWRpb0NvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXVkaW9Db250ZXh0KGFyZykge1xuICAgIHJldHVybiBpc0FueUF1ZGlvQ29udGV4dChhcmcpO1xufVxuLyoqXG4gKiBUZXN0IGlmIHRoZSBhcmcgaXMgaW5zdGFuY2VvZiBhbiBBdWRpb0J1ZmZlclxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBdWRpb0J1ZmZlcihhcmcpIHtcbiAgICByZXR1cm4gYXJnIGluc3RhbmNlb2YgQXVkaW9CdWZmZXI7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BZHZhbmNlZFR5cGVDaGVjay5qcy5tYXAiLCJpbXBvcnQgeyBpc0F1ZGlvQnVmZmVyLCBpc0F1ZGlvTm9kZSwgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4vQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCwgaXNPYmplY3QsIGlzVW5kZWYgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogU29tZSBvYmplY3RzIHNob3VsZCBub3QgYmUgbWVyZ2VkXG4gKi9cbmZ1bmN0aW9uIG5vQ29weShrZXksIGFyZykge1xuICAgIHJldHVybiBrZXkgPT09IFwidmFsdWVcIiB8fCBpc0F1ZGlvUGFyYW0oYXJnKSB8fCBpc0F1ZGlvTm9kZShhcmcpIHx8IGlzQXVkaW9CdWZmZXIoYXJnKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBkZWVwTWVyZ2UodGFyZ2V0LCAuLi5zb3VyY2VzKSB7XG4gICAgaWYgKCFzb3VyY2VzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgaWYgKGlzT2JqZWN0KHRhcmdldCkgJiYgaXNPYmplY3Qoc291cmNlKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmIChub0NvcHkoa2V5LCBzb3VyY2Vba2V5XSkpIHtcbiAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNPYmplY3Qoc291cmNlW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXRba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRhcmdldCwgeyBba2V5XToge30gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZXBNZXJnZSh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHsgW2tleV06IHNvdXJjZVtrZXldIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gZGVlcE1lcmdlKHRhcmdldCwgLi4uc291cmNlcyk7XG59XG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgdHdvIGFycmF5cyBoYXZlIHRoZSBzYW1lIHZhbHVlIGZvciBlYWNoIG9mIHRoZSBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZGVlcEVxdWFscyhhcnJheUEsIGFycmF5Qikge1xuICAgIHJldHVybiBhcnJheUEubGVuZ3RoID09PSBhcnJheUIubGVuZ3RoICYmIGFycmF5QS5ldmVyeSgoZWxlbWVudCwgaW5kZXgpID0+IGFycmF5QltpbmRleF0gPT09IGVsZW1lbnQpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGFuIGFyZ3MgYXJyYXkgaW50byBhbiBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvcHRpb25zRnJvbUFyZ3VtZW50cyhkZWZhdWx0cywgYXJnc0FycmF5LCBrZXlzID0gW10sIG9iaktleSkge1xuICAgIGNvbnN0IG9wdHMgPSB7fTtcbiAgICBjb25zdCBhcmdzID0gQXJyYXkuZnJvbShhcmdzQXJyYXkpO1xuICAgIC8vIGlmIHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhbiBvYmplY3QgYW5kIGhhcyBhbiBvYmplY3Qga2V5XG4gICAgaWYgKGlzT2JqZWN0KGFyZ3NbMF0pICYmIG9iaktleSAmJiAhUmVmbGVjdC5oYXMoYXJnc1swXSwgb2JqS2V5KSkge1xuICAgICAgICAvLyBpZiBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBkZWZhdWx0c1xuICAgICAgICBjb25zdCBwYXJ0T2ZEZWZhdWx0cyA9IE9iamVjdC5rZXlzKGFyZ3NbMF0pLnNvbWUoa2V5ID0+IFJlZmxlY3QuaGFzKGRlZmF1bHRzLCBrZXkpKTtcbiAgICAgICAgaWYgKCFwYXJ0T2ZEZWZhdWx0cykge1xuICAgICAgICAgICAgLy8gbWVyZ2UgdGhhdCBrZXlcbiAgICAgICAgICAgIGRlZXBNZXJnZShvcHRzLCB7IFtvYmpLZXldOiBhcmdzWzBdIH0pO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBvYmoga2V5IGZyb20gdGhlIGtleXNcbiAgICAgICAgICAgIGtleXMuc3BsaWNlKGtleXMuaW5kZXhPZihvYmpLZXkpLCAxKTtcbiAgICAgICAgICAgIC8vIHNoaWZ0IHRoZSBmaXJzdCBhcmd1bWVudCBvZmZcbiAgICAgICAgICAgIGFyZ3Muc2hpZnQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNPYmplY3QoYXJnc1swXSkpIHtcbiAgICAgICAgZGVlcE1lcmdlKG9wdHMsIGFyZ3NbMF0pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKGFyZ3NbaV0pKSB7XG4gICAgICAgICAgICAgICAgb3B0c1trZXlzW2ldXSA9IGFyZ3NbaV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlZXBNZXJnZShkZWZhdWx0cywgb3B0cyk7XG59XG4vKipcbiAqIFJldHVybiB0aGlzIGluc3RhbmNlcyBkZWZhdWx0IHZhbHVlcyBieSBjYWxsaW5nIENvbnN0cnVjdG9yLmdldERlZmF1bHRzKClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRzRnJvbUluc3RhbmNlKGluc3RhbmNlKSB7XG4gICAgcmV0dXJuIGluc3RhbmNlLmNvbnN0cnVjdG9yLmdldERlZmF1bHRzKCk7XG59XG4vKipcbiAqIFJldHVybnMgdGhlIGZhbGxiYWNrIGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgdW5kZWZpbmVkLlxuICogVGFrZSBhbiBhcnJheSBvZiBhcmd1bWVudHMgYW5kIHJldHVybiBhIGZvcm1hdHRlZCBvcHRpb25zIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRBcmcoZ2l2ZW4sIGZhbGxiYWNrKSB7XG4gICAgaWYgKGlzVW5kZWYoZ2l2ZW4pKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBnaXZlbjtcbiAgICB9XG59XG4vKipcbiAqIFJlbW92ZSBhbGwgb2YgdGhlIHByb3BlcnRpZXMgYmVsb25naW5nIHRvIG9taXQgZnJvbSBvYmouXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbWl0RnJvbU9iamVjdChvYmosIG9taXQpIHtcbiAgICBvbWl0LmZvckVhY2gocHJvcCA9PiB7XG4gICAgICAgIGlmIChSZWZsZWN0LmhhcyhvYmosIHByb3ApKSB7XG4gICAgICAgICAgICBkZWxldGUgb2JqW3Byb3BdO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG9iajtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlZmF1bHRzLmpzLm1hcCIsIi8qKlxuICogVG9uZS5qc1xuICogQGF1dGhvciBZb3RhbSBNYW5uXG4gKiBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiBAY29weXJpZ2h0IDIwMTQtMjAxOSBZb3RhbSBNYW5uXG4gKi9cbmltcG9ydCB7IHZlcnNpb24gfSBmcm9tIFwiLi4vdmVyc2lvblwiO1xuaW1wb3J0IHsgdGhlV2luZG93IH0gZnJvbSBcIi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCIuL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQGNsYXNzICBUb25lIGlzIHRoZSBiYXNlIGNsYXNzIG9mIGFsbCBvdGhlciBjbGFzc2VzLlxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5leHBvcnQgY2xhc3MgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdERFQlVHR0lOR1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldCB0aGlzIGRlYnVnIGZsYWcgdG8gbG9nIGFsbCBldmVudHMgdGhhdCBoYXBwZW4gaW4gdGhpcyBjbGFzcy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVidWcgPSBmYWxzZTtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8vIFx0RElTUE9TSU5HXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvKipcbiAgICAgICAgICogSW5kaWNhdGVzIGlmIHRoZSBpbnN0YW5jZSB3YXMgZGlzcG9zZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3dhc0Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYWxsIG9mIHRoZSBkZWZhdWx0IG9wdGlvbnMgYmVsb25naW5nIHRvIHRoZSBjbGFzcy5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUHJpbnRzIHRoZSBvdXRwdXRzIHRvIHRoZSBjb25zb2xlIGxvZyBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLlxuICAgICAqIFByaW50cyB0aGUgY29udGVudHMgb25seSBpZiBlaXRoZXIgdGhlIG9iamVjdCBoYXMgYSBwcm9wZXJ0eVxuICAgICAqIGNhbGxlZCBgZGVidWdgIHNldCB0byB0cnVlLCBvciBhIHZhcmlhYmxlIGNhbGxlZCBUT05FX0RFQlVHX0NMQVNTXG4gICAgICogaXMgc2V0IHRvIHRoZSBuYW1lIG9mIHRoZSBjbGFzcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiAvLyBwcmludHMgYWxsIGxvZ3Mgb3JpZ2luYXRpbmcgZnJvbSB0aGlzIG9zY2lsbGF0b3JcbiAgICAgKiBvc2MuZGVidWcgPSB0cnVlO1xuICAgICAqIC8vIGNhbGxzIHRvIHN0YXJ0L3N0b3Agd2lsbCBwcmludCBpbiB0aGUgY29uc29sZVxuICAgICAqIG9zYy5zdGFydCgpO1xuICAgICAqL1xuICAgIGxvZyguLi5hcmdzKSB7XG4gICAgICAgIC8vIGlmIHRoZSBvYmplY3QgaXMgZWl0aGVyIHNldCB0byBkZWJ1ZyA9IHRydWVcbiAgICAgICAgLy8gb3IgaWYgdGhlcmUgaXMgYSBzdHJpbmcgb24gdGhlIFRvbmUuZ2xvYmFsLndpdGggdGhlIGNsYXNzIG5hbWVcbiAgICAgICAgaWYgKHRoaXMuZGVidWcgfHwgKHRoZVdpbmRvdyAmJiB0aGlzLnRvU3RyaW5nKCkgPT09IHRoZVdpbmRvdy5UT05FX0RFQlVHX0NMQVNTKSkge1xuICAgICAgICAgICAgbG9nKHRoaXMsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGRpc2Nvbm5lY3QgYW5kIGRpc3Bvc2UuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5fd2FzRGlzcG9zZWQgPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIGlmIHRoZSBpbnN0YW5jZSB3YXMgZGlzcG9zZWQuICdEaXNwb3NpbmcnIGFuXG4gICAgICogaW5zdGFuY2UgbWVhbnMgdGhhdCBhbGwgb2YgdGhlIFdlYiBBdWRpbyBub2RlcyB0aGF0IHdlcmVcbiAgICAgKiBjcmVhdGVkIGZvciB0aGUgaW5zdGFuY2UgYXJlIGRpc2Nvbm5lY3RlZCBhbmQgZnJlZWQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgZGlzcG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93YXNEaXNwb3NlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgY2xhc3MgdG8gYSBzdHJpbmdcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvc2MudG9TdHJpbmcoKSk7XG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5hbWU7XG4gICAgfVxufVxuLyoqXG4gKiBUaGUgdmVyc2lvbiBudW1iZXIgc2VtdmVyXG4gKi9cblRvbmUudmVyc2lvbiA9IHZlcnNpb247XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lLmpzLm1hcCIsIi8qKlxuICogVGhlIHRocmVzaG9sZCBmb3IgY29ycmVjdG5lc3MgZm9yIG9wZXJhdG9ycy4gTGVzcyB0aGFuIG9uZSBzYW1wbGUgZXZlblxuICogYXQgdmVyeSBoaWdoIHNhbXBsaW5nIHJhdGVzIChlLmcuIGAxZS02IDwgMSAvIDE5MjAwMGApLlxuICovXG5jb25zdCBFUFNJTE9OID0gMWUtNjtcbi8qKlxuICogVGVzdCBpZiBBIGlzIGdyZWF0ZXIgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHVChhLCBiKSB7XG4gICAgcmV0dXJuIGEgPiBiICsgRVBTSUxPTjtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBHVEUoYSwgYikge1xuICAgIHJldHVybiBHVChhLCBiKSB8fCBFUShhLCBiKTtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGxlc3MgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMVChhLCBiKSB7XG4gICAgcmV0dXJuIGEgKyBFUFNJTE9OIDwgYjtcbn1cbi8qKlxuICogVGVzdCBpZiBBIGlzIGxlc3MgdGhhbiBCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFUShhLCBiKSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKGEgLSBiKSA8IEVQU0lMT047XG59XG4vKipcbiAqIENsYW1wIHRoZSB2YWx1ZSB3aXRoaW4gdGhlIGdpdmVuIHJhbmdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbGFtcCh2YWx1ZSwgbWluLCBtYXgpIHtcbiAgICByZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4odmFsdWUsIG1heCksIG1pbik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NYXRoLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4vRGVidWdcIjtcbmltcG9ydCB7IEVRLCBHVCwgR1RFLCBMVCB9IGZyb20gXCIuL01hdGhcIjtcbi8qKlxuICogQSBUaW1lbGluZSBjbGFzcyBmb3Igc2NoZWR1bGluZyBhbmQgbWFpbnRhaW5pbmcgc3RhdGVcbiAqIGFsb25nIGEgdGltZWxpbmUuIEFsbCBldmVudHMgbXVzdCBoYXZlIGEgXCJ0aW1lXCIgcHJvcGVydHkuXG4gKiBJbnRlcm5hbGx5LCBldmVudHMgYXJlIHN0b3JlZCBpbiB0aW1lIG9yZGVyIGZvciBmYXN0XG4gKiByZXRyaWV2YWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lbGluZSBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVsaW5lXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXJyYXkgb2Ygc2NoZWR1bGVkIHRpbWVsaW5lIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpbWVsaW5lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWVtb3J5XCJdKTtcbiAgICAgICAgdGhpcy5tZW1vcnkgPSBvcHRpb25zLm1lbW9yeTtcbiAgICAgICAgdGhpcy5pbmNyZWFzaW5nID0gb3B0aW9ucy5pbmNyZWFzaW5nO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBtZW1vcnk6IEluZmluaXR5LFxuICAgICAgICAgICAgaW5jcmVhc2luZzogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEluc2VydCBhbiBldmVudCBvYmplY3Qgb250byB0aGUgdGltZWxpbmUuIEV2ZW50cyBtdXN0IGhhdmUgYSBcInRpbWVcIiBhdHRyaWJ1dGUuXG4gICAgICogQHBhcmFtIGV2ZW50ICBUaGUgZXZlbnQgb2JqZWN0IHRvIGluc2VydCBpbnRvIHRoZSB0aW1lbGluZS5cbiAgICAgKi9cbiAgICBhZGQoZXZlbnQpIHtcbiAgICAgICAgLy8gdGhlIGV2ZW50IG5lZWRzIHRvIGhhdmUgYSB0aW1lIGF0dHJpYnV0ZVxuICAgICAgICBhc3NlcnQoUmVmbGVjdC5oYXMoZXZlbnQsIFwidGltZVwiKSwgXCJUaW1lbGluZTogZXZlbnRzIG11c3QgaGF2ZSBhIHRpbWUgYXR0cmlidXRlXCIpO1xuICAgICAgICBldmVudC50aW1lID0gZXZlbnQudGltZS52YWx1ZU9mKCk7XG4gICAgICAgIGlmICh0aGlzLmluY3JlYXNpbmcgJiYgdGhpcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnN0IGxhc3RWYWx1ZSA9IHRoaXMuX3RpbWVsaW5lW3RoaXMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICBhc3NlcnQoR1RFKGV2ZW50LnRpbWUsIGxhc3RWYWx1ZS50aW1lKSwgXCJUaGUgdGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUgbGFzdCBzY2hlZHVsZWQgdGltZVwiKTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnB1c2goZXZlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9zZWFyY2goZXZlbnQudGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXggKyAxLCAwLCBldmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgdGhlIGxlbmd0aCBpcyBtb3JlIHRoYW4gdGhlIG1lbW9yeSwgcmVtb3ZlIHRoZSBwcmV2aW91cyBvbmVzXG4gICAgICAgIGlmICh0aGlzLmxlbmd0aCA+IHRoaXMubWVtb3J5KSB7XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gdGhpcy5sZW5ndGggLSB0aGlzLm1lbW9yeTtcbiAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lLnNwbGljZSgwLCBkaWZmKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGZyb20gdGhlIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIGV2ZW50ICBUaGUgZXZlbnQgb2JqZWN0IHRvIHJlbW92ZSBmcm9tIHRoZSBsaXN0LlxuICAgICAqIEByZXR1cm5zIHtUaW1lbGluZX0gdGhpc1xuICAgICAqL1xuICAgIHJlbW92ZShldmVudCkge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3RpbWVsaW5lLmluZGV4T2YoZXZlbnQpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl90aW1lbGluZS5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIG5lYXJlc3QgZXZlbnQgd2hvc2UgdGltZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXQodGltZSwgcGFyYW0gPSBcInRpbWVcIikge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lLCBwYXJhbSk7XG4gICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtpbmRleF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGZpcnN0IGV2ZW50IGluIHRoZSB0aW1lbGluZSB3aXRob3V0IHJlbW92aW5nIGl0XG4gICAgICogQHJldHVybnMge09iamVjdH0gVGhlIGZpcnN0IGV2ZW50IG9iamVjdFxuICAgICAqL1xuICAgIHBlZWsoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVswXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBmaXJzdCBldmVudCBpbiB0aGUgdGltZWxpbmUgYW5kIHJlbW92ZSBpdFxuICAgICAqL1xuICAgIHNoaWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmUuc2hpZnQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBldmVudCB3aGljaCBpcyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRBZnRlcih0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUsIHBhcmFtKTtcbiAgICAgICAgaWYgKGluZGV4ICsgMSA8IHRoaXMuX3RpbWVsaW5lLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4ICsgMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGV2ZW50IGJlZm9yZSB0aGUgZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRCZWZvcmUodGltZSkge1xuICAgICAgICBjb25zdCBsZW4gPSB0aGlzLl90aW1lbGluZS5sZW5ndGg7XG4gICAgICAgIC8vIGlmIGl0J3MgYWZ0ZXIgdGhlIGxhc3QgaXRlbSwgcmV0dXJuIHRoZSBsYXN0IGl0ZW1cbiAgICAgICAgaWYgKGxlbiA+IDAgJiYgdGhpcy5fdGltZWxpbmVbbGVuIC0gMV0udGltZSA8IHRpbWUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKGluZGV4IC0gMSA+PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdGltZWxpbmVbaW5kZXggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgYXQgYW5kIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLl9zZWFyY2goYWZ0ZXIpO1xuICAgICAgICAgICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAoRVEodGhpcy5fdGltZWxpbmVbaW5kZXhdLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGZpcnN0IGl0ZW0gd2l0aCB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGluZGV4OyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2ldLnRpbWUsIGFmdGVyKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gdGhpcy5fdGltZWxpbmUuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZSgwLCBpbmRleCArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVsaW5lID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdGltZWxpbmUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICAvLyB0aGUgZmlyc3QgaXRlbSdzIHRpbWVcbiAgICAgICAgICAgIGlmIChHVEUodGhpcy5fdGltZWxpbmVbMF0udGltZSwgYWZ0ZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGV2ZW50cyBiZWZvcmUgb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBjYW5jZWwgYmVmb3JlLlxuICAgICAqL1xuICAgIGNhbmNlbEJlZm9yZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdGhpcy5fdGltZWxpbmUgPSB0aGlzLl90aW1lbGluZS5zbGljZShpbmRleCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwcmV2aW91cyBldmVudCBpZiB0aGVyZSBpcyBvbmUuIG51bGwgb3RoZXJ3aXNlXG4gICAgICogQHBhcmFtICBldmVudCBUaGUgZXZlbnQgdG8gZmluZCB0aGUgcHJldmlvdXMgb25lIG9mXG4gICAgICogQHJldHVybiBUaGUgZXZlbnQgcmlnaHQgYmVmb3JlIHRoZSBnaXZlbiBldmVudFxuICAgICAqL1xuICAgIHByZXZpb3VzRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl90aW1lbGluZS5pbmRleE9mKGV2ZW50KTtcbiAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVsaW5lW2luZGV4IC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEb2VzIGEgYmluYXJ5IHNlYXJjaCBvbiB0aGUgdGltZWxpbmUgYXJyYXkgYW5kIHJldHVybnMgdGhlXG4gICAgICogbmVhcmVzdCBldmVudCBpbmRleCB3aG9zZSB0aW1lIGlzIGFmdGVyIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIElmIGEgdGltZSBpcyBzZWFyY2hlZCBiZWZvcmUgdGhlIGZpcnN0IGluZGV4IGluIHRoZSB0aW1lbGluZSwgLTEgaXMgcmV0dXJuZWQuXG4gICAgICogSWYgdGhlIHRpbWUgaXMgYWZ0ZXIgdGhlIGVuZCwgdGhlIGluZGV4IG9mIHRoZSBsYXN0IGl0ZW0gaXMgcmV0dXJuZWQuXG4gICAgICovXG4gICAgX3NlYXJjaCh0aW1lLCBwYXJhbSA9IFwidGltZVwiKSB7XG4gICAgICAgIGlmICh0aGlzLl90aW1lbGluZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYmVnaW5uaW5nID0gMDtcbiAgICAgICAgY29uc3QgbGVuID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoO1xuICAgICAgICBsZXQgZW5kID0gbGVuO1xuICAgICAgICBpZiAobGVuID4gMCAmJiB0aGlzLl90aW1lbGluZVtsZW4gLSAxXVtwYXJhbV0gPD0gdGltZSkge1xuICAgICAgICAgICAgcmV0dXJuIGxlbiAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGJlZ2lubmluZyA8IGVuZCkge1xuICAgICAgICAgICAgLy8gY2FsY3VsYXRlIHRoZSBtaWRwb2ludCBmb3Igcm91Z2hseSBlcXVhbCBwYXJ0aXRpb25cbiAgICAgICAgICAgIGxldCBtaWRQb2ludCA9IE1hdGguZmxvb3IoYmVnaW5uaW5nICsgKGVuZCAtIGJlZ2lubmluZykgLyAyKTtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbbWlkUG9pbnRdO1xuICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fdGltZWxpbmVbbWlkUG9pbnQgKyAxXTtcbiAgICAgICAgICAgIGlmIChFUShldmVudFtwYXJhbV0sIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gY2hvb3NlIHRoZSBsYXN0IG9uZSB0aGF0IGhhcyB0aGUgc2FtZSB0aW1lXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IG1pZFBvaW50OyBpIDwgdGhpcy5fdGltZWxpbmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVzdEV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChFUSh0ZXN0RXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWlkUG9pbnQgPSBpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1pZFBvaW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoTFQoZXZlbnRbcGFyYW1dLCB0aW1lKSAmJiBHVChuZXh0RXZlbnRbcGFyYW1dLCB0aW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKEdUKGV2ZW50W3BhcmFtXSwgdGltZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBzZWFyY2ggbG93ZXJcbiAgICAgICAgICAgICAgICBlbmQgPSBtaWRQb2ludDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIHNlYXJjaCB1cHBlclxuICAgICAgICAgICAgICAgIGJlZ2lubmluZyA9IG1pZFBvaW50ICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGl0ZXJhdG9yLiBBcHBsaWVzIGV4dHJhIHNhZmV0eSBjaGVja3MgZm9yXG4gICAgICogcmVtb3ZpbmcgaXRlbXMgZnJvbSB0aGUgYXJyYXkuXG4gICAgICovXG4gICAgX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgPSAwLCB1cHBlckJvdW5kID0gdGhpcy5fdGltZWxpbmUubGVuZ3RoIC0gMSkge1xuICAgICAgICB0aGlzLl90aW1lbGluZS5zbGljZShsb3dlckJvdW5kLCB1cHBlckJvdW5kICsgMSkuZm9yRWFjaChjYWxsYmFjayk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IG9yIGJlZm9yZSB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoQmVmb3JlKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgY29uc3QgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaCh0aW1lKTtcbiAgICAgICAgaWYgKHVwcGVyQm91bmQgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCAwLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hBZnRlcih0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIHRoaXMuX2l0ZXJhdGUoY2FsbGJhY2ssIGxvd2VyQm91bmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBiZXR3ZWVuIHRoZSBzdGFydFRpbWUgYW5kIGVuZFRpbWUuXG4gICAgICogVGhlIHRpbWVyYW5nZSBpcyBpbmNsdXNpdmUgb2YgdGhlIHN0YXJ0VGltZSwgYnV0IGV4Y2x1c2l2ZSBvZiB0aGUgZW5kVGltZS5cbiAgICAgKiByYW5nZSA9IFtzdGFydFRpbWUsIGVuZFRpbWUpLlxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGVuZFRpbWUgVGhlIGVuZCBvZiB0aGUgdGVzdCBpbnRlcnZhbC5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEJldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBjYWxsYmFjaykge1xuICAgICAgICBsZXQgbG93ZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChzdGFydFRpbWUpO1xuICAgICAgICBsZXQgdXBwZXJCb3VuZCA9IHRoaXMuX3NlYXJjaChlbmRUaW1lKTtcbiAgICAgICAgaWYgKGxvd2VyQm91bmQgIT09IC0xICYmIHVwcGVyQm91bmQgIT09IC0xKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fdGltZWxpbmVbbG93ZXJCb3VuZF0udGltZSAhPT0gc3RhcnRUaW1lKSB7XG4gICAgICAgICAgICAgICAgbG93ZXJCb3VuZCArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXhjbHVzaXZlIG9mIHRoZSBlbmQgdGltZVxuICAgICAgICAgICAgaWYgKHRoaXMuX3RpbWVsaW5lW3VwcGVyQm91bmRdLnRpbWUgPT09IGVuZFRpbWUpIHtcbiAgICAgICAgICAgICAgICB1cHBlckJvdW5kIC09IDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9pdGVyYXRlKGNhbGxiYWNrLCBsb3dlckJvdW5kLCB1cHBlckJvdW5kKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChsb3dlckJvdW5kID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgMCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBhdCBvciBhZnRlciB0aGUgZ2l2ZW4gdGltZS4gU2ltaWxhciB0b1xuICAgICAqIGZvckVhY2hBZnRlciwgYnV0IGluY2x1ZGVzIHRoZSBpdGVtKHMpIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgYmVmb3JlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggZXZlcnkgaXRlbVxuICAgICAqL1xuICAgIGZvckVhY2hGcm9tKHRpbWUsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIGl0ZXJhdGUgb3ZlciB0aGUgaXRlbXMgaW4gcmV2ZXJzZSBzbyB0aGF0IHJlbW92aW5nIGFuIGl0ZW0gZG9lc24ndCBicmVhayB0aGluZ3NcbiAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIC8vIHdvcmsgYmFja3dhcmRzIHVudGlsIHRoZSBldmVudCB0aW1lIGlzIGxlc3MgdGhhbiB0aW1lXG4gICAgICAgIHdoaWxlIChsb3dlckJvdW5kID49IDAgJiYgdGhpcy5fdGltZWxpbmVbbG93ZXJCb3VuZF0udGltZSA+PSB0aW1lKSB7XG4gICAgICAgICAgICBsb3dlckJvdW5kLS07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faXRlcmF0ZShjYWxsYmFjaywgbG93ZXJCb3VuZCArIDEpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXRlcmF0ZSBvdmVyIGV2ZXJ5dGhpbmcgaW4gdGhlIGFycmF5IGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGNoZWNrIGlmIGl0ZW1zIGFyZSBiZWZvcmVcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEF0VGltZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBpdGVyYXRlIG92ZXIgdGhlIGl0ZW1zIGluIHJldmVyc2Ugc28gdGhhdCByZW1vdmluZyBhbiBpdGVtIGRvZXNuJ3QgYnJlYWsgdGhpbmdzXG4gICAgICAgIGNvbnN0IHVwcGVyQm91bmQgPSB0aGlzLl9zZWFyY2godGltZSk7XG4gICAgICAgIGlmICh1cHBlckJvdW5kICE9PSAtMSAmJiBFUSh0aGlzLl90aW1lbGluZVt1cHBlckJvdW5kXS50aW1lLCB0aW1lKSkge1xuICAgICAgICAgICAgbGV0IGxvd2VyQm91bmQgPSB1cHBlckJvdW5kO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHVwcGVyQm91bmQ7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKEVRKHRoaXMuX3RpbWVsaW5lW2ldLnRpbWUsIHRpbWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvd2VyQm91bmQgPSBpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5faXRlcmF0ZShldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXZlbnQpO1xuICAgICAgICAgICAgfSwgbG93ZXJCb3VuZCwgdXBwZXJCb3VuZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZWxpbmUuanMubWFwIiwiLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBJTklUSUFMSVpJTkcgTkVXIENPTlRFWFRcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBBcnJheSBvZiBjYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkXG4gKi9cbmNvbnN0IG5vdGlmeU5ld0NvbnRleHQgPSBbXTtcbi8qKlxuICogVXNlZCBpbnRlcm5hbGx5IHRvIHNldHVwIGEgbmV3IENvbnRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ29udGV4dEluaXQoY2IpIHtcbiAgICBub3RpZnlOZXdDb250ZXh0LnB1c2goY2IpO1xufVxuLyoqXG4gKiBJbnZva2UgYW55IGNsYXNzZXMgd2hpY2ggbmVlZCB0byBhbHNvIGJlIGluaXRpYWxpemVkIHdoZW4gYSBuZXcgY29udGV4dCBpcyBjcmVhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdGlhbGl6ZUNvbnRleHQoY3R4KSB7XG4gICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICBub3RpZnlOZXdDb250ZXh0LmZvckVhY2goY2IgPT4gY2IoY3R4KSk7XG59XG4vKipcbiAqIEFycmF5IG9mIGNhbGxiYWNrcyB0byBpbnZva2Ugd2hlbiBhIG5ldyBjb250ZXh0IGlzIGNyZWF0ZWRcbiAqL1xuY29uc3Qgbm90aWZ5Q2xvc2VDb250ZXh0ID0gW107XG4vKipcbiAqIFVzZWQgaW50ZXJuYWxseSB0byB0ZWFyIGRvd24gYSBDb250ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkNvbnRleHRDbG9zZShjYikge1xuICAgIG5vdGlmeUNsb3NlQ29udGV4dC5wdXNoKGNiKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBjbG9zZUNvbnRleHQoY3R4KSB7XG4gICAgLy8gYWRkIGFueSBhZGRpdGlvbmFsIG1vZHVsZXNcbiAgICBub3RpZnlDbG9zZUNvbnRleHQuZm9yRWFjaChjYiA9PiBjYihjdHgpKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbnRleHRJbml0aWFsaXphdGlvbi5qcy5tYXAiLCJpbXBvcnQgeyBUb25lIH0gZnJvbSBcIi4uL1RvbmVcIjtcbmltcG9ydCB7IGlzVW5kZWYgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogRW1pdHRlciBnaXZlcyBjbGFzc2VzIHdoaWNoIGV4dGVuZCBpdFxuICogdGhlIGFiaWxpdHkgdG8gbGlzdGVuIGZvciBhbmQgZW1pdCBldmVudHMuXG4gKiBJbnNwaXJhdGlvbiBhbmQgcmVmZXJlbmNlIGZyb20gSmVyb21lIEV0aWVubmUncyBbTWljcm9FdmVudF0oaHR0cHM6Ly9naXRodWIuY29tL2plcm9tZWV0aWVubmUvbWljcm9ldmVudC5qcykuXG4gKiBNSVQgKGMpIDIwMTEgSmVyb21lIEV0aWVubmUuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgRW1pdHRlciBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkVtaXR0ZXJcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQmluZCBhIGNhbGxiYWNrIHRvIGEgc3BlY2lmaWMgZXZlbnQuXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIGxpc3RlbiBmb3IuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gICAgICovXG4gICAgb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gICAgICAgIC8vIHNwbGl0IHRoZSBldmVudFxuICAgICAgICBjb25zdCBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuICAgICAgICBldmVudHMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fZXZlbnRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCF0aGlzLl9ldmVudHMuaGFzT3duUHJvcGVydHkoZXZlbnROYW1lKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1tldmVudE5hbWVdID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9ldmVudHNbZXZlbnROYW1lXS5wdXNoKGNhbGxiYWNrKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCaW5kIGEgY2FsbGJhY2sgd2hpY2ggaXMgb25seSBpbnZva2VkIG9uY2VcbiAgICAgKiBAcGFyYW0gIGV2ZW50ICAgICBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gbGlzdGVuIGZvci5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrICBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gdGhlIGV2ZW50IGlzIGVtaXR0ZWRcbiAgICAgKi9cbiAgICBvbmNlKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBjb25zdCBib3VuZENhbGxiYWNrID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgIGNhbGxiYWNrKC4uLmFyZ3MpO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBldmVudFxuICAgICAgICAgICAgdGhpcy5vZmYoZXZlbnQsIGJvdW5kQ2FsbGJhY2spO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9uKGV2ZW50LCBib3VuZENhbGxiYWNrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbW92ZSB0aGUgZXZlbnQgbGlzdGVuZXIuXG4gICAgICogQHBhcmFtICBldmVudCAgICAgVGhlIGV2ZW50IHRvIHN0b3AgbGlzdGVuaW5nIHRvLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB3aGljaCB3YXMgYm91bmQgdG8gdGhlIGV2ZW50IHdpdGggRW1pdHRlci5vbi5cbiAgICAgKiAgICAgICAgICAgICAgICAgICBJZiBubyBjYWxsYmFjayBpcyBnaXZlbiwgYWxsIGNhbGxiYWNrcyBldmVudHMgYXJlIHJlbW92ZWQuXG4gICAgICovXG4gICAgb2ZmKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBjb25zdCBldmVudHMgPSBldmVudC5zcGxpdCgvXFxXKy8pO1xuICAgICAgICBldmVudHMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fZXZlbnRzKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNVbmRlZihjYWxsYmFjaykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW2V2ZW50XSA9IFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXZlbnRMaXN0ID0gdGhpcy5fZXZlbnRzW2V2ZW50XTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGV2ZW50TGlzdC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGV2ZW50TGlzdFtpXSA9PT0gY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudExpc3Quc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSBhbGwgb2YgdGhlIGNhbGxiYWNrcyBib3VuZCB0byB0aGUgZXZlbnRcbiAgICAgKiB3aXRoIGFueSBhcmd1bWVudHMgcGFzc2VkIGluLlxuICAgICAqIEBwYXJhbSAgZXZlbnQgIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cbiAgICAgKiBAcGFyYW0gYXJncyBUaGUgYXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGZ1bmN0aW9ucyBsaXN0ZW5pbmcuXG4gICAgICovXG4gICAgZW1pdChldmVudCwgLi4uYXJncykge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnRzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmhhc093blByb3BlcnR5KGV2ZW50KSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50TGlzdCA9IHRoaXMuX2V2ZW50c1tldmVudF0uc2xpY2UoMCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGV2ZW50TGlzdC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBldmVudExpc3RbaV0uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgRW1pdHRlciBmdW5jdGlvbnMgKG9uL29mZi9lbWl0KSB0byB0aGUgb2JqZWN0XG4gICAgICovXG4gICAgc3RhdGljIG1peGluKGNvbnN0cikge1xuICAgICAgICAvLyBpbnN0YW5jZS5fZXZlbnRzID0ge307XG4gICAgICAgIFtcIm9uXCIsIFwib25jZVwiLCBcIm9mZlwiLCBcImVtaXRcIl0uZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHByb3BlcnR5ID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihFbWl0dGVyLnByb3RvdHlwZSwgbmFtZSk7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29uc3RyLnByb3RvdHlwZSwgbmFtZSwgcHJvcGVydHkpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RW1pdHRlci5qcy5tYXAiLCJpbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuZXhwb3J0IGNsYXNzIEJhc2VDb250ZXh0IGV4dGVuZHMgRW1pdHRlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgfVxuICAgIC8qXG4gICAgICogVGhpcyBpcyBhIHBsYWNlaG9sZGVyIHNvIHRoYXQgSlNPTi5zdHJpbmdpZnkgZG9lcyBub3QgdGhyb3cgYW4gZXJyb3JcbiAgICAgKiBUaGlzIG1hdGNoZXMgd2hhdCBKU09OLnN0cmluZ2lmeShhdWRpb0NvbnRleHQpIHJldHVybnMgb24gYSBuYXRpdmVcbiAgICAgKiBhdWRpb0NvbnRleHQgaW5zdGFuY2UuXG4gICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QmFzZUNvbnRleHQuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUaWNrZXIgfSBmcm9tIFwiLi4vY2xvY2svVGlja2VyXCI7XG5pbXBvcnQgeyBpc0F1ZGlvQ29udGV4dCB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBUaW1lbGluZSB9IGZyb20gXCIuLi91dGlsL1RpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzU3RyaW5nIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBjcmVhdGVBdWRpb0NvbnRleHQsIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUsIH0gZnJvbSBcIi4vQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBjbG9zZUNvbnRleHQsIGluaXRpYWxpemVDb250ZXh0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG5pbXBvcnQgeyBCYXNlQ29udGV4dCB9IGZyb20gXCIuL0Jhc2VDb250ZXh0XCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIEF1ZGlvQ29udGV4dC5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250ZXh0IGV4dGVuZHMgQmFzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbnRleHRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFuIG9iamVjdCBjb250YWluaW5nIGFsbCBvZiB0aGUgY29uc3RhbnRzIEF1ZGlvQnVmZmVyU291cmNlTm9kZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbnN0YW50cyA9IG5ldyBNYXAoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCBvZiB0aGUgc2V0VGltZW91dCBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl90aW1lb3V0cyA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHRpbWVvdXQgaWQgY291bnRlclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dElkcyA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIGluZGljYXRvciBpZiB0aGUgY29udGV4dCBoYXMgYmVlbiBpbml0aWFsaXplZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgY29udGV4dCBpcyBhbiBPZmZsaW5lQXVkaW9Db250ZXh0IG9yIGFuIEF1ZGlvQ29udGV4dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pc09mZmxpbmUgPSBmYWxzZTtcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBBVURJTyBXT1JLTEVUXG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1hcHMgYSBtb2R1bGUgbmFtZSB0byBwcm9taXNlIG9mIHRoZSBhZGRNb2R1bGUgbWV0aG9kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbnRleHQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXG4gICAgICAgICAgICBcImNvbnRleHRcIixcbiAgICAgICAgXSk7XG4gICAgICAgIGlmIChvcHRpb25zLmNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHQgPSBvcHRpb25zLmNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY3JlYXRlQXVkaW9Db250ZXh0KHtcbiAgICAgICAgICAgICAgICBsYXRlbmN5SGludDogb3B0aW9ucy5sYXRlbmN5SGludCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RpY2tlciA9IG5ldyBUaWNrZXIodGhpcy5lbWl0LmJpbmQodGhpcywgXCJ0aWNrXCIpLCBvcHRpb25zLmNsb2NrU291cmNlLCBvcHRpb25zLnVwZGF0ZUludGVydmFsKTtcbiAgICAgICAgdGhpcy5vbihcInRpY2tcIiwgdGhpcy5fdGltZW91dExvb3AuYmluZCh0aGlzKSk7XG4gICAgICAgIC8vIGZ3ZCBldmVudHMgZnJvbSB0aGUgY29udGV4dFxuICAgICAgICB0aGlzLl9jb250ZXh0Lm9uc3RhdGVjaGFuZ2UgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGF0ZWNoYW5nZVwiLCB0aGlzLnN0YXRlKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5fc2V0TGF0ZW5jeUhpbnQob3B0aW9ucy5sYXRlbmN5SGludCk7XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gb3B0aW9ucy5sb29rQWhlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNsb2NrU291cmNlOiBcIndvcmtlclwiLFxuICAgICAgICAgICAgbGF0ZW5jeUhpbnQ6IFwiaW50ZXJhY3RpdmVcIixcbiAgICAgICAgICAgIGxvb2tBaGVhZDogMC4xLFxuICAgICAgICAgICAgdXBkYXRlSW50ZXJ2YWw6IDAuMDUsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmlzaCBzZXR0aW5nIHVwIHRoZSBjb250ZXh0LiAqKllvdSB1c3VhbGx5IGRvIG5vdCBuZWVkIHRvIGRvIHRoaXMgbWFudWFsbHkuKipcbiAgICAgKi9cbiAgICBpbml0aWFsaXplKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2luaXRpYWxpemVkKSB7XG4gICAgICAgICAgICAvLyBhZGQgYW55IGFkZGl0aW9uYWwgbW9kdWxlc1xuICAgICAgICAgICAgaW5pdGlhbGl6ZUNvbnRleHQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQkFTRSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgIH1cbiAgICBjcmVhdGVPc2NpbGxhdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVPc2NpbGxhdG9yKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlclNvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyU291cmNlKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZUJ1ZmZlcihudW1iZXJPZkNoYW5uZWxzLCBsZW5ndGgsIHNhbXBsZVJhdGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQnVmZmVyKG51bWJlck9mQ2hhbm5lbHMsIGxlbmd0aCwgc2FtcGxlUmF0ZSk7XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxNZXJnZXIobnVtYmVyT2ZJbnB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ2hhbm5lbE1lcmdlcihudW1iZXJPZklucHV0cyk7XG4gICAgfVxuICAgIGNyZWF0ZUNoYW5uZWxTcGxpdHRlcihudW1iZXJPZk91dHB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlQ2hhbm5lbFNwbGl0dGVyKG51bWJlck9mT3V0cHV0cyk7XG4gICAgfVxuICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVDb25zdGFudFNvdXJjZSgpO1xuICAgIH1cbiAgICBjcmVhdGVDb252b2x2ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgIH1cbiAgICBjcmVhdGVEZWxheShtYXhEZWxheVRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlRGVsYXkobWF4RGVsYXlUaW1lKTtcbiAgICB9XG4gICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVEeW5hbWljc0NvbXByZXNzb3IoKTtcbiAgICB9XG4gICAgY3JlYXRlR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgIH1cbiAgICBjcmVhdGVJSVJGaWx0ZXIoZmVlZEZvcndhcmQsIGZlZWRiYWNrKSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlSUlSRmlsdGVyKGZlZWRGb3J3YXJkLCBmZWVkYmFjayk7XG4gICAgfVxuICAgIGNyZWF0ZVBhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3JlYXRlUGFubmVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnLCBjb25zdHJhaW50cykge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmUocmVhbCwgaW1hZywgY29uc3RyYWludHMpO1xuICAgIH1cbiAgICBjcmVhdGVTdGVyZW9QYW5uZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgIH1cbiAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jcmVhdGVXYXZlU2hhcGVyKCk7XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSkge1xuICAgICAgICBhc3NlcnQoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCksIFwiTm90IGF2YWlsYWJsZSBpZiBPZmZsaW5lQXVkaW9Db250ZXh0XCIpO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFFbGVtZW50U291cmNlKGVsZW1lbnQpIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhRWxlbWVudFNvdXJjZShlbGVtZW50KTtcbiAgICB9XG4gICAgY3JlYXRlTWVkaWFTdHJlYW1EZXN0aW5hdGlvbigpIHtcbiAgICAgICAgYXNzZXJ0KGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpLCBcIk5vdCBhdmFpbGFibGUgaWYgT2ZmbGluZUF1ZGlvQ29udGV4dFwiKTtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHJldHVybiBjb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtRGVzdGluYXRpb24oKTtcbiAgICB9XG4gICAgZGVjb2RlQXVkaW9EYXRhKGF1ZGlvRGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5kZWNvZGVBdWRpb0RhdGEoYXVkaW9EYXRhKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGltZSBpbiBzZWNvbmRzIG9mIHRoZSBBdWRpb0NvbnRleHQuXG4gICAgICovXG4gICAgZ2V0IHNhbXBsZVJhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0ZW5lclxuICAgICAqL1xuICAgIGdldCBsaXN0ZW5lcigpIHtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9saXN0ZW5lcjtcbiAgICB9XG4gICAgc2V0IGxpc3RlbmVyKGwpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgbGlzdGVuZXIgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2xpc3RlbmVyID0gbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlcmUgaXMgb25seSBvbmUgVHJhbnNwb3J0IHBlciBDb250ZXh0LiBJdCBpcyBjcmVhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuICAgICAqL1xuICAgIGdldCB0cmFuc3BvcnQoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNwb3J0O1xuICAgIH1cbiAgICBzZXQgdHJhbnNwb3J0KHQpIHtcbiAgICAgICAgYXNzZXJ0KCF0aGlzLl9pbml0aWFsaXplZCwgXCJUaGUgdHJhbnNwb3J0IGNhbm5vdCBiZSBzZXQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uXCIpO1xuICAgICAgICB0aGlzLl90cmFuc3BvcnQgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGlzIGlzIHRoZSBEcmF3IG9iamVjdCBmb3IgdGhlIGNvbnRleHQgd2hpY2ggaXMgdXNlZnVsIGZvciBzeW5jaHJvbml6aW5nIHRoZSBkcmF3IGZyYW1lIHdpdGggdGhlIFRvbmUuanMgY2xvY2suXG4gICAgICovXG4gICAgZ2V0IGRyYXcoKSB7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZSgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fZHJhdztcbiAgICB9XG4gICAgc2V0IGRyYXcoZCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIkRyYXcgY2Fubm90IGJlIHNldCBhZnRlciBpbml0aWFsaXphdGlvbi5cIik7XG4gICAgICAgIHRoaXMuX2RyYXcgPSBkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgQ29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICovXG4gICAgZ2V0IGRlc3RpbmF0aW9uKCkge1xuICAgICAgICB0aGlzLmluaXRpYWxpemUoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rlc3RpbmF0aW9uO1xuICAgIH1cbiAgICBzZXQgZGVzdGluYXRpb24oZCkge1xuICAgICAgICBhc3NlcnQoIXRoaXMuX2luaXRpYWxpemVkLCBcIlRoZSBkZXN0aW5hdGlvbiBjYW5ub3QgYmUgc2V0IGFmdGVyIGluaXRpYWxpemF0aW9uLlwiKTtcbiAgICAgICAgdGhpcy5fZGVzdGluYXRpb24gPSBkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYW4gYXVkaW8gd29ya2xldCBub2RlIGZyb20gYSBuYW1lIGFuZCBvcHRpb25zLiBUaGUgbW9kdWxlXG4gICAgICogbXVzdCBmaXJzdCBiZSBsb2FkZWQgdXNpbmcgW1thZGRBdWRpb1dvcmtsZXRNb2R1bGVdXS5cbiAgICAgKi9cbiAgICBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKG5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUF1ZGlvV29ya2xldE5vZGUodGhpcy5yYXdDb250ZXh0LCBuYW1lLCBvcHRpb25zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIEF1ZGlvV29ya2xldFByb2Nlc3NvciBtb2R1bGVcbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIG1vZHVsZVxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGVcbiAgICAgKi9cbiAgICBhZGRBdWRpb1dvcmtsZXRNb2R1bGUodXJsLCBuYW1lKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKHRoaXMucmF3Q29udGV4dC5hdWRpb1dvcmtsZXQpLCBcIkF1ZGlvV29ya2xldE5vZGUgaXMgb25seSBhdmFpbGFibGUgaW4gYSBzZWN1cmUgY29udGV4dCAoaHR0cHMgb3IgbG9jYWxob3N0KVwiKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd29ya2xldE1vZHVsZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldE1vZHVsZXMuc2V0KG5hbWUsIHRoaXMucmF3Q29udGV4dC5hdWRpb1dvcmtsZXQuYWRkTW9kdWxlKHVybCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeWllbGQgdGhpcy5fd29ya2xldE1vZHVsZXMuZ2V0KG5hbWUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIHdvcmtsZXRzIGhhdmUgYmVlbiBsb2FkZWQgb24gdGhpcyBjb250ZXh0XG4gICAgICovXG4gICAgd29ya2xldHNBcmVSZWFkeSgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0TW9kdWxlcy5mb3JFYWNoKChwcm9taXNlKSA9PiBwcm9taXNlcy5wdXNoKHByb21pc2UpKTtcbiAgICAgICAgICAgIHlpZWxkIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gVElDS0VSXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBIb3cgb2Z0ZW4gdGhlIGludGVydmFsIGNhbGxiYWNrIGlzIGludm9rZWQuXG4gICAgICogVGhpcyBudW1iZXIgY29ycmVzcG9uZHMgdG8gaG93IHJlc3BvbnNpdmUgdGhlIHNjaGVkdWxpbmdcbiAgICAgKiBjYW4gYmUuIGNvbnRleHQudXBkYXRlSW50ZXJ2YWwgKyBjb250ZXh0Lmxvb2tBaGVhZCBnaXZlcyB5b3UgdGhlXG4gICAgICogdG90YWwgbGF0ZW5jeSBiZXR3ZWVuIHNjaGVkdWxpbmcgYW4gZXZlbnQgYW5kIGhlYXJpbmcgaXQuXG4gICAgICovXG4gICAgZ2V0IHVwZGF0ZUludGVydmFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsO1xuICAgIH1cbiAgICBzZXQgdXBkYXRlSW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fdGlja2VyLnVwZGF0ZUludGVydmFsID0gaW50ZXJ2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdoYXQgdGhlIHNvdXJjZSBvZiB0aGUgY2xvY2sgaXMsIGVpdGhlciBcIndvcmtlclwiIChkZWZhdWx0KSxcbiAgICAgKiBcInRpbWVvdXRcIiwgb3IgXCJvZmZsaW5lXCIgKG5vbmUpLlxuICAgICAqL1xuICAgIGdldCBjbG9ja1NvdXJjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tlci50eXBlO1xuICAgIH1cbiAgICBzZXQgY2xvY2tTb3VyY2UodHlwZSkge1xuICAgICAgICB0aGlzLl90aWNrZXIudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHBsYXliYWNrLCB3aGljaCBhZmZlY3RzIHRyYWRlb2ZmcyBiZXR3ZWVuIGF1ZGlvXG4gICAgICogb3V0cHV0IGxhdGVuY3kgYW5kIHJlc3BvbnNpdmVuZXNzLlxuICAgICAqIEluIGFkZGl0aW9uIHRvIHNldHRpbmcgdGhlIHZhbHVlIGluIHNlY29uZHMsIHRoZSBsYXRlbmN5SGludCBhbHNvXG4gICAgICogYWNjZXB0cyB0aGUgc3RyaW5ncyBcImludGVyYWN0aXZlXCIgKHByaW9yaXRpemVzIGxvdyBsYXRlbmN5KSxcbiAgICAgKiBcInBsYXliYWNrXCIgKHByaW9yaXRpemVzIHN1c3RhaW5lZCBwbGF5YmFjayksIFwiYmFsYW5jZWRcIiAoYmFsYW5jZXNcbiAgICAgKiBsYXRlbmN5IGFuZCBwZXJmb3JtYW5jZSkuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBwcmlvcml0aXplIHN1c3RhaW5lZCBwbGF5YmFja1xuICAgICAqIGNvbnN0IGNvbnRleHQgPSBuZXcgVG9uZS5Db250ZXh0KHsgbGF0ZW5jeUhpbnQ6IFwicGxheWJhY2tcIiB9KTtcbiAgICAgKiAvLyBzZXQgdGhpcyBjb250ZXh0IGFzIHRoZSBnbG9iYWwgQ29udGV4dFxuICAgICAqIFRvbmUuc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgKiAvLyB0aGUgZ2xvYmFsIGNvbnRleHQgaXMgZ2V0dGFibGUgd2l0aCBUb25lLmdldENvbnRleHQoKVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuZ2V0Q29udGV4dCgpLmxhdGVuY3lIaW50KTtcbiAgICAgKi9cbiAgICBnZXQgbGF0ZW5jeUhpbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sYXRlbmN5SGludDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHRoZSBsb29rQWhlYWQgYW5kIHVwZGF0ZUludGVydmFsIGJhc2VkIG9uIHRoZSBsYXRlbmN5SGludFxuICAgICAqL1xuICAgIF9zZXRMYXRlbmN5SGludChoaW50KSB7XG4gICAgICAgIGxldCBsb29rQWhlYWRWYWx1ZSA9IDA7XG4gICAgICAgIHRoaXMuX2xhdGVuY3lIaW50ID0gaGludDtcbiAgICAgICAgaWYgKGlzU3RyaW5nKGhpbnQpKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGhpbnQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwiaW50ZXJhY3RpdmVcIjpcbiAgICAgICAgICAgICAgICAgICAgbG9va0FoZWFkVmFsdWUgPSAwLjE7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJwbGF5YmFja1wiOlxuICAgICAgICAgICAgICAgICAgICBsb29rQWhlYWRWYWx1ZSA9IDAuNTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImJhbGFuY2VkXCI6XG4gICAgICAgICAgICAgICAgICAgIGxvb2tBaGVhZFZhbHVlID0gMC4yNTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb29rQWhlYWQgPSBsb29rQWhlYWRWYWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVJbnRlcnZhbCA9IGxvb2tBaGVhZFZhbHVlIC8gMjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHVud3JhcHBlZCBBdWRpb0NvbnRleHQgb3IgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICAgICAqL1xuICAgIGdldCByYXdDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIHBsdXMgYSBzaG9ydCBbW2xvb2tBaGVhZF1dLlxuICAgICAqL1xuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWUgKyB0aGlzLmxvb2tBaGVhZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIHdpdGhvdXQgdGhlIFtbbG9va0FoZWFkXV0uXG4gICAgICogSW4gbW9zdCBjYXNlcyBpdCBpcyBiZXR0ZXIgdG8gdXNlIFtbbm93XV0gaW5zdGVhZCBvZiBbW2ltbWVkaWF0ZV1dIHNpbmNlXG4gICAgICogd2l0aCBbW25vd11dIHRoZSBbW2xvb2tBaGVhZF1dIGlzIGFwcGxpZWQgZXF1YWxseSB0byBfYWxsXyBjb21wb25lbnRzIGluY2x1ZGluZyBpbnRlcm5hbCBjb21wb25lbnRzLFxuICAgICAqIHRvIG1ha2luZyBzdXJlIHRoYXQgZXZlcnl0aGluZyBpcyBzY2hlZHVsZWQgaW4gc3luYy4gTWl4aW5nIFtbbm93XV0gYW5kIFtbaW1tZWRpYXRlXV1cbiAgICAgKiBjYW4gY2F1c2Ugc29tZSB0aW1pbmcgaXNzdWVzLiBJZiBubyBsb29rQWhlYWQgaXMgZGVzaXJlZCwgeW91IGNhbiBzZXQgdGhlIFtbbG9va0FoZWFkXV0gdG8gYDBgLlxuICAgICAqL1xuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0cyB0aGUgYXVkaW8gY29udGV4dCBmcm9tIGEgc3VzcGVuZGVkIHN0YXRlLiBUaGlzIGlzIHJlcXVpcmVkXG4gICAgICogdG8gaW5pdGlhbGx5IHN0YXJ0IHRoZSBBdWRpb0NvbnRleHQuIFNlZSBbW1RvbmUuc3RhcnRdXVxuICAgICAqL1xuICAgIHJlc3VtZSgpIHtcbiAgICAgICAgaWYgKGlzQXVkaW9Db250ZXh0KHRoaXMuX2NvbnRleHQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5yZXN1bWUoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgY29udGV4dC4gT25jZSBjbG9zZWQsIHRoZSBjb250ZXh0IGNhbiBubyBsb25nZXIgYmUgdXNlZCBhbmRcbiAgICAgKiBhbnkgQXVkaW9Ob2RlcyBjcmVhdGVkIGZyb20gdGhlIGNvbnRleHQgd2lsbCBiZSBzaWxlbnQuXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBpZiAoaXNBdWRpb0NvbnRleHQodGhpcy5fY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCB0aGlzLl9jb250ZXh0LmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5faW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICBjbG9zZUNvbnRleHQodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqKkludGVybmFsKiogR2VuZXJhdGUgYSBsb29wZWQgYnVmZmVyIGF0IHNvbWUgY29uc3RhbnQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0Q29uc3RhbnQodmFsKSB7XG4gICAgICAgIGlmICh0aGlzLl9jb25zdGFudHMuaGFzKHZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9jb25zdGFudHMuZ2V0KHZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB0aGlzLl9jb250ZXh0LmNyZWF0ZUJ1ZmZlcigxLCAxMjgsIHRoaXMuX2NvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBhcnIgPSBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGFycltpXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGNvbnN0YW50ID0gdGhpcy5fY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgICAgIGNvbnN0YW50LmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgICAgICBjb25zdGFudC5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICAgICAgY29uc3RhbnQuYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICAgICAgY29uc3RhbnQubG9vcCA9IHRydWU7XG4gICAgICAgICAgICBjb25zdGFudC5zdGFydCgwKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnN0YW50cy5zZXQodmFsLCBjb25zdGFudCk7XG4gICAgICAgICAgICByZXR1cm4gY29uc3RhbnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuIEFsc28gY2xvc2VzIHRoZSBhdWRpbyBjb250ZXh0LlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGlja2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdGltZW91dHMuZGlzcG9zZSgpO1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLl9jb25zdGFudHMpLm1hcCgodmFsKSA9PiB0aGlzLl9jb25zdGFudHNbdmFsXS5kaXNjb25uZWN0KCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBUSU1FT1VUU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVGhlIHByaXZhdGUgbG9vcCB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgY29udGV4dCBzY2hlZHVsZWQgdGltZW91dHNcbiAgICAgKiBJcyBpbnZva2VkIGZyb20gdGhlIGNsb2NrIHNvdXJjZVxuICAgICAqL1xuICAgIF90aW1lb3V0TG9vcCgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgbGV0IGZpcnN0RXZlbnQgPSB0aGlzLl90aW1lb3V0cy5wZWVrKCk7XG4gICAgICAgIHdoaWxlICh0aGlzLl90aW1lb3V0cy5sZW5ndGggJiYgZmlyc3RFdmVudCAmJiBmaXJzdEV2ZW50LnRpbWUgPD0gbm93KSB7XG4gICAgICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICBmaXJzdEV2ZW50LmNhbGxiYWNrKCk7XG4gICAgICAgICAgICAvLyBzaGlmdCB0aGUgZmlyc3QgZXZlbnQgb2ZmXG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5zaGlmdCgpO1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBuZXh0IG9uZVxuICAgICAgICAgICAgZmlyc3RFdmVudCA9IHRoaXMuX3RpbWVvdXRzLnBlZWsoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHNldFRpbWVvdXQgd2hpY2ggaXMgZ3VhcmFudGVlZCBieSB0aGUgY2xvY2sgc291cmNlLlxuICAgICAqIEFsc28gcnVucyBpbiB0aGUgb2ZmbGluZSBjb250ZXh0LlxuICAgICAqIEBwYXJhbSAgZm4gICAgICAgVGhlIGNhbGxiYWNrIHRvIGludm9rZVxuICAgICAqIEBwYXJhbSAgdGltZW91dCAgVGhlIHRpbWVvdXQgaW4gc2Vjb25kc1xuICAgICAqIEByZXR1cm5zIElEIHRvIHVzZSB3aGVuIGludm9raW5nIENvbnRleHQuY2xlYXJUaW1lb3V0XG4gICAgICovXG4gICAgc2V0VGltZW91dChmbiwgdGltZW91dCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0SWRzKys7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX3RpbWVvdXRzLmFkZCh7XG4gICAgICAgICAgICBjYWxsYmFjazogZm4sXG4gICAgICAgICAgICBpZDogdGhpcy5fdGltZW91dElkcyxcbiAgICAgICAgICAgIHRpbWU6IG5vdyArIHRpbWVvdXQsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcy5fdGltZW91dElkcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXJzIGEgcHJldmlvdXNseSBzY2hlZHVsZWQgdGltZW91dCB3aXRoIFRvbmUuY29udGV4dC5zZXRUaW1lb3V0XG4gICAgICogQHBhcmFtICBpZCAgVGhlIElEIHJldHVybmVkIGZyb20gc2V0VGltZW91dFxuICAgICAqL1xuICAgIGNsZWFyVGltZW91dChpZCkge1xuICAgICAgICB0aGlzLl90aW1lb3V0cy5mb3JFYWNoKChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50LmlkID09PSBpZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RpbWVvdXRzLnJlbW92ZShldmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYXIgdGhlIGZ1bmN0aW9uIHNjaGVkdWxlZCBieSBbW3NldEludGVydmFsXV1cbiAgICAgKi9cbiAgICBjbGVhckludGVydmFsKGlkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNsZWFyVGltZW91dChpZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZHMgYSByZXBlYXRpbmcgZXZlbnQgdG8gdGhlIGNvbnRleHQncyBjYWxsYmFjayBjbG9ja1xuICAgICAqL1xuICAgIHNldEludGVydmFsKGZuLCBpbnRlcnZhbCkge1xuICAgICAgICBjb25zdCBpZCA9ICsrdGhpcy5fdGltZW91dElkcztcbiAgICAgICAgY29uc3QgaW50ZXJ2YWxGbiA9ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgICAgICB0aGlzLl90aW1lb3V0cy5hZGQoe1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gaW52b2tlIHRoZSBldmVudCB0byByZXBlYXQgaXRcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWxGbigpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgdGltZTogbm93ICsgaW50ZXJ2YWwsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8ga2ljayBpdCBvZmZcbiAgICAgICAgaW50ZXJ2YWxGbigpO1xuICAgICAgICByZXR1cm4gaWQ7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEJhc2VDb250ZXh0IH0gZnJvbSBcIi4vQmFzZUNvbnRleHRcIjtcbmV4cG9ydCBjbGFzcyBEdW1teUNvbnRleHQgZXh0ZW5kcyBCYXNlQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubG9va0FoZWFkID0gMDtcbiAgICAgICAgdGhpcy5sYXRlbmN5SGludCA9IDA7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gZmFsc2U7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQkFTRSBBVURJTyBDT05URVhUIE1FVEhPRFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIGNyZWF0ZUFuYWx5c2VyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU9zY2lsbGF0b3IoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQnVmZmVyU291cmNlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUJpcXVhZEZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVCdWZmZXIoX251bWJlck9mQ2hhbm5lbHMsIF9sZW5ndGgsIF9zYW1wbGVSYXRlKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlQ2hhbm5lbE1lcmdlcihfbnVtYmVyT2ZJbnB1dHMpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVDaGFubmVsU3BsaXR0ZXIoX251bWJlck9mT3V0cHV0cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNvbnN0YW50U291cmNlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUNvbnZvbHZlcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVEZWxheShfbWF4RGVsYXlUaW1lKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZUdhaW4oKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlSUlSRmlsdGVyKF9mZWVkRm9yd2FyZCwgX2ZlZWRiYWNrKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY3JlYXRlUGFubmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVBlcmlvZGljV2F2ZShfcmVhbCwgX2ltYWcsIF9jb25zdHJhaW50cykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZVN0ZXJlb1Bhbm5lcigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVXYXZlU2hhcGVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKF9zdHJlYW0pIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYUVsZW1lbnRTb3VyY2UoX2VsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGRlY29kZUF1ZGlvRGF0YShfYXVkaW9EYXRhKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFRPTkUgQVVESU8gQ09OVEVYVCBNRVRIT0RTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVBdWRpb1dvcmtsZXROb2RlKF9uYW1lLCBfb3B0aW9ucykge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCByYXdDb250ZXh0KCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGFkZEF1ZGlvV29ya2xldE1vZHVsZShfdXJsLCBfbmFtZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVzdW1lKCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHNldFRpbWVvdXQoX2ZuLCBfdGltZW91dCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgY2xlYXJUaW1lb3V0KF9pZCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0SW50ZXJ2YWwoX2ZuLCBfaW50ZXJ2YWwpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoX2lkKSB7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRDb25zdGFudChfdmFsKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IGN1cnJlbnRUaW1lKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCBzYW1wbGVSYXRlKCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgZ2V0IGxpc3RlbmVyKCkge1xuICAgICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGdldCB0cmFuc3BvcnQoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgZ2V0IGRyYXcoKSB7XG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgc2V0IGRyYXcoX2QpIHsgfVxuICAgIGdldCBkZXN0aW5hdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBzZXQgZGVzdGluYXRpb24oX2QpIHsgfVxuICAgIG5vdygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RHVtbXlDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IGlzQXJyYXkgfSBmcm9tIFwiLi9UeXBlQ2hlY2tcIjtcbi8qKlxuICogTWFrZSB0aGUgcHJvcGVydHkgbm90IHdyaXRhYmxlIHVzaW5nIGBkZWZpbmVQcm9wZXJ0eWAuIEludGVybmFsIHVzZSBvbmx5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZE9ubHkodGFyZ2V0LCBwcm9wZXJ0eSkge1xuICAgIGlmIChpc0FycmF5KHByb3BlcnR5KSkge1xuICAgICAgICBwcm9wZXJ0eS5mb3JFYWNoKHN0ciA9PiByZWFkT25seSh0YXJnZXQsIHN0cikpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHksIHtcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8qKlxuICogTWFrZSBhbiBhdHRyaWJ1dGUgd3JpdGVhYmxlLiBJbnRlcm5hbCB1c2Ugb25seS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRhYmxlKHRhcmdldCwgcHJvcGVydHkpIHtcbiAgICBpZiAoaXNBcnJheShwcm9wZXJ0eSkpIHtcbiAgICAgICAgcHJvcGVydHkuZm9yRWFjaChzdHIgPT4gd3JpdGFibGUodGFyZ2V0LCBzdHIpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB7XG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuZXhwb3J0IGNvbnN0IG5vT3AgPSAoKSA9PiB7XG4gICAgLy8gbm8gb3BlcmF0aW9uIGhlcmUhXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW50ZXJmYWNlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc051bWJlciwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEF1ZGlvQnVmZmVyIGxvYWRpbmcgYW5kIHN0b3JhZ2UuIFRvbmVBdWRpb0J1ZmZlciBpcyB1c2VkIGludGVybmFsbHkgYnkgYWxsXG4gKiBjbGFzc2VzIHRoYXQgbWFrZSByZXF1ZXN0cyBmb3IgYXVkaW8gZmlsZXMgc3VjaCBhcyBUb25lLlBsYXllcixcbiAqIFRvbmUuU2FtcGxlciBhbmQgVG9uZS5Db252b2x2ZXIuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgYnVmZmVyID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0ExLm1wM1wiLCAoKSA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKFwibG9hZGVkXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUF1ZGlvQnVmZmVyIGV4dGVuZHMgVG9uZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUF1ZGlvQnVmZmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsYmFjayB3aGVuIHRoZSBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vbmxvYWQgPSBub09wO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUF1ZGlvQnVmZmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCIsIFwib25lcnJvclwiXSk7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9IG9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgdGhpcy5vbmxvYWQgPSBvcHRpb25zLm9ubG9hZDtcbiAgICAgICAgaWYgKG9wdGlvbnMudXJsICYmIGlzQXVkaW9CdWZmZXIob3B0aW9ucy51cmwpIHx8IG9wdGlvbnMudXJsIGluc3RhbmNlb2YgVG9uZUF1ZGlvQnVmZmVyKSB7XG4gICAgICAgICAgICB0aGlzLnNldChvcHRpb25zLnVybCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcob3B0aW9ucy51cmwpKSB7XG4gICAgICAgICAgICAvLyBpbml0aWF0ZSB0aGUgZG93bmxvYWRcbiAgICAgICAgICAgIHRoaXMubG9hZChvcHRpb25zLnVybCkuY2F0Y2gob3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzYW1wbGUgcmF0ZSBvZiB0aGUgQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBnZXQgc2FtcGxlUmF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlci5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGdldENvbnRleHQoKS5zYW1wbGVSYXRlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFBhc3MgaW4gYW4gQXVkaW9CdWZmZXIgb3IgVG9uZUF1ZGlvQnVmZmVyIHRvIHNldCB0aGUgdmFsdWUgb2YgdGhpcyBidWZmZXIuXG4gICAgICovXG4gICAgc2V0KGJ1ZmZlcikge1xuICAgICAgICBpZiAoYnVmZmVyIGluc3RhbmNlb2YgVG9uZUF1ZGlvQnVmZmVyKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIGxvYWRlZCwgc2V0IGl0XG4gICAgICAgICAgICBpZiAoYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlci5nZXQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSB3aGVuIGl0J3MgbG9hZGVkLCBpbnZva2UgaXQncyBjYWxsYmFja1xuICAgICAgICAgICAgICAgIGJ1ZmZlci5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0KGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25sb2FkKHRoaXMpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXIgPSBidWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmV2ZXJzZSBpdCBpbml0aWFsbHlcbiAgICAgICAgaWYgKHRoaXMuX3JldmVyc2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgc3RvcmVkIGluIHRoZSBvYmplY3QuXG4gICAgICovXG4gICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhbiBmZXRjaCByZXF1ZXN0IGZvciB0aGUgc2VsZWN0ZWQgdXJsIHRoZW4gZGVjb2RlcyB0aGUgZmlsZSBhcyBhbiBhdWRpbyBidWZmZXIuXG4gICAgICogSW52b2tlcyB0aGUgY2FsbGJhY2sgb25jZSB0aGUgYXVkaW8gYnVmZmVyIGxvYWRzLlxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCBvZiB0aGUgYnVmZmVyIHRvIGxvYWQuIGZpbGV0eXBlIHN1cHBvcnQgZGVwZW5kcyBvbiB0aGUgYnJvd3Nlci5cbiAgICAgKiBAcmV0dXJucyBBIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2l0aCB0aGlzIFRvbmVBdWRpb0J1ZmZlclxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBkb25lTG9hZGluZyA9IFRvbmVBdWRpb0J1ZmZlci5sb2FkKHVybCkudGhlbihhdWRpb0J1ZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXQoYXVkaW9CdWZmZXIpO1xuICAgICAgICAgICAgICAgIC8vIGludm9rZSB0aGUgb25sb2FkIG1ldGhvZFxuICAgICAgICAgICAgICAgIHRoaXMub25sb2FkKHRoaXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLnB1c2goZG9uZUxvYWRpbmcpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB5aWVsZCBkb25lTG9hZGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgZG93bmxvYWRlZCBmaWxlXG4gICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLmluZGV4T2YoZG9uZUxvYWRpbmcpO1xuICAgICAgICAgICAgICAgIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXVkaW8gYnVmZmVyIGZyb20gdGhlIGFycmF5LlxuICAgICAqIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlciwgcGFzcyBpbiBhIG11bHRpZGltZW5zaW9uYWwgYXJyYXkuXG4gICAgICogQHBhcmFtIGFycmF5IFRoZSBhcnJheSB0byBmaWxsIHRoZSBhdWRpbyBidWZmZXJcbiAgICAgKi9cbiAgICBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgY29uc3QgaXNNdWx0aWRpbWVuc2lvbmFsID0gaXNBcnJheShhcnJheSkgJiYgYXJyYXlbMF0ubGVuZ3RoID4gMDtcbiAgICAgICAgY29uc3QgY2hhbm5lbHMgPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheS5sZW5ndGggOiAxO1xuICAgICAgICBjb25zdCBsZW4gPSBpc011bHRpZGltZW5zaW9uYWwgPyBhcnJheVswXS5sZW5ndGggOiBhcnJheS5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGNvbnRleHQuY3JlYXRlQnVmZmVyKGNoYW5uZWxzLCBsZW4sIGNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgIGNvbnN0IG11bHRpQ2hhbm5lbEFycmF5ID0gIWlzTXVsdGlkaW1lbnNpb25hbCAmJiBjaGFubmVscyA9PT0gMSA/XG4gICAgICAgICAgICBbYXJyYXldIDogYXJyYXk7XG4gICAgICAgIGZvciAobGV0IGMgPSAwOyBjIDwgY2hhbm5lbHM7IGMrKykge1xuICAgICAgICAgICAgYnVmZmVyLmNvcHlUb0NoYW5uZWwobXVsdGlDaGFubmVsQXJyYXlbY10sIGMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2J1ZmZlciA9IGJ1ZmZlcjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN1bXMgbXVsdGlwbGUgY2hhbm5lbHMgaW50byAxIGNoYW5uZWxcbiAgICAgKiBAcGFyYW0gY2hhbk51bSBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIHRvTW9ubyhjaGFuTnVtKSB7XG4gICAgICAgIGlmIChpc051bWJlcihjaGFuTnVtKSkge1xuICAgICAgICAgICAgdGhpcy5mcm9tQXJyYXkodGhpcy50b0FycmF5KGNoYW5OdW0pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBvdXRwdXRBcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5sZW5ndGgpO1xuICAgICAgICAgICAgY29uc3QgbnVtQ2hhbm5lbHMgPSB0aGlzLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IG51bUNoYW5uZWxzOyBjaGFubmVsKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsQXJyYXkgPSB0aGlzLnRvQXJyYXkoY2hhbm5lbCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGFubmVsQXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0QXJyYXlbaV0gKz0gY2hhbm5lbEFycmF5W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGRpdmlkZSBieSB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzXG4gICAgICAgICAgICBvdXRwdXRBcnJheSA9IG91dHB1dEFycmF5Lm1hcChzYW1wbGUgPT4gc2FtcGxlIC8gbnVtQ2hhbm5lbHMpO1xuICAgICAgICAgICAgdGhpcy5mcm9tQXJyYXkob3V0cHV0QXJyYXkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ1ZmZlciBhcyBhbiBhcnJheS4gU2luZ2xlIGNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBhIDEtZGltZW5zaW9uYWxcbiAgICAgKiBGbG9hdDMyQXJyYXksIGFuZCBtdWx0aWNoYW5uZWwgYnVmZmVycyB3aWxsIHJldHVybiBtdWx0aWRpbWVuc2lvbmFsIGFycmF5cy5cbiAgICAgKiBAcGFyYW0gY2hhbm5lbCBPcHRpb25hbGx5IG9ubHkgY29weSBhIHNpbmdsZSBjaGFubmVsIGZyb20gdGhlIGFycmF5LlxuICAgICAqL1xuICAgIHRvQXJyYXkoY2hhbm5lbCkge1xuICAgICAgICBpZiAoaXNOdW1iZXIoY2hhbm5lbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubnVtYmVyT2ZDaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9BcnJheSgwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJldCA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCB0aGlzLm51bWJlck9mQ2hhbm5lbHM7IGMrKykge1xuICAgICAgICAgICAgICAgIHJldFtjXSA9IHRoaXMuZ2V0Q2hhbm5lbERhdGEoYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIEZsb2F0MzJBcnJheSByZXByZXNlbnRpbmcgdGhlIFBDTSBhdWRpbyBkYXRhIGZvciB0aGUgc3BlY2lmaWMgY2hhbm5lbC5cbiAgICAgKiBAcGFyYW0gIGNoYW5uZWwgIFRoZSBjaGFubmVsIG51bWJlciB0byByZXR1cm5cbiAgICAgKiBAcmV0dXJuIFRoZSBhdWRpbyBhcyBhIFR5cGVkQXJyYXlcbiAgICAgKi9cbiAgICBnZXRDaGFubmVsRGF0YShjaGFubmVsKSB7XG4gICAgICAgIGlmICh0aGlzLl9idWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXIuZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEZsb2F0MzJBcnJheSgwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDdXQgYSBzdWJzZWN0aW9uIG9mIHRoZSBhcnJheSBhbmQgcmV0dXJuIGEgYnVmZmVyIG9mIHRoZVxuICAgICAqIHN1YnNlY3Rpb24uIERvZXMgbm90IG1vZGlmeSB0aGUgb3JpZ2luYWwgYnVmZmVyXG4gICAgICogQHBhcmFtIHN0YXJ0IFRoZSB0aW1lIHRvIHN0YXJ0IHRoZSBzbGljZVxuICAgICAqIEBwYXJhbSBlbmQgVGhlIGVuZCB0aW1lIHRvIHNsaWNlLiBJZiBub25lIGlzIGdpdmVuIHdpbGwgZGVmYXVsdCB0byB0aGUgZW5kIG9mIHRoZSBidWZmZXJcbiAgICAgKi9cbiAgICBzbGljZShzdGFydCwgZW5kID0gdGhpcy5kdXJhdGlvbikge1xuICAgICAgICBjb25zdCBzdGFydFNhbXBsZXMgPSBNYXRoLmZsb29yKHN0YXJ0ICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgY29uc3QgZW5kU2FtcGxlcyA9IE1hdGguZmxvb3IoZW5kICogdGhpcy5zYW1wbGVSYXRlKTtcbiAgICAgICAgYXNzZXJ0KHN0YXJ0U2FtcGxlcyA8IGVuZFNhbXBsZXMsIFwiVGhlIHN0YXJ0IHRpbWUgbXVzdCBiZSBsZXNzIHRoYW4gdGhlIGVuZCB0aW1lXCIpO1xuICAgICAgICBjb25zdCBsZW5ndGggPSBlbmRTYW1wbGVzIC0gc3RhcnRTYW1wbGVzO1xuICAgICAgICBjb25zdCByZXRCdWZmZXIgPSBnZXRDb250ZXh0KCkuY3JlYXRlQnVmZmVyKHRoaXMubnVtYmVyT2ZDaGFubmVscywgbGVuZ3RoLCB0aGlzLnNhbXBsZVJhdGUpO1xuICAgICAgICBmb3IgKGxldCBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICByZXRCdWZmZXIuY29weVRvQ2hhbm5lbCh0aGlzLmdldENoYW5uZWxEYXRhKGNoYW5uZWwpLnN1YmFycmF5KHN0YXJ0U2FtcGxlcywgZW5kU2FtcGxlcyksIGNoYW5uZWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKHJldEJ1ZmZlcik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldmVyc2UgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBfcmV2ZXJzZSgpIHtcbiAgICAgICAgaWYgKHRoaXMubG9hZGVkKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubnVtYmVyT2ZDaGFubmVsczsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5nZXRDaGFubmVsRGF0YShpKS5yZXZlcnNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgaXMgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxlbmd0aCA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgZ2V0IGR1cmF0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyIGluIHNhbXBsZXNcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGlzY3JldGUgYXVkaW8gY2hhbm5lbHMuIFJldHVybnMgMCBpZiBubyBidWZmZXIgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGdldCBudW1iZXJPZkNoYW5uZWxzKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLm51bWJlck9mQ2hhbm5lbHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgZ2V0IHJldmVyc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yZXZlcnNlZDtcbiAgICB9XG4gICAgc2V0IHJldmVyc2UocmV2KSB7XG4gICAgICAgIGlmICh0aGlzLl9yZXZlcnNlZCAhPT0gcmV2KSB7XG4gICAgICAgICAgICB0aGlzLl9yZXZlcnNlZCA9IHJldjtcbiAgICAgICAgICAgIHRoaXMuX3JldmVyc2UoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBUb25lQXVkaW9CdWZmZXIgZnJvbSB0aGUgYXJyYXkuIFRvIGNyZWF0ZSBhIG11bHRpY2hhbm5lbCBBdWRpb0J1ZmZlcixcbiAgICAgKiBwYXNzIGluIGEgbXVsdGlkaW1lbnNpb25hbCBhcnJheS5cbiAgICAgKiBAcGFyYW0gYXJyYXkgVGhlIGFycmF5IHRvIGZpbGwgdGhlIGF1ZGlvIGJ1ZmZlclxuICAgICAqIEByZXR1cm4gQSBUb25lQXVkaW9CdWZmZXIgY3JlYXRlZCBmcm9tIHRoZSBhcnJheVxuICAgICAqL1xuICAgIHN0YXRpYyBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIChuZXcgVG9uZUF1ZGlvQnVmZmVyKCkpLmZyb21BcnJheShhcnJheSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBUb25lQXVkaW9CdWZmZXIgZnJvbSBhIFVSTCwgcmV0dXJucyBhIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lQXVkaW9CdWZmZXJcbiAgICAgKiBAcGFyYW0gIHVybCBUaGUgdXJsIHRvIGxvYWQuXG4gICAgICogQHJldHVybiBBIHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgdG8gYSBUb25lQXVkaW9CdWZmZXJcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbVVybCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKTtcbiAgICAgICAgICAgIHJldHVybiB5aWVsZCBidWZmZXIubG9hZCh1cmwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTG9hZHMgYSB1cmwgdXNpbmcgZmV0Y2ggYW5kIHJldHVybnMgdGhlIEF1ZGlvQnVmZmVyLlxuICAgICAqL1xuICAgIHN0YXRpYyBsb2FkKHVybCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgLy8gdGVzdCBpZiB0aGUgdXJsIGNvbnRhaW5zIG11bHRpcGxlIGV4dGVuc2lvbnNcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSB1cmwubWF0Y2goL1xcWyhbXlxcXVxcW10rXFx8LispXFxdJC8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBleHRlbnNpb25zID0gbWF0Y2hlc1sxXS5zcGxpdChcInxcIik7XG4gICAgICAgICAgICAgICAgbGV0IGV4dGVuc2lvbiA9IGV4dGVuc2lvbnNbMF07XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBleHQgb2YgZXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoVG9uZUF1ZGlvQnVmZmVyLnN1cHBvcnRzVHlwZShleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24gPSBleHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZShtYXRjaGVzWzBdLCBleHRlbnNpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZXJlIGlzIGEgc2xhc2ggYmV0d2VlbiB0aGUgYmFzZVVybCBhbmQgdGhlIHVybFxuICAgICAgICAgICAgY29uc3QgYmFzZVVybCA9IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsID09PSBcIlwiIHx8IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsLmVuZHNXaXRoKFwiL1wiKSA/IFRvbmVBdWRpb0J1ZmZlci5iYXNlVXJsIDogVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgKyBcIi9cIjtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0geWllbGQgZmV0Y2goYmFzZVVybCArIHVybCk7XG4gICAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBjb3VsZCBub3QgbG9hZCB1cmw6ICR7dXJsfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSB5aWVsZCByZXNwb25zZS5hcnJheUJ1ZmZlcigpO1xuICAgICAgICAgICAgY29uc3QgYXVkaW9CdWZmZXIgPSB5aWVsZCBnZXRDb250ZXh0KCkuZGVjb2RlQXVkaW9EYXRhKGFycmF5QnVmZmVyKTtcbiAgICAgICAgICAgIHJldHVybiBhdWRpb0J1ZmZlcjtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBhIHVybCdzIGV4dGVuc2lvbiB0byBzZWUgaWYgdGhlIGN1cnJlbnQgYnJvd3NlciBjYW4gcGxheSB0aGF0IGZpbGUgdHlwZS5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwvZXh0ZW5zaW9uIHRvIHRlc3RcbiAgICAgKiBAcmV0dXJuIElmIHRoZSBmaWxlIGV4dGVuc2lvbiBjYW4gYmUgcGxheWVkXG4gICAgICogQHN0YXRpY1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5Ub25lQXVkaW9CdWZmZXIuc3VwcG9ydHNUeXBlKFwid2F2XCIpOyAvLyByZXR1cm5zIHRydWVcbiAgICAgKiBUb25lLlRvbmVBdWRpb0J1ZmZlci5zdXBwb3J0c1R5cGUoXCJwYXRoL3RvL2ZpbGUud2F2XCIpOyAvLyByZXR1cm5zIHRydWVcbiAgICAgKi9cbiAgICBzdGF0aWMgc3VwcG9ydHNUeXBlKHVybCkge1xuICAgICAgICBjb25zdCBleHRlbnNpb25zID0gdXJsLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gZXh0ZW5zaW9uc1tleHRlbnNpb25zLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhdWRpb1wiKS5jYW5QbGF5VHlwZShcImF1ZGlvL1wiICsgZXh0ZW5zaW9uKTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlICE9PSBcIlwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGEgUHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIGFsbCBvZiB0aGUgYnVmZmVycyBoYXZlIGxvYWRlZFxuICAgICAqL1xuICAgIHN0YXRpYyBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAvLyB0aGlzIG1ha2VzIHN1cmUgdGhhdCB0aGUgZnVuY3Rpb24gaXMgYWx3YXlzIGFzeW5jXG4gICAgICAgICAgICB5aWVsZCBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIHdoaWxlIChUb25lQXVkaW9CdWZmZXIuZG93bmxvYWRzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHlpZWxkIFRvbmVBdWRpb0J1ZmZlci5kb3dubG9hZHNbMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU1RBVElDIE1FVEhPRFNcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBBIHBhdGggd2hpY2ggaXMgcHJlZml4ZWQgYmVmb3JlIGV2ZXJ5IHVybC5cbiAqL1xuVG9uZUF1ZGlvQnVmZmVyLmJhc2VVcmwgPSBcIlwiO1xuLyoqXG4gKiBBbGwgb2YgdGhlIGRvd25sb2Fkc1xuICovXG5Ub25lQXVkaW9CdWZmZXIuZG93bmxvYWRzID0gW107XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9CdWZmZXIuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dFwiO1xuaW1wb3J0IHsgaXNPZmZsaW5lQXVkaW9Db250ZXh0IH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgT2ZmbGluZUF1ZGlvQ29udGV4dFxuICogQGNhdGVnb3J5IENvcmVcbiAqIEBleGFtcGxlXG4gKiAvLyBnZW5lcmF0ZSBhIHNpbmdsZSBjaGFubmVsLCAwLjUgc2Vjb25kIGJ1ZmZlclxuICogY29uc3QgY29udGV4dCA9IG5ldyBUb25lLk9mZmxpbmVDb250ZXh0KDEsIDAuNSwgNDQxMDApO1xuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcih7IGNvbnRleHQgfSk7XG4gKiBjb250ZXh0LnJlbmRlcigpLnRoZW4oYnVmZmVyID0+IHtcbiAqIFx0Y29uc29sZS5sb2coYnVmZmVyLm51bWJlck9mQ2hhbm5lbHMsIGJ1ZmZlci5kdXJhdGlvbik7XG4gKiB9KTtcbiAqL1xuZXhwb3J0IGNsYXNzIE9mZmxpbmVDb250ZXh0IGV4dGVuZHMgQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKHtcbiAgICAgICAgICAgIGNsb2NrU291cmNlOiBcIm9mZmxpbmVcIixcbiAgICAgICAgICAgIGNvbnRleHQ6IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgICAgICBhcmd1bWVudHNbMF0gOiBjcmVhdGVPZmZsaW5lQXVkaW9Db250ZXh0KGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdICogYXJndW1lbnRzWzJdLCBhcmd1bWVudHNbMl0pLFxuICAgICAgICAgICAgbG9va0FoZWFkOiAwLFxuICAgICAgICAgICAgdXBkYXRlSW50ZXJ2YWw6IGlzT2ZmbGluZUF1ZGlvQ29udGV4dChhcmd1bWVudHNbMF0pID9cbiAgICAgICAgICAgICAgICAxMjggLyBhcmd1bWVudHNbMF0uc2FtcGxlUmF0ZSA6IDEyOCAvIGFyZ3VtZW50c1syXSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiT2ZmbGluZUNvbnRleHRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFuIGFydGlmaWNpYWwgY2xvY2sgc291cmNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9jdXJyZW50VGltZSA9IDA7XG4gICAgICAgIHRoaXMuaXNPZmZsaW5lID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fZHVyYXRpb24gPSBpc09mZmxpbmVBdWRpb0NvbnRleHQoYXJndW1lbnRzWzBdKSA/XG4gICAgICAgICAgICBhcmd1bWVudHNbMF0ubGVuZ3RoIC8gYXJndW1lbnRzWzBdLnNhbXBsZVJhdGUgOiBhcmd1bWVudHNbMV07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE92ZXJyaWRlIHRoZSBub3cgbWV0aG9kIHRvIHBvaW50IHRvIHRoZSBpbnRlcm5hbCBjbG9jayB0aW1lXG4gICAgICovXG4gICAgbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudFRpbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNhbWUgYXMgdGhpcy5ub3coKVxuICAgICAqL1xuICAgIGdldCBjdXJyZW50VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIganVzdCB0aGUgY2xvY2sgcG9ydGlvbiBvZiB0aGUgYXVkaW8gY29udGV4dC5cbiAgICAgKi9cbiAgICBfcmVuZGVyQ2xvY2soYXN5bmNocm9ub3VzKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICAgICAgd2hpbGUgKHRoaXMuX2R1cmF0aW9uIC0gdGhpcy5fY3VycmVudFRpbWUgPj0gMCkge1xuICAgICAgICAgICAgICAgIC8vIGludm9rZSBhbGwgdGhlIGNhbGxiYWNrcyBvbiB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJ0aWNrXCIpO1xuICAgICAgICAgICAgICAgIC8vIGluY3JlbWVudCB0aGUgY2xvY2sgaW4gYmxvY2stc2l6ZWQgY2h1bmtzXG4gICAgICAgICAgICAgICAgdGhpcy5fY3VycmVudFRpbWUgKz0gMTI4IC8gdGhpcy5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgIC8vIHlpZWxkIG9uY2UgYSBzZWNvbmQgb2YgYXVkaW9cbiAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgICAgIGNvbnN0IHlpZWxkRXZlcnkgPSBNYXRoLmZsb29yKHRoaXMuc2FtcGxlUmF0ZSAvIDEyOCk7XG4gICAgICAgICAgICAgICAgaWYgKGFzeW5jaHJvbm91cyAmJiBpbmRleCAlIHlpZWxkRXZlcnkgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgeWllbGQgbmV3IFByb21pc2UoZG9uZSA9PiBzZXRUaW1lb3V0KGRvbmUsIDEpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgdGhlIG91dHB1dCBvZiB0aGUgT2ZmbGluZUNvbnRleHRcbiAgICAgKiBAcGFyYW0gYXN5bmNocm9ub3VzIElmIHRoZSBjbG9jayBzaG91bGQgYmUgcmVuZGVyZWQgYXN5bmNocm9ub3VzbHksIHdoaWNoIHdpbGwgbm90IGJsb2NrIHRoZSBtYWluIHRocmVhZCwgYnV0IGJlIHNsaWdodGx5IHNsb3dlci5cbiAgICAgKi9cbiAgICByZW5kZXIoYXN5bmNocm9ub3VzID0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgeWllbGQgdGhpcy53b3JrbGV0c0FyZVJlYWR5KCk7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl9yZW5kZXJDbG9jayhhc3luY2hyb25vdXMpO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0geWllbGQgdGhpcy5fY29udGV4dC5zdGFydFJlbmRlcmluZygpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBUb25lQXVkaW9CdWZmZXIoYnVmZmVyKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBjb250ZXh0XG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PZmZsaW5lQ29udGV4dC5qcy5tYXAiLCJpbXBvcnQgeyB2ZXJzaW9uIH0gZnJvbSBcIi4uL3ZlcnNpb25cIjtcbmltcG9ydCB7IGhhc0F1ZGlvQ29udGV4dCwgdGhlV2luZG93IH0gZnJvbSBcIi4vY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0L0NvbnRleHRcIjtcbmltcG9ydCB7IER1bW15Q29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvRHVtbXlDb250ZXh0XCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IGlzQXVkaW9Db250ZXh0LCBpc09mZmxpbmVBdWRpb0NvbnRleHQgfSBmcm9tIFwiLi91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRoaXMgZHVtbXkgY29udGV4dCBpcyB1c2VkIHRvIGF2b2lkIHRocm93aW5nIGltbWVkaWF0ZSBlcnJvcnMgd2hlbiBpbXBvcnRpbmcgaW4gTm9kZS5qc1xuICovXG5jb25zdCBkdW1teUNvbnRleHQgPSBuZXcgRHVtbXlDb250ZXh0KCk7XG4vKipcbiAqIFRoZSBnbG9iYWwgYXVkaW8gY29udGV4dCB3aGljaCBpcyBnZXRhYmxlIGFuZCBhc3NpZ25hYmxlIHRocm91Z2hcbiAqIGdldENvbnRleHQgYW5kIHNldENvbnRleHRcbiAqL1xubGV0IGdsb2JhbENvbnRleHQgPSBkdW1teUNvbnRleHQ7XG4vKipcbiAqIFJldHVybnMgdGhlIGRlZmF1bHQgc3lzdGVtLXdpZGUgW1tDb250ZXh0XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250ZXh0KCkge1xuICAgIGlmIChnbG9iYWxDb250ZXh0ID09PSBkdW1teUNvbnRleHQgJiYgaGFzQXVkaW9Db250ZXh0KSB7XG4gICAgICAgIHNldENvbnRleHQobmV3IENvbnRleHQoKSk7XG4gICAgfVxuICAgIHJldHVybiBnbG9iYWxDb250ZXh0O1xufVxuLyoqXG4gKiBTZXQgdGhlIGRlZmF1bHQgYXVkaW8gY29udGV4dFxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldENvbnRleHQoY29udGV4dCkge1xuICAgIGlmIChpc0F1ZGlvQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gbmV3IENvbnRleHQoY29udGV4dCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzT2ZmbGluZUF1ZGlvQ29udGV4dChjb250ZXh0KSkge1xuICAgICAgICBnbG9iYWxDb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KGNvbnRleHQpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZ2xvYmFsQ29udGV4dCA9IGNvbnRleHQ7XG4gICAgfVxufVxuLyoqXG4gKiBNb3N0IGJyb3dzZXJzIHdpbGwgbm90IHBsYXkgX2FueV8gYXVkaW8gdW50aWwgYSB1c2VyXG4gKiBjbGlja3Mgc29tZXRoaW5nIChsaWtlIGEgcGxheSBidXR0b24pLiBJbnZva2UgdGhpcyBtZXRob2RcbiAqIG9uIGEgY2xpY2sgb3Iga2V5cHJlc3MgZXZlbnQgaGFuZGxlciB0byBzdGFydCB0aGUgYXVkaW8gY29udGV4dC5cbiAqIE1vcmUgYWJvdXQgdGhlIEF1dG9wbGF5IHBvbGljeVxuICogW2hlcmVdKGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3dlYi91cGRhdGVzLzIwMTcvMDkvYXV0b3BsYXktcG9saWN5LWNoYW5nZXMjd2ViYXVkaW8pXG4gKiBAZXhhbXBsZVxuICogZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImJ1dHRvblwiKS5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYXN5bmMgKCkgPT4ge1xuICogXHRhd2FpdCBUb25lLnN0YXJ0KCk7XG4gKiBcdGNvbnNvbGUubG9nKFwiY29udGV4dCBzdGFydGVkXCIpO1xuICogfSk7XG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhcnQoKSB7XG4gICAgcmV0dXJuIGdsb2JhbENvbnRleHQucmVzdW1lKCk7XG59XG4vKipcbiAqIExvZyBUb25lLmpzICsgdmVyc2lvbiBpbiB0aGUgY29uc29sZS5cbiAqL1xuaWYgKHRoZVdpbmRvdyAmJiAhdGhlV2luZG93LlRPTkVfU0lMRU5DRV9MT0dHSU5HKSB7XG4gICAgbGV0IHByZWZpeCA9IFwidlwiO1xuICAgIGlmICh2ZXJzaW9uID09PSBcImRldlwiKSB7XG4gICAgICAgIHByZWZpeCA9IFwiXCI7XG4gICAgfVxuICAgIGNvbnN0IHByaW50U3RyaW5nID0gYCAqIFRvbmUuanMgJHtwcmVmaXh9JHt2ZXJzaW9ufSAqIGA7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBjb25zb2xlLmxvZyhgJWMke3ByaW50U3RyaW5nfWAsIFwiYmFja2dyb3VuZDogIzAwMDsgY29sb3I6ICNmZmZcIik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HbG9iYWwuanMubWFwIiwiLyoqXG4gKiBFcXVhbCBwb3dlciBnYWluIHNjYWxlLiBHb29kIGZvciBjcm9zcy1mYWRpbmcuXG4gKiBAcGFyYW0gIHBlcmNlbnQgKDAtMSlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVxdWFsUG93ZXJTY2FsZShwZXJjZW50KSB7XG4gICAgY29uc3QgcGlGYWN0b3IgPSAwLjUgKiBNYXRoLlBJO1xuICAgIHJldHVybiBNYXRoLnNpbihwZXJjZW50ICogcGlGYWN0b3IpO1xufVxuLyoqXG4gKiBDb252ZXJ0IGRlY2liZWxzIGludG8gZ2Fpbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRiVG9HYWluKGRiKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDEwLCBkYiAvIDIwKTtcbn1cbi8qKlxuICogQ29udmVydCBnYWluIHRvIGRlY2liZWxzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2FpblRvRGIoZ2Fpbikge1xuICAgIHJldHVybiAyMCAqIChNYXRoLmxvZyhnYWluKSAvIE1hdGguTE4xMCk7XG59XG4vKipcbiAqIENvbnZlcnQgYW4gaW50ZXJ2YWwgKGluIHNlbWl0b25lcykgdG8gYSBmcmVxdWVuY3kgcmF0aW8uXG4gKiBAcGFyYW0gaW50ZXJ2YWwgdGhlIG51bWJlciBvZiBzZW1pdG9uZXMgYWJvdmUgdGhlIGJhc2Ugbm90ZVxuICogQGV4YW1wbGVcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKDApOyAvLyAxXG4gKiBUb25lLmludGVydmFsVG9GcmVxdWVuY3lSYXRpbygxMik7IC8vIDJcbiAqIFRvbmUuaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKC0xMik7IC8vIDAuNVxuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSB7XG4gICAgcmV0dXJuIE1hdGgucG93KDIsIChpbnRlcnZhbCAvIDEyKSk7XG59XG4vKipcbiAqIFRoZSBHbG9iYWwgW2NvbmNlcnQgdHVuaW5nIHBpdGNoXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db25jZXJ0X3BpdGNoKSB3aGljaCBpcyB1c2VkXG4gKiB0byBnZW5lcmF0ZSBhbGwgdGhlIG90aGVyIHBpdGNoIHZhbHVlcyBmcm9tIG5vdGVzLiBBNCdzIHZhbHVlcyBpbiBIZXJ0ei5cbiAqL1xubGV0IEE0ID0gNDQwO1xuZXhwb3J0IGZ1bmN0aW9uIGdldEE0KCkge1xuICAgIHJldHVybiBBNDtcbn1cbmV4cG9ydCBmdW5jdGlvbiBzZXRBNChmcmVxKSB7XG4gICAgQTQgPSBmcmVxO1xufVxuLyoqXG4gKiBDb252ZXJ0IGEgZnJlcXVlbmN5IHZhbHVlIHRvIGEgTUlESSBub3RlLlxuICogQHBhcmFtIGZyZXF1ZW5jeSBUaGUgdmFsdWUgdG8gZnJlcXVlbmN5IHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAZXhhbXBsZVxuICogVG9uZS5mdG9tKDQ0MCk7IC8vIHJldHVybnMgNjlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZ0b20oZnJlcXVlbmN5KSB7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoZnRvbWYoZnJlcXVlbmN5KSk7XG59XG4vKipcbiAqIENvbnZlcnQgYSBmcmVxdWVuY3kgdG8gYSBmbG9hdGluZyBwb2ludCBtaWRpIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmdG9tZihmcmVxdWVuY3kpIHtcbiAgICByZXR1cm4gNjkgKyAxMiAqIE1hdGgubG9nMihmcmVxdWVuY3kgLyBBNCk7XG59XG4vKipcbiAqIENvbnZlcnQgYSBNSURJIG5vdGUgdG8gZnJlcXVlbmN5IHZhbHVlLlxuICogQHBhcmFtICBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuICogQHJldHVybiBUaGUgY29ycmVzcG9uZGluZyBmcmVxdWVuY3kgdmFsdWVcbiAqIEBleGFtcGxlXG4gKiBUb25lLm10b2YoNjkpOyAvLyA0NDBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG10b2YobWlkaSkge1xuICAgIHJldHVybiBBNCAqIE1hdGgucG93KDIsIChtaWRpIC0gNjkpIC8gMTIpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q29udmVyc2lvbnMuanMubWFwIiwiaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1N0cmluZywgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBUaW1lQmFzZSBpcyBhIGZsZXhpYmxlIGVuY29kaW5nIG9mIHRpbWUgd2hpY2ggY2FuIGJlIGV2YWx1YXRlZCB0byBhbmQgZnJvbSBhIHN0cmluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVCYXNlQ2xhc3MgZXh0ZW5kcyBUb25lIHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gY29udGV4dCBUaGUgY29udGV4dCBhc3NvY2lhdGVkIHdpdGggdGhlIHRpbWUgdmFsdWUuIFVzZWQgdG8gY29tcHV0ZVxuICAgICAqIFRyYW5zcG9ydCBhbmQgY29udGV4dC1yZWxhdGl2ZSB0aW1pbmcuXG4gICAgICogQHBhcmFtICB2YWx1ZSAgVGhlIHRpbWUgdmFsdWUgYXMgYSBudW1iZXIsIHN0cmluZyBvciBvYmplY3RcbiAgICAgKiBAcGFyYW0gIHVuaXRzICBVbml0IHZhbHVlc1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGNvbnRleHQsIHZhbHVlLCB1bml0cykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGRlZmF1bHQgdW5pdHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZGVmYXVsdFVuaXRzID0gXCJzXCI7XG4gICAgICAgIHRoaXMuX3ZhbCA9IHZhbHVlO1xuICAgICAgICB0aGlzLl91bml0cyA9IHVuaXRzO1xuICAgICAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0aGlzLl9leHByZXNzaW9ucyA9IHRoaXMuX2dldEV4cHJlc3Npb25zKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFsbCBvZiB0aGUgdGltZSBlbmNvZGluZyBleHByZXNzaW9uc1xuICAgICAqL1xuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGh6OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeVRvVW5pdHMocGFyc2VGbG9hdCh2YWx1ZSkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KWh6JC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGk6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fdGlja3NUb1VuaXRzKHBhcnNlSW50KHZhbHVlLCAxMCkpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKWkkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbToge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VJbnQodmFsdWUsIDEwKSAqIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCspbSQvaSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUsIGRvdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzY2FsYXIgPSBkb3QgPT09IFwiLlwiID8gMS41IDogMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG51bWVyaWNWYWx1ZSA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyh0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpICogc2NhbGFyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg0IC8gbnVtZXJpY1ZhbHVlKSAqIHNjYWxhcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKW4oXFwuPykkL2ksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbnVtYmVyOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuZGVmYXVsdFVuaXRzXS5tZXRob2QuY2FsbCh0aGlzLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pJC8sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgczoge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9zZWNvbmRzVG9Vbml0cyhwYXJzZUZsb2F0KHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFxcZCsoPzpcXC5cXGQrKT8pcyQvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNhbXBsZXM6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcGFyc2VJbnQodmFsdWUsIDEwKSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKXNhbXBsZXMkLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0OiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gcGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2JlYXRzVG9Vbml0cyg4IC8gKE1hdGguZmxvb3IobnVtZXJpY1ZhbHVlKSAqIDMpKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyl0JC9pLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAobSwgcSwgcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwO1xuICAgICAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChxICYmIHEgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHMpIC8gNCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/KTooXFxkKyg/OlxcLlxcZCspPyk6PyhcXGQrKD86XFwuXFxkKyk/KT8kLyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VkFMVUUgT0ZcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBFdmFsdWF0ZSB0aGUgdGltZSB2YWx1ZS4gUmV0dXJucyB0aGUgdGltZSBpbiBzZWNvbmRzLlxuICAgICAqL1xuICAgIHZhbHVlT2YoKSB7XG4gICAgICAgIGlmICh0aGlzLl92YWwgaW5zdGFuY2VvZiBUaW1lQmFzZUNsYXNzKSB7XG4gICAgICAgICAgICB0aGlzLmZyb21UeXBlKHRoaXMuX3ZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVW5kZWYodGhpcy5fdmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25vQXJnKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNTdHJpbmcodGhpcy5fdmFsKSAmJiBpc1VuZGVmKHRoaXMuX3VuaXRzKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCB1bml0cyBpbiB0aGlzLl9leHByZXNzaW9ucykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9leHByZXNzaW9uc1t1bml0c10ucmVnZXhwLnRlc3QodGhpcy5fdmFsLnRyaW0oKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fdW5pdHMgPSB1bml0cztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzT2JqZWN0KHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHR5cGVOYW1lIGluIHRoaXMuX3ZhbCkge1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fdmFsW3R5cGVOYW1lXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSB0aGlzLl92YWxbdHlwZU5hbWVdO1xuICAgICAgICAgICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWUgPSAobmV3IHRoaXMuY29uc3RydWN0b3IodGhpcy5jb250ZXh0LCB0eXBlTmFtZSkpLnZhbHVlT2YoKSAqIHF1YW50aXR5O1xuICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0aW1lO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0b3RhbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuX3VuaXRzKSkge1xuICAgICAgICAgICAgY29uc3QgZXhwciA9IHRoaXMuX2V4cHJlc3Npb25zW3RoaXMuX3VuaXRzXTtcbiAgICAgICAgICAgIGNvbnN0IG1hdGNoaW5nID0gdGhpcy5fdmFsLnRvU3RyaW5nKCkudHJpbSgpLm1hdGNoKGV4cHIucmVnZXhwKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGluZykge1xuICAgICAgICAgICAgICAgIHJldHVybiBleHByLm1ldGhvZC5hcHBseSh0aGlzLCBtYXRjaGluZy5zbGljZSgxKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwci5tZXRob2QuY2FsbCh0aGlzLCB0aGlzLl92YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRoaXMuX3ZhbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHRoaXMuX3ZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fdmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0VU5JVCBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gMSAvIGZyZXE7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gKDYwIC8gdGhpcy5fZ2V0QnBtKCkpICogYmVhdHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgc2Vjb25kIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX3NlY29uZHNUb1VuaXRzKHNlY29uZHMpIHtcbiAgICAgICAgcmV0dXJuIHNlY29uZHM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gKHRpY2tzICogKHRoaXMuX2JlYXRzVG9Vbml0cygxKSkgLyB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdpdGggbm8gYXJndW1lbnRzLCByZXR1cm4gJ25vdydcbiAgICAgKi9cbiAgICBfbm9BcmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ub3coKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRURU1QTyBDT05WRVJTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgYnBtXG4gICAgICovXG4gICAgX2dldEJwbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuYnBtLnZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWVTaWduYXR1cmVcbiAgICAgKi9cbiAgICBfZ2V0VGltZVNpZ25hdHVyZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQudGltZVNpZ25hdHVyZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBQUFEgb3IgMTkyIGlmIFRyYW5zcG9ydCBpcyBub3QgYXZhaWxhYmxlXG4gICAgICovXG4gICAgX2dldFBQUSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC50cmFuc3BvcnQuUFBRO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdENPTlZFUlNJT04gSU5URVJGQUNFXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQ29lcmNlIGEgdGltZSB0eXBlIGludG8gdGhpcyB1bml0cyB0eXBlLlxuICAgICAqIEBwYXJhbSB0eXBlIEFueSB0aW1lIHR5cGUgdW5pdHNcbiAgICAgKi9cbiAgICBmcm9tVHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3VuaXRzID0gdW5kZWZpbmVkO1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZGVmYXVsdFVuaXRzKSB7XG4gICAgICAgICAgICBjYXNlIFwic1wiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9TZWNvbmRzKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFwiaVwiOlxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbCA9IHR5cGUudG9UaWNrcygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImh6XCI6XG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsID0gdHlwZS50b0ZyZXF1ZW5jeSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcIm1pZGlcIjpcbiAgICAgICAgICAgICAgICB0aGlzLl92YWwgPSB0eXBlLnRvTWlkaSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIGluIGhlcnR6XG4gICAgICovXG4gICAgdG9GcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiAxIC8gdGhpcy50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNhbXBsZXNcbiAgICAgKi9cbiAgICB0b1NhbXBsZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiBtaWxsaXNlY29uZHMuXG4gICAgICovXG4gICAgdG9NaWxsaXNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcygpICogMTAwMDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lQmFzZS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgZnRvbSB9IGZyb20gXCIuL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBUaW1lQmFzZUNsYXNzIH0gZnJvbSBcIi4vVGltZUJhc2VcIjtcbi8qKlxuICogVGltZUNsYXNzIGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIGFuZCBkZWNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIFRpbWVDbGFzcyBjYW4gYmUgcGFzc2VkIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAcGFyYW0gIHZhbCAgICBUaGUgdGltZSB2YWx1ZS5cbiAqIEBwYXJhbSAgdW5pdHMgIFRoZSB1bml0cyBvZiB0aGUgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdGltZSA9IFRvbmUuVGltZShcIjRuXCIpOyAvLyBhIHF1YXJ0ZXIgbm90ZVxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRpbWVDbGFzcyBleHRlbmRzIFRpbWVCYXNlQ2xhc3Mge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRpbWVDbGFzc1wiO1xuICAgIH1cbiAgICBfZ2V0RXhwcmVzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHN1cGVyLl9nZXRFeHByZXNzaW9ucygpLCB7XG4gICAgICAgICAgICBub3c6IHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6IChjYXB0dXJlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9ub3coKSArIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgY2FwdHVyZSkudmFsdWVPZigpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXlxcKyguKykvLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHF1YW50aXplOiB7XG4gICAgICAgICAgICAgICAgbWV0aG9kOiAoY2FwdHVyZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBxdWFudFRvID0gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIGNhcHR1cmUpLnZhbHVlT2YoKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NlY29uZHNUb1VuaXRzKHRoaXMuY29udGV4dC50cmFuc3BvcnQubmV4dFN1YmRpdmlzaW9uKHF1YW50VG8pKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlZ2V4cDogL15AKC4rKS8sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUXVhbnRpemUgdGhlIHRpbWUgYnkgdGhlIGdpdmVuIHN1YmRpdmlzaW9uLiBPcHRpb25hbGx5IGFkZCBhXG4gICAgICogcGVyY2VudGFnZSB3aGljaCB3aWxsIG1vdmUgdGhlIHRpbWUgdmFsdWUgdG93YXJkcyB0aGUgaWRlYWxcbiAgICAgKiBxdWFudGl6ZWQgdmFsdWUgYnkgdGhhdCBwZXJjZW50YWdlLlxuICAgICAqIEBwYXJhbSAgc3ViZGl2ICAgIFRoZSBzdWJkaXZpc2lvbiB0byBxdWFudGl6ZSB0b1xuICAgICAqIEBwYXJhbSAgcGVyY2VudCAgTW92ZSB0aGUgdGltZSB2YWx1ZSB0b3dhcmRzIHRoZSBxdWFudGl6ZWQgdmFsdWUgYnkgYSBwZXJjZW50YWdlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5UaW1lKDIxKS5xdWFudGl6ZSgyKTsgLy8gcmV0dXJucyAyMlxuICAgICAqIFRvbmUuVGltZSgwLjYpLnF1YW50aXplKFwiNG5cIiwgMC41KTsgLy8gcmV0dXJucyAwLjU1XG4gICAgICovXG4gICAgcXVhbnRpemUoc3ViZGl2LCBwZXJjZW50ID0gMSkge1xuICAgICAgICBjb25zdCBzdWJkaXZpc2lvbiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKHRoaXMuY29udGV4dCwgc3ViZGl2KS52YWx1ZU9mKCk7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWx1ZU9mKCk7XG4gICAgICAgIGNvbnN0IG11bHRpcGxlID0gTWF0aC5yb3VuZCh2YWx1ZSAvIHN1YmRpdmlzaW9uKTtcbiAgICAgICAgY29uc3QgaWRlYWwgPSBtdWx0aXBsZSAqIHN1YmRpdmlzaW9uO1xuICAgICAgICBjb25zdCBkaWZmID0gaWRlYWwgLSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHZhbHVlICsgZGlmZiAqIHBlcmNlbnQ7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIFRpbWUgdG8gTm90YXRpb24uIFRoZSBub3RhdGlvbiB2YWx1ZXMgYXJlIHdpbGwgYmUgdGhlXG4gICAgICogY2xvc2VzdCByZXByZXNlbnRhdGlvbiBiZXR3ZWVuIDFtIHRvIDEyOHRoIG5vdGUuXG4gICAgICogQHJldHVybiB7Tm90YXRpb259XG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBpZiB0aGUgVHJhbnNwb3J0IGlzIGF0IDEyMGJwbTpcbiAgICAgKiBUb25lLlRpbWUoMikudG9Ob3RhdGlvbigpOyAvLyByZXR1cm5zIFwiMW1cIlxuICAgICAqL1xuICAgIHRvTm90YXRpb24oKSB7XG4gICAgICAgIGNvbnN0IHRpbWUgPSB0aGlzLnRvU2Vjb25kcygpO1xuICAgICAgICBjb25zdCB0ZXN0Tm90YXRpb25zID0gW1wiMW1cIl07XG4gICAgICAgIGZvciAobGV0IHBvd2VyID0gMTsgcG93ZXIgPCA5OyBwb3dlcisrKSB7XG4gICAgICAgICAgICBjb25zdCBzdWJkaXYgPSBNYXRoLnBvdygyLCBwb3dlcik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJuLlwiKTtcbiAgICAgICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChzdWJkaXYgKyBcIm5cIik7XG4gICAgICAgICAgICB0ZXN0Tm90YXRpb25zLnB1c2goc3ViZGl2ICsgXCJ0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHRlc3ROb3RhdGlvbnMucHVzaChcIjBcIik7XG4gICAgICAgIC8vIGZpbmQgdGhlIGNsb3NldHMgbm90YXRpb24gcmVwcmVzZW50YXRpb25cbiAgICAgICAgbGV0IGNsb3Nlc3QgPSB0ZXN0Tm90YXRpb25zWzBdO1xuICAgICAgICBsZXQgY2xvc2VzdFNlY29uZHMgPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGVzdE5vdGF0aW9uc1swXSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHRlc3ROb3RhdGlvbnMuZm9yRWFjaChub3RhdGlvbiA9PiB7XG4gICAgICAgICAgICBjb25zdCBub3RhdGlvblNlY29uZHMgPSBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgbm90YXRpb24pLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgaWYgKE1hdGguYWJzKG5vdGF0aW9uU2Vjb25kcyAtIHRpbWUpIDwgTWF0aC5hYnMoY2xvc2VzdFNlY29uZHMgLSB0aW1lKSkge1xuICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBub3RhdGlvbjtcbiAgICAgICAgICAgICAgICBjbG9zZXN0U2Vjb25kcyA9IG5vdGF0aW9uU2Vjb25kcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjbG9zZXN0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgZW5jb2RlZCBhcyBCYXJzOkJlYXRzOlNpeHRlZW50aHMuXG4gICAgICovXG4gICAgdG9CYXJzQmVhdHNTaXh0ZWVudGhzKCkge1xuICAgICAgICBjb25zdCBxdWFydGVyVGltZSA9IHRoaXMuX2JlYXRzVG9Vbml0cygxKTtcbiAgICAgICAgbGV0IHF1YXJ0ZXJzID0gdGhpcy52YWx1ZU9mKCkgLyBxdWFydGVyVGltZTtcbiAgICAgICAgcXVhcnRlcnMgPSBwYXJzZUZsb2F0KHF1YXJ0ZXJzLnRvRml4ZWQoNCkpO1xuICAgICAgICBjb25zdCBtZWFzdXJlcyA9IE1hdGguZmxvb3IocXVhcnRlcnMgLyB0aGlzLl9nZXRUaW1lU2lnbmF0dXJlKCkpO1xuICAgICAgICBsZXQgc2l4dGVlbnRocyA9IChxdWFydGVycyAlIDEpICogNDtcbiAgICAgICAgcXVhcnRlcnMgPSBNYXRoLmZsb29yKHF1YXJ0ZXJzKSAlIHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKTtcbiAgICAgICAgY29uc3Qgc2l4dGVlbnRoU3RyaW5nID0gc2l4dGVlbnRocy50b1N0cmluZygpO1xuICAgICAgICBpZiAoc2l4dGVlbnRoU3RyaW5nLmxlbmd0aCA+IDMpIHtcbiAgICAgICAgICAgIC8vIHRoZSBhZGRpdGlvbmFsIHBhcnNlRmxvYXQgcmVtb3ZlcyBpbnNpZ25pZmljYW50IHRyYWlsaW5nIHplcm9lc1xuICAgICAgICAgICAgc2l4dGVlbnRocyA9IHBhcnNlRmxvYXQocGFyc2VGbG9hdChzaXh0ZWVudGhTdHJpbmcpLnRvRml4ZWQoMykpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb2dyZXNzID0gW21lYXN1cmVzLCBxdWFydGVycywgc2l4dGVlbnRoc107XG4gICAgICAgIHJldHVybiBwcm9ncmVzcy5qb2luKFwiOlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHRpY2tzLlxuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBjb25zdCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHF1YXJ0ZXJzICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHRpbWUgaW4gc2Vjb25kcy5cbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBhcyBhIG1pZGkgbm90ZS5cbiAgICAgKi9cbiAgICB0b01pZGkoKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHRoaXMudG9GcmVxdWVuY3koKSk7XG4gICAgfVxuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQubm93KCk7XG4gICAgfVxufVxuLyoqXG4gKiBDcmVhdGUgYSBUaW1lQ2xhc3MgZnJvbSBhIHRpbWUgc3RyaW5nIG9yIG51bWJlci4gVGhlIHRpbWUgaXMgY29tcHV0ZWQgYWdhaW5zdCB0aGVcbiAqIGdsb2JhbCBUb25lLkNvbnRleHQuIFRvIHVzZSBhIHNwZWNpZmljIGNvbnRleHQsIHVzZSBbW1RpbWVDbGFzc11dXG4gKiBAcGFyYW0gdmFsdWUgQSB2YWx1ZSB3aGljaCByZXByZXNlbnRzIHRpbWVcbiAqIEBwYXJhbSB1bml0cyBUaGUgdmFsdWUncyB1bml0cyBpZiB0aGV5IGNhbid0IGJlIGluZmVycmVkIGJ5IHRoZSB2YWx1ZS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKiBAZXhhbXBsZVxuICogY29uc3QgdGltZSA9IFRvbmUuVGltZShcIjRuXCIpLnRvU2Vjb25kcygpO1xuICogY29uc29sZS5sb2codGltZSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3Qgbm90ZSA9IFRvbmUuVGltZSgxKS50b05vdGF0aW9uKCk7XG4gKiBjb25zb2xlLmxvZyhub3RlKTtcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmcmVxID0gVG9uZS5UaW1lKDAuNSkudG9GcmVxdWVuY3koKTtcbiAqIGNvbnNvbGUubG9nKGZyZXEpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gVGltZSh2YWx1ZSwgdW5pdHMpIHtcbiAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaW1lLmpzLm1hcCIsImltcG9ydCB7IGdldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8sIG10b2YgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgZnRvbSwgZ2V0QTQsIHNldEE0IH0gZnJvbSBcIi4vQ29udmVyc2lvbnNcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuL1RpbWVcIjtcbi8qKlxuICogRnJlcXVlbmN5IGlzIGEgcHJpbWl0aXZlIHR5cGUgZm9yIGVuY29kaW5nIEZyZXF1ZW5jeSB2YWx1ZXMuXG4gKiBFdmVudHVhbGx5IGFsbCB0aW1lIHZhbHVlcyBhcmUgZXZhbHVhdGVkIHRvIGhlcnR6IHVzaW5nIHRoZSBgdmFsdWVPZmAgbWV0aG9kLlxuICogQGV4YW1wbGVcbiAqIFRvbmUuRnJlcXVlbmN5KFwiQzNcIik7IC8vIDI2MVxuICogVG9uZS5GcmVxdWVuY3koMzgsIFwibWlkaVwiKTtcbiAqIFRvbmUuRnJlcXVlbmN5KFwiQzNcIikudHJhbnNwb3NlKDQpO1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIEZyZXF1ZW5jeUNsYXNzIGV4dGVuZHMgVGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGcmVxdWVuY3lcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcImh6XCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBbY29uY2VydCB0dW5pbmcgcGl0Y2hdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbmNlcnRfcGl0Y2gpIHdoaWNoIGlzIHVzZWRcbiAgICAgKiB0byBnZW5lcmF0ZSBhbGwgdGhlIG90aGVyIHBpdGNoIHZhbHVlcyBmcm9tIG5vdGVzLiBBNCdzIHZhbHVlcyBpbiBIZXJ0ei5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IEE0KCkge1xuICAgICAgICByZXR1cm4gZ2V0QTQoKTtcbiAgICB9XG4gICAgc3RhdGljIHNldCBBNChmcmVxKSB7XG4gICAgICAgIHNldEE0KGZyZXEpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdEFVR01FTlQgQkFTRSBFWFBSRVNTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIF9nZXRFeHByZXNzaW9ucygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN1cGVyLl9nZXRFeHByZXNzaW9ucygpLCB7XG4gICAgICAgICAgICBtaWRpOiB7XG4gICAgICAgICAgICAgICAgcmVnZXhwOiAvXihcXGQrKD86XFwuXFxkKyk/bWlkaSkvLFxuICAgICAgICAgICAgICAgIG1ldGhvZCh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VW5pdHMgPT09IFwibWlkaVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRnJlcXVlbmN5Q2xhc3MubXRvZih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5vdGU6IHtcbiAgICAgICAgICAgICAgICByZWdleHA6IC9eKFthLWddezF9KD86YnwjfHh8YmIpPykoLT9bMC05XSspL2ksXG4gICAgICAgICAgICAgICAgbWV0aG9kKHBpdGNoLCBvY3RhdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5kZXggPSBub3RlVG9TY2FsZUluZGV4W3BpdGNoLnRvTG93ZXJDYXNlKCldO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBub3RlTnVtYmVyID0gaW5kZXggKyAocGFyc2VJbnQob2N0YXZlLCAxMCkgKyAxKSAqIDEyO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWZhdWx0VW5pdHMgPT09IFwibWlkaVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm90ZU51bWJlcjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBGcmVxdWVuY3lDbGFzcy5tdG9mKG5vdGVOdW1iZXIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0cjoge1xuICAgICAgICAgICAgICAgIHJlZ2V4cDogL14oXFxkKyg/OlxcLlxcZCspPyk6KFxcZCsoPzpcXC5cXGQrKT8pOj8oXFxkKyg/OlxcLlxcZCspPyk/LyxcbiAgICAgICAgICAgICAgICBtZXRob2QobSwgcSwgcykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdG90YWwgPSAxO1xuICAgICAgICAgICAgICAgICAgICBpZiAobSAmJiBtICE9PSBcIjBcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKj0gdGhpcy5fYmVhdHNUb1VuaXRzKHRoaXMuX2dldFRpbWVTaWduYXR1cmUoKSAqIHBhcnNlRmxvYXQobSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChxICYmIHEgIT09IFwiMFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCAqPSB0aGlzLl9iZWF0c1RvVW5pdHMocGFyc2VGbG9hdChxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMgJiYgcyAhPT0gXCIwXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICo9IHRoaXMuX2JlYXRzVG9Vbml0cyhwYXJzZUZsb2F0KHMpIC8gNCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRvdGFsO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRFWFBSRVNTSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFRyYW5zcG9zZXMgdGhlIGZyZXF1ZW5jeSBieSB0aGUgZ2l2ZW4gbnVtYmVyIG9mIHNlbWl0b25lcy5cbiAgICAgKiBAcmV0dXJuICBBIG5ldyB0cmFuc3Bvc2VkIGZyZXF1ZW5jeVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS50cmFuc3Bvc2UoMyk7IC8vIFwiQzVcIlxuICAgICAqL1xuICAgIHRyYW5zcG9zZShpbnRlcnZhbCkge1xuICAgICAgICByZXR1cm4gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy52YWx1ZU9mKCkgKiBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8oaW50ZXJ2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGFrZXMgYW4gYXJyYXkgb2Ygc2VtaXRvbmUgaW50ZXJ2YWxzIGFuZCByZXR1cm5zXG4gICAgICogYW4gYXJyYXkgb2YgZnJlcXVlbmNpZXMgdHJhbnNwb3NlZCBieSB0aG9zZSBpbnRlcnZhbHMuXG4gICAgICogQHJldHVybiAgUmV0dXJucyBhbiBhcnJheSBvZiBGcmVxdWVuY2llc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koXCJBNFwiKS5oYXJtb25pemUoWzAsIDMsIDddKTsgLy8gW1wiQTRcIiwgXCJDNVwiLCBcIkU1XCJdXG4gICAgICovXG4gICAgaGFybW9uaXplKGludGVydmFscykge1xuICAgICAgICByZXR1cm4gaW50ZXJ2YWxzLm1hcChpbnRlcnZhbCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy50cmFuc3Bvc2UoaW50ZXJ2YWwpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRVTklUIENPTlZFUlNJT05TXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgZnJlcXVlbmN5IGFzIGEgTUlESSBub3RlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLkZyZXF1ZW5jeShcIkM0XCIpLnRvTWlkaSgpOyAvLyA2MFxuICAgICAqL1xuICAgIHRvTWlkaSgpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20odGhpcy52YWx1ZU9mKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgaW4gU2NpZW50aWZpYyBQaXRjaCBOb3RhdGlvblxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5GcmVxdWVuY3koNjksIFwibWlkaVwiKS50b05vdGUoKTsgLy8gXCJBNFwiXG4gICAgICovXG4gICAgdG9Ob3RlKCkge1xuICAgICAgICBjb25zdCBmcmVxID0gdGhpcy50b0ZyZXF1ZW5jeSgpO1xuICAgICAgICBjb25zdCBsb2cgPSBNYXRoLmxvZzIoZnJlcSAvIEZyZXF1ZW5jeUNsYXNzLkE0KTtcbiAgICAgICAgbGV0IG5vdGVOdW1iZXIgPSBNYXRoLnJvdW5kKDEyICogbG9nKSArIDU3O1xuICAgICAgICBjb25zdCBvY3RhdmUgPSBNYXRoLmZsb29yKG5vdGVOdW1iZXIgLyAxMik7XG4gICAgICAgIGlmIChvY3RhdmUgPCAwKSB7XG4gICAgICAgICAgICBub3RlTnVtYmVyICs9IC0xMiAqIG9jdGF2ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBub3RlTmFtZSA9IHNjYWxlSW5kZXhUb05vdGVbbm90ZU51bWJlciAlIDEyXTtcbiAgICAgICAgcmV0dXJuIG5vdGVOYW1lICsgb2N0YXZlLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZHVyYXRpb24gb2Ygb25lIGN5Y2xlIGluIHNlY29uZHMuXG4gICAgICovXG4gICAgdG9TZWNvbmRzKCkge1xuICAgICAgICByZXR1cm4gMSAvIHN1cGVyLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGR1cmF0aW9uIG9mIG9uZSBjeWNsZSBpbiB0aWNrc1xuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIGNvbnN0IHF1YXJ0ZXJUaW1lID0gdGhpcy5fYmVhdHNUb1VuaXRzKDEpO1xuICAgICAgICBjb25zdCBxdWFydGVycyA9IHRoaXMudmFsdWVPZigpIC8gcXVhcnRlclRpbWU7XG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHF1YXJ0ZXJzICogdGhpcy5fZ2V0UFBRKCkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFVOSVQgQ09OVkVSU0lPTlMgSEVMUEVSU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIFdpdGggbm8gYXJndW1lbnRzLCByZXR1cm4gMFxuICAgICAqL1xuICAgIF9ub0FyZygpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgZnJlcXVlbmN5IGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2ZyZXF1ZW5jeVRvVW5pdHMoZnJlcSkge1xuICAgICAgICByZXR1cm4gZnJlcTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiAxIC8gKCh0aWNrcyAqIDYwKSAvICh0aGlzLl9nZXRCcG0oKSAqIHRoaXMuX2dldFBQUSgpKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGJlYXRzIGluIHRoZSBjdXJyZW50IHVuaXRzXG4gICAgICovXG4gICAgX2JlYXRzVG9Vbml0cyhiZWF0cykge1xuICAgICAgICByZXR1cm4gMSAvIHN1cGVyLl9iZWF0c1RvVW5pdHMoYmVhdHMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiAxIC8gc2Vjb25kcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIE1JREkgbm90ZSB0byBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICogQHBhcmFtICBtaWRpIFRoZSBtaWRpIG51bWJlciB0byBjb252ZXJ0LlxuICAgICAqIEByZXR1cm4gVGhlIGNvcnJlc3BvbmRpbmcgZnJlcXVlbmN5IHZhbHVlXG4gICAgICovXG4gICAgc3RhdGljIG10b2YobWlkaSkge1xuICAgICAgICByZXR1cm4gbXRvZihtaWRpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCBhIGZyZXF1ZW5jeSB2YWx1ZSB0byBhIE1JREkgbm90ZS5cbiAgICAgKiBAcGFyYW0gZnJlcXVlbmN5IFRoZSB2YWx1ZSB0byBmcmVxdWVuY3kgdmFsdWUgdG8gY29udmVydC5cbiAgICAgKi9cbiAgICBzdGF0aWMgZnRvbShmcmVxdWVuY3kpIHtcbiAgICAgICAgcmV0dXJuIGZ0b20oZnJlcXVlbmN5KTtcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0RlJFUVVFTkNZIENPTlZFUlNJT05TXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogTm90ZSB0byBzY2FsZSBpbmRleC5cbiAqIEBoaWRkZW5cbiAqL1xuY29uc3Qgbm90ZVRvU2NhbGVJbmRleCA9IHtcbiAgICBjYmI6IC0yLCBjYjogLTEsIGM6IDAsIFwiYyNcIjogMSwgY3g6IDIsXG4gICAgZGJiOiAwLCBkYjogMSwgZDogMiwgXCJkI1wiOiAzLCBkeDogNCxcbiAgICBlYmI6IDIsIGViOiAzLCBlOiA0LCBcImUjXCI6IDUsIGV4OiA2LFxuICAgIGZiYjogMywgZmI6IDQsIGY6IDUsIFwiZiNcIjogNiwgZng6IDcsXG4gICAgZ2JiOiA1LCBnYjogNiwgZzogNywgXCJnI1wiOiA4LCBneDogOSxcbiAgICBhYmI6IDcsIGFiOiA4LCBhOiA5LCBcImEjXCI6IDEwLCBheDogMTEsXG4gICAgYmJiOiA5LCBiYjogMTAsIGI6IDExLCBcImIjXCI6IDEyLCBieDogMTMsXG59O1xuLyoqXG4gKiBzY2FsZSBpbmRleCB0byBub3RlIChzaGFycHMpXG4gKiBAaGlkZGVuXG4gKi9cbmNvbnN0IHNjYWxlSW5kZXhUb05vdGUgPSBbXCJDXCIsIFwiQyNcIiwgXCJEXCIsIFwiRCNcIiwgXCJFXCIsIFwiRlwiLCBcIkYjXCIsIFwiR1wiLCBcIkcjXCIsIFwiQVwiLCBcIkEjXCIsIFwiQlwiXTtcbi8qKlxuICogQ29udmVydCBhIHZhbHVlIGludG8gYSBGcmVxdWVuY3lDbGFzcyBvYmplY3QuXG4gKiBAY2F0ZWdvcnkgVW5pdFxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1pZGkgPSBUb25lLkZyZXF1ZW5jeShcIkMzXCIpLnRvTWlkaSgpO1xuICogY29uc29sZS5sb2cobWlkaSk7XG4gKiBAZXhhbXBsZVxuICogY29uc3QgaGVydHogPSBUb25lLkZyZXF1ZW5jeSgzOCwgXCJtaWRpXCIpLnRvRnJlcXVlbmN5KCk7XG4gKiBjb25zb2xlLmxvZyhoZXJ0eik7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBGcmVxdWVuY3kodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBGcmVxdWVuY3lDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GcmVxdWVuY3kuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuL1RpbWVcIjtcbi8qKlxuICogVHJhbnNwb3J0VGltZSBpcyBhIHRoZSB0aW1lIGFsb25nIHRoZSBUcmFuc3BvcnQnc1xuICogdGltZWxpbmUuIEl0IGlzIHNpbWlsYXIgdG8gVG9uZS5UaW1lLCBidXQgaW5zdGVhZCBvZiBldmFsdWF0aW5nXG4gKiBhZ2FpbnN0IHRoZSBBdWRpb0NvbnRleHQncyBjbG9jaywgaXQgaXMgZXZhbHVhdGVkIGFnYWluc3RcbiAqIHRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbi4gU2VlIFtUcmFuc3BvcnRUaW1lIHdpa2ldKGh0dHBzOi8vZ2l0aHViLmNvbS9Ub25lanMvVG9uZS5qcy93aWtpL1RyYW5zcG9ydFRpbWUpLlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIFRyYW5zcG9ydFRpbWVDbGFzcyBleHRlbmRzIFRpbWVDbGFzcyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJhbnNwb3J0VGltZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBpbiB3aGljaGV2ZXIgY29udGV4dCBpcyByZWxldmFudFxuICAgICAqL1xuICAgIF9ub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHM7XG4gICAgfVxufVxuLyoqXG4gKiBUcmFuc3BvcnRUaW1lIGlzIGEgdGhlIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzXG4gKiB0aW1lbGluZS4gSXQgaXMgc2ltaWxhciB0byBbW1RpbWVdXSwgYnV0IGluc3RlYWQgb2YgZXZhbHVhdGluZ1xuICogYWdhaW5zdCB0aGUgQXVkaW9Db250ZXh0J3MgY2xvY2ssIGl0IGlzIGV2YWx1YXRlZCBhZ2FpbnN0XG4gKiB0aGUgVHJhbnNwb3J0J3MgcG9zaXRpb24uIFNlZSBbVHJhbnNwb3J0VGltZSB3aWtpXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9UcmFuc3BvcnRUaW1lKS5cbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBUcmFuc3BvcnRUaW1lKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKGdldENvbnRleHQoKSwgdmFsdWUsIHVuaXRzKTtcbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRyYW5zcG9ydFRpbWUuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9GcmVxdWVuY3lcIjtcbmltcG9ydCB7IFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpbWVcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RyYW5zcG9ydFRpbWVcIjtcbmltcG9ydCB7IGdldERlZmF1bHRzRnJvbUluc3RhbmNlLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0Jvb2xlYW4sIGlzRGVmaW5lZCwgaXNOdW1iZXIsIGlzU3RyaW5nLCBpc1VuZGVmIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG4vKipcbiAqIFRoZSBCYXNlIGNsYXNzIGZvciBhbGwgbm9kZXMgdGhhdCBoYXZlIGFuIEF1ZGlvQ29udGV4dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVXaXRoQ29udGV4dCBleHRlbmRzIFRvbmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY29udGV4dFwiXSk7XG4gICAgICAgIGlmICh0aGlzLmRlZmF1bHRDb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQgPSB0aGlzLmRlZmF1bHRDb250ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0ID0gb3B0aW9ucy5jb250ZXh0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldENvbnRleHQoKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIENvbnRleHQgY2xvY2sgcGx1cyB0aGUgbG9va0FoZWFkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2coVG9uZS5ub3coKSk7XG4gICAgICogfSwgMTAwKTtcbiAgICAgKi9cbiAgICBub3coKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUgKyB0aGlzLmNvbnRleHQubG9va0FoZWFkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGN1cnJlbnQgdGltZSBvZiB0aGUgQ29udGV4dCBjbG9jayB3aXRob3V0IGFueSBsb29rQWhlYWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICogXHRjb25zb2xlLmxvZyhUb25lLmltbWVkaWF0ZSgpKTtcbiAgICAgKiB9LCAxMDApO1xuICAgICAqL1xuICAgIGltbWVkaWF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgb2Ygb25lIHNhbXBsZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuVHJhbnNwb3J0LnNhbXBsZVRpbWUpO1xuICAgICAqL1xuICAgIGdldCBzYW1wbGVUaW1lKCkge1xuICAgICAgICByZXR1cm4gMSAvIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNlY29uZHMgb2YgMSBwcm9jZXNzaW5nIGJsb2NrICgxMjggc2FtcGxlcylcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnNvbGUubG9nKFRvbmUuRGVzdGluYXRpb24uYmxvY2tUaW1lKTtcbiAgICAgKi9cbiAgICBnZXQgYmxvY2tUaW1lKCkge1xuICAgICAgICByZXR1cm4gMTI4IC8gdGhpcy5jb250ZXh0LnNhbXBsZVJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgdGhlIGluY29taW5nIHRpbWUgdG8gc2Vjb25kcy5cbiAgICAgKiBUaGlzIGlzIGNhbGN1bGF0ZWQgYWdhaW5zdCB0aGUgY3VycmVudCBbW1RvbmUuVHJhbnNwb3J0XV0gYnBtXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigpO1xuICAgICAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKGdhaW4udG9TZWNvbmRzKFwiNG5cIikpLCAxMDApO1xuICAgICAqIC8vIHJhbXAgdGhlIHRlbXBvIHRvIDYwIGJwbSBvdmVyIDMwIHNlY29uZHNcbiAgICAgKiBUb25lLmdldFRyYW5zcG9ydCgpLmJwbS5yYW1wVG8oNjAsIDMwKTtcbiAgICAgKi9cbiAgICB0b1NlY29uZHModGltZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbnB1dCB0byBhIGZyZXF1ZW5jeSBudW1iZXJcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2coZ2Fpbi50b0ZyZXF1ZW5jeShcIjRuXCIpKTtcbiAgICAgKi9cbiAgICB0b0ZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHJldHVybiBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBmcmVxKS50b0ZyZXF1ZW5jeSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHRoZSBpbnB1dCB0aW1lIGludG8gdGlja3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGdhaW4gPSBuZXcgVG9uZS5HYWluKCk7XG4gICAgICogY29uc29sZS5sb2coZ2Fpbi50b1RpY2tzKFwiNG5cIikpO1xuICAgICAqL1xuICAgIHRvVGlja3ModGltZSkge1xuICAgICAgICByZXR1cm4gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvVGlja3MoKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRHRVQvU0VUXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogR2V0IGEgc3Vic2V0IG9mIHRoZSBwcm9wZXJ0aWVzIHdoaWNoIGFyZSBpbiB0aGUgcGFydGlhbCBwcm9wc1xuICAgICAqL1xuICAgIF9nZXRQYXJ0aWFsUHJvcGVydGllcyhwcm9wcykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5nZXQoKTtcbiAgICAgICAgLy8gcmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgcHJvcCB0aGF0IGFyZSBub3QgaW4gdGhlIHBhcnRpYWxcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChpc1VuZGVmKHByb3BzW25hbWVdKSkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zW25hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgb2JqZWN0J3MgYXR0cmlidXRlcy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvc2MuZ2V0KCkpO1xuICAgICAqL1xuICAgIGdldCgpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSBnZXREZWZhdWx0c0Zyb21JbnN0YW5jZSh0aGlzKTtcbiAgICAgICAgT2JqZWN0LmtleXMoZGVmYXVsdHMpLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0Lmhhcyh0aGlzLCBhdHRyaWJ1dGUpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWVtYmVyID0gdGhpc1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIGlmIChpc0RlZmluZWQobWVtYmVyKSAmJiBpc0RlZmluZWQobWVtYmVyLnZhbHVlKSAmJiBpc0RlZmluZWQobWVtYmVyLnNldFZhbHVlQXRUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0c1thdHRyaWJ1dGVdID0gbWVtYmVyLnZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChtZW1iZXIgaW5zdGFuY2VvZiBUb25lV2l0aENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlci5fZ2V0UGFydGlhbFByb3BlcnRpZXMoZGVmYXVsdHNbYXR0cmlidXRlXSk7XG4gICAgICAgICAgICAgICAgICAgIC8vIG90aGVyd2lzZSBtYWtlIHN1cmUgaXQncyBhIHNlcmlhbGl6YWJsZSB0eXBlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzQXJyYXkobWVtYmVyKSB8fCBpc051bWJlcihtZW1iZXIpIHx8IGlzU3RyaW5nKG1lbWJlcikgfHwgaXNCb29sZWFuKG1lbWJlcikpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHNbYXR0cmlidXRlXSA9IG1lbWJlcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBhbGwgdW5kZWZpbmVkIGFuZCB1bnNlcmlhbGl6YWJsZSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBkZWZhdWx0c1thdHRyaWJ1dGVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBkZWZhdWx0cztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IG11bHRpcGxlIHByb3BlcnRpZXMgYXQgb25jZSB3aXRoIGFuIG9iamVjdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzZXQgdmFsdWVzIHVzaW5nIGFuIG9iamVjdFxuICAgICAqIGZpbHRlci5zZXQoe1xuICAgICAqIFx0ZnJlcXVlbmN5OiBcIkM2XCIsXG4gICAgICogXHR0eXBlOiBcImhpZ2hwYXNzXCJcbiAgICAgKiB9KTtcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9BbmFsb2dzeW50aF9vY3RhdmVzX2hpZ2htaWQubXAzXCIpLmNvbm5lY3QoZmlsdGVyKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXQocHJvcHMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMocHJvcHMpLmZvckVhY2goYXR0cmlidXRlID0+IHtcbiAgICAgICAgICAgIGlmIChSZWZsZWN0Lmhhcyh0aGlzLCBhdHRyaWJ1dGUpICYmIGlzRGVmaW5lZCh0aGlzW2F0dHJpYnV0ZV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdLnZhbHVlKSAmJiBpc0RlZmluZWQodGhpc1thdHRyaWJ1dGVdLnNldFZhbHVlQXRUaW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBzbWFsbCBvcHRpbWl6YXRpb25cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXNbYXR0cmlidXRlXS52YWx1ZSAhPT0gcHJvcHNbYXR0cmlidXRlXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdLnZhbHVlID0gcHJvcHNbYXR0cmlidXRlXTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICh0aGlzW2F0dHJpYnV0ZV0gaW5zdGFuY2VvZiBUb25lV2l0aENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1thdHRyaWJ1dGVdLnNldChwcm9wc1thdHRyaWJ1dGVdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXNbYXR0cmlidXRlXSA9IHByb3BzW2F0dHJpYnV0ZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZVdpdGhDb250ZXh0LmpzLm1hcCIsImltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogQSBUaW1lbGluZSBTdGF0ZS4gUHJvdmlkZXMgdGhlIG1ldGhvZHM6IGBzZXRTdGF0ZUF0VGltZShcInN0YXRlXCIsIHRpbWUpYCBhbmQgYGdldFZhbHVlQXRUaW1lKHRpbWUpYFxuICogQHBhcmFtIGluaXRpYWwgVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIFN0YXRlVGltZWxpbmUuICBEZWZhdWx0cyB0byBgdW5kZWZpbmVkYFxuICovXG5leHBvcnQgY2xhc3MgU3RhdGVUaW1lbGluZSBleHRlbmRzIFRpbWVsaW5lIHtcbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsID0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGF0ZVRpbWVsaW5lXCI7XG4gICAgICAgIHRoaXMuX2luaXRpYWwgPSBpbml0aWFsO1xuICAgICAgICB0aGlzLnNldFN0YXRlQXRUaW1lKHRoaXMuX2luaXRpYWwsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgc2NoZWR1bGVkIGJlZm9yZSBvciBhdFxuICAgICAqIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuICAgICAqL1xuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKGV2ZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBzdGF0ZSB0byB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgbmFtZSBvZiB0aGUgc3RhdGUgdG8gc2V0LlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHBhcmFtIG9wdGlvbnMgQW55IGFkZGl0aW9uYWwgb3B0aW9ucyB0aGF0IGFyZSBuZWVkZWQgaW4gdGhlIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIHNldFN0YXRlQXRUaW1lKHN0YXRlLCB0aW1lLCBvcHRpb25zKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDApO1xuICAgICAgICB0aGlzLmFkZChPYmplY3QuYXNzaWduKHt9LCBvcHRpb25zLCB7XG4gICAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICAgIHRpbWUsXG4gICAgICAgIH0pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgZXZlbnQgYmVmb3JlIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgc3RhdGUgdG8gbG9vayBmb3JcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gY2hlY2sgYmVmb3JlXG4gICAgICogQHJldHVybiAgVGhlIGV2ZW50IHdpdGggdGhlIGdpdmVuIHN0YXRlIGJlZm9yZSB0aGUgdGltZVxuICAgICAqL1xuICAgIGdldExhc3RTdGF0ZShzdGF0ZSwgdGltZSkge1xuICAgICAgICAvLyB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lW2ldO1xuICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBldmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGV2ZW50IGFmdGVyIHRoZSB0aW1lIHdpdGggdGhlIGdpdmVuIHN0YXRlXG4gICAgICogQHBhcmFtICBzdGF0ZSBUaGUgc3RhdGUgdG8gbG9vayBmb3JcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gY2hlY2sgZnJvbVxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aXRoIHRoZSBnaXZlbiBzdGF0ZSBhZnRlciB0aGUgdGltZVxuICAgICAqL1xuICAgIGdldE5leHRTdGF0ZShzdGF0ZSwgdGltZSkge1xuICAgICAgICAvLyB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fc2VhcmNoKHRpbWUpO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPCB0aGlzLl90aW1lbGluZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fdGltZWxpbmVbaV07XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnN0YXRlID09PSBzdGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZXZlbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RhdGVUaW1lbGluZS5qcy5tYXAiLCJpbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgaXNBdWRpb1BhcmFtIH0gZnJvbSBcIi4uL3V0aWwvQWR2YW5jZWRUeXBlQ2hlY2tcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvVGltZWxpbmVcIjtcbmltcG9ydCB7IGlzRGVmaW5lZCB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4vVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBFUSB9IGZyb20gXCIuLi91dGlsL01hdGhcIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBQYXJhbSB3cmFwcyB0aGUgbmF0aXZlIFdlYiBBdWRpbydzIEF1ZGlvUGFyYW0gdG8gcHJvdmlkZVxuICogYWRkaXRpb25hbCB1bml0IGNvbnZlcnNpb24gZnVuY3Rpb25hbGl0eS4gSXQgYWxzb1xuICogc2VydmVzIGFzIGEgYmFzZS1jbGFzcyBmb3IgY2xhc3NlcyB3aGljaCBoYXZlIGEgc2luZ2xlLFxuICogYXV0b21hdGFibGUgcGFyYW1ldGVyLlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFBhcmFtIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYXJhbVwiLCBcInVuaXRzXCIsIFwiY29udmVydFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBhcmFtXCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGRlbiA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9taW5PdXRwdXQgPSAxZS03O1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYXJhbVwiLCBcInVuaXRzXCIsIFwiY29udmVydFwiXSk7XG4gICAgICAgIGFzc2VydChpc0RlZmluZWQob3B0aW9ucy5wYXJhbSkgJiZcbiAgICAgICAgICAgIChpc0F1ZGlvUGFyYW0ob3B0aW9ucy5wYXJhbSkgfHwgb3B0aW9ucy5wYXJhbSBpbnN0YW5jZW9mIFBhcmFtKSwgXCJwYXJhbSBtdXN0IGJlIGFuIEF1ZGlvUGFyYW1cIik7XG4gICAgICAgIHdoaWxlICghaXNBdWRpb1BhcmFtKG9wdGlvbnMucGFyYW0pKSB7XG4gICAgICAgICAgICBvcHRpb25zLnBhcmFtID0gb3B0aW9ucy5wYXJhbS5fcGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3dhcHBhYmxlID0gaXNEZWZpbmVkKG9wdGlvbnMuc3dhcHBhYmxlKSA/IG9wdGlvbnMuc3dhcHBhYmxlIDogZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLl9zd2FwcGFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICAgICAgLy8gaW5pdGlhbGl6ZVxuICAgICAgICAgICAgdGhpcy5fcGFyYW0gPSBvcHRpb25zLnBhcmFtO1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtID0gdGhpcy5pbnB1dCA9IG9wdGlvbnMucGFyYW07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZXZlbnRzID0gbmV3IFRpbWVsaW5lKDEwMDApO1xuICAgICAgICB0aGlzLl9pbml0aWFsVmFsdWUgPSB0aGlzLl9wYXJhbS5kZWZhdWx0VmFsdWU7XG4gICAgICAgIHRoaXMudW5pdHMgPSBvcHRpb25zLnVuaXRzO1xuICAgICAgICB0aGlzLmNvbnZlcnQgPSBvcHRpb25zLmNvbnZlcnQ7XG4gICAgICAgIHRoaXMuX21pblZhbHVlID0gb3B0aW9ucy5taW5WYWx1ZTtcbiAgICAgICAgdGhpcy5fbWF4VmFsdWUgPSBvcHRpb25zLm1heFZhbHVlO1xuICAgICAgICAvLyBpZiB0aGUgdmFsdWUgaXMgZGVmaW5lZCwgc2V0IGl0IGltbWVkaWF0ZWx5XG4gICAgICAgIGlmIChpc0RlZmluZWQob3B0aW9ucy52YWx1ZSkgJiYgb3B0aW9ucy52YWx1ZSAhPT0gdGhpcy5fdG9UeXBlKHRoaXMuX2luaXRpYWxWYWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0IHZhbHVlKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZUF0VGltZShub3cpO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGhpcy5ub3coKSk7XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUodmFsdWUsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBnZXQgbWluVmFsdWUoKSB7XG4gICAgICAgIC8vIGlmIGl0J3Mgbm90IHRoZSBkZWZhdWx0IG1pblZhbHVlLCByZXR1cm4gaXRcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLl9taW5WYWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9taW5WYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcInRpbWVcIiB8fCB0aGlzLnVuaXRzID09PSBcImZyZXF1ZW5jeVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcIm5vcm1hbFJhbmdlXCIgfHwgdGhpcy51bml0cyA9PT0gXCJwb3NpdGl2ZVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcInRyYW5zcG9ydFRpbWVcIiB8fCB0aGlzLnVuaXRzID09PSBcInRpY2tzXCIgfHxcbiAgICAgICAgICAgIHRoaXMudW5pdHMgPT09IFwiYnBtXCIgfHwgdGhpcy51bml0cyA9PT0gXCJoZXJ0elwiIHx8IHRoaXMudW5pdHMgPT09IFwic2FtcGxlc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnVuaXRzID09PSBcImF1ZGlvUmFuZ2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMudW5pdHMgPT09IFwiZGVjaWJlbHNcIikge1xuICAgICAgICAgICAgcmV0dXJuIC1JbmZpbml0eTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5taW5WYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5fbWF4VmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWF4VmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy51bml0cyA9PT0gXCJub3JtYWxSYW5nZVwiIHx8XG4gICAgICAgICAgICB0aGlzLnVuaXRzID09PSBcImF1ZGlvUmFuZ2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWF4VmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHlwZSBndWFyZCBiYXNlZCBvbiB0aGUgdW5pdCBuYW1lXG4gICAgICovXG4gICAgX2lzKGFyZywgdHlwZSkge1xuICAgICAgICByZXR1cm4gdGhpcy51bml0cyA9PT0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTWFrZSBzdXJlIHRoZSB2YWx1ZSBpcyBhbHdheXMgaW4gdGhlIGRlZmluZWQgcmFuZ2VcbiAgICAgKi9cbiAgICBfYXNzZXJ0UmFuZ2UodmFsdWUpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm1heFZhbHVlKSAmJiBpc0RlZmluZWQodGhpcy5taW5WYWx1ZSkpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHZhbHVlLCB0aGlzLl9mcm9tVHlwZSh0aGlzLm1pblZhbHVlKSwgdGhpcy5fZnJvbVR5cGUodGhpcy5tYXhWYWx1ZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgZ2l2ZW4gdmFsdWUgZnJvbSB0aGUgdHlwZSBzcGVjaWZpZWQgYnkgUGFyYW0udW5pdHNcbiAgICAgKiBpbnRvIHRoZSBkZXN0aW5hdGlvbiB2YWx1ZSAoc3VjaCBhcyBHYWluIG9yIEZyZXF1ZW5jeSkuXG4gICAgICovXG4gICAgX2Zyb21UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy5jb252ZXJ0ICYmICF0aGlzLm92ZXJyaWRkZW4pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9pcyh2YWwsIFwidGltZVwiKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvU2Vjb25kcyh2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5faXModmFsLCBcImRlY2liZWxzXCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRiVG9HYWluKHZhbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLl9pcyh2YWwsIFwiZnJlcXVlbmN5XCIpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9GcmVxdWVuY3kodmFsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5vdmVycmlkZGVuKSB7XG4gICAgICAgICAgICAvLyBpZiBpdCdzIG92ZXJyaWRkZW4sIHNob3VsZCBvbmx5IHNjaGVkdWxlIDBzXG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29udmVydCB0aGUgcGFyYW1ldGVycyB2YWx1ZSBpbnRvIHRoZSB1bml0cyBzcGVjaWZpZWQgYnkgUGFyYW0udW5pdHMuXG4gICAgICovXG4gICAgX3RvVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udmVydCAmJiB0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBnYWluVG9EYih2YWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBQlNUUkFDVCBQQVJBTSBJTlRFUkZBQ0VcbiAgICAvLyBhbGwgZG9jcyBhcmUgZ2VuZXJhdGVkIGZyb20gUGFyYW1JbnRlcmZhY2UudHNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBzZXRWYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KHRpbWUpfWApO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcInNldFZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwic2V0VmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRWYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXRWYWx1ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IE1hdGgubWF4KHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwKTtcbiAgICAgICAgY29uc3QgYWZ0ZXIgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBsZXQgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIC8vIGlmIGl0IHdhcyBzZXQgYnlcbiAgICAgICAgaWYgKGJlZm9yZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aGlzLl9pbml0aWFsVmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIgJiYgKGFmdGVyID09PSBudWxsIHx8IGFmdGVyLnR5cGUgPT09IFwic2V0VmFsdWVBdFRpbWVcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy5fZXZlbnRzLmdldEJlZm9yZShiZWZvcmUudGltZSk7XG4gICAgICAgICAgICBsZXQgcHJldmlvdXNWYWw7XG4gICAgICAgICAgICBpZiAocHJldmlvdXMgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBwcmV2aW91c1ZhbCA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzVmFsID0gcHJldmlvdXMudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHRoaXMuX2V4cG9uZW50aWFsQXBwcm9hY2goYmVmb3JlLnRpbWUsIHByZXZpb3VzVmFsLCBiZWZvcmUudmFsdWUsIGJlZm9yZS5jb25zdGFudCwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChhZnRlciA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiIHx8IGFmdGVyLnR5cGUgPT09IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICBsZXQgYmVmb3JlVmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuX2V2ZW50cy5nZXRCZWZvcmUoYmVmb3JlLnRpbWUpO1xuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91cyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBiZWZvcmVWYWx1ZSA9IHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZVZhbHVlID0gcHJldmlvdXMudmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGFmdGVyLnR5cGUgPT09IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fbGluZWFySW50ZXJwb2xhdGUoYmVmb3JlLnRpbWUsIGJlZm9yZVZhbHVlLCBhZnRlci50aW1lLCBhZnRlci52YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdGhpcy5fZXhwb25lbnRpYWxJbnRlcnBvbGF0ZShiZWZvcmUudGltZSwgYmVmb3JlVmFsdWUsIGFmdGVyLnRpbWUsIGFmdGVyLnZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSBiZWZvcmUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh2YWx1ZSk7XG4gICAgfVxuICAgIHNldFJhbXBQb2ludCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWYWwgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9mcm9tVHlwZShjdXJyZW50VmFsKSA9PT0gMCkge1xuICAgICAgICAgICAgY3VycmVudFZhbCA9IHRoaXMuX3RvVHlwZSh0aGlzLl9taW5PdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0VmFsdWVBdFRpbWUoY3VycmVudFZhbCwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgZW5kVGltZSkge1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKGVuZFRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9LCAke0pTT04uc3RyaW5naWZ5KGVuZFRpbWUpfWApO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwibGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBudW1lcmljVmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvZyh0aGlzLnVuaXRzLCBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBlbmRUaW1lKSB7XG4gICAgICAgIGxldCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIHRoZSB2YWx1ZSBjYW4ndCBiZSAwXG4gICAgICAgIG51bWVyaWNWYWx1ZSA9IEVRKG51bWVyaWNWYWx1ZSwgMCkgPyB0aGlzLl9taW5PdXRwdXQgOiBudW1lcmljVmFsdWU7XG4gICAgICAgIHRoaXMuX2Fzc2VydFJhbmdlKG51bWVyaWNWYWx1ZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKGVuZFRpbWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX0sICR7SlNPTi5zdHJpbmdpZnkoZW5kVGltZSl9YCk7XG4gICAgICAgIC8vIHN0b3JlIHRoZSBldmVudFxuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIHRpbWU6IGNvbXB1dGVkVGltZSxcbiAgICAgICAgICAgIHR5cGU6IFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwiZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZVwiLCB2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG9WYWx1ZUF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSArIHRoaXMudG9TZWNvbmRzKHJhbXBUaW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5zZXRSYW1wUG9pbnQoc3RhcnRUaW1lKTtcbiAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lICsgdGhpcy50b1NlY29uZHMocmFtcFRpbWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSkge1xuICAgICAgICBzdGFydFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLnNldFJhbXBQb2ludChzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUsIHJhbXBUaW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmFtcFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhyYW1wVGltZSk7XG4gICAgICAgIGNvbnN0IHRpbWVDb25zdGFudCA9IE1hdGgubG9nKHJhbXBUaW1lICsgMSkgLyBNYXRoLmxvZygyMDApO1xuICAgICAgICB0aGlzLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgdGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgLy8gYXQgOTAlIHN0YXJ0IGEgbGluZWFyIHJhbXAgdG8gdGhlIGZpbmFsIHZhbHVlXG4gICAgICAgIHRoaXMuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lICsgcmFtcFRpbWUgKiAwLjkpO1xuICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lICsgcmFtcFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICBjb25zdCBudW1lcmljVmFsdWUgPSB0aGlzLl9mcm9tVHlwZSh2YWx1ZSk7XG4gICAgICAgIC8vIFRoZSB2YWx1ZSB3aWxsIG5ldmVyIGJlIGFibGUgdG8gYXBwcm9hY2ggd2l0aG91dCB0aW1lQ29uc3RhbnQgPiAwLlxuICAgICAgICBhc3NlcnQoaXNGaW5pdGUodGltZUNvbnN0YW50KSAmJiB0aW1lQ29uc3RhbnQgPiAwLCBcInRpbWVDb25zdGFudCBtdXN0IGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwXCIpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyhzdGFydFRpbWUpO1xuICAgICAgICB0aGlzLl9hc3NlcnRSYW5nZShudW1lcmljVmFsdWUpO1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUobnVtZXJpY1ZhbHVlKSAmJiBpc0Zpbml0ZShjb21wdXRlZFRpbWUpLCBgSW52YWxpZCBhcmd1bWVudChzKSB0byBzZXRUYXJnZXRBdFRpbWU6ICR7SlNPTi5zdHJpbmdpZnkodmFsdWUpfSwgJHtKU09OLnN0cmluZ2lmeShzdGFydFRpbWUpfWApO1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIGNvbnN0YW50OiB0aW1lQ29uc3RhbnQsXG4gICAgICAgICAgICB0aW1lOiBjb21wdXRlZFRpbWUsXG4gICAgICAgICAgICB0eXBlOiBcInNldFRhcmdldEF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG51bWVyaWNWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG9nKHRoaXMudW5pdHMsIFwic2V0VGFyZ2V0QXRUaW1lXCIsIHZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFRhcmdldEF0VGltZShudW1lcmljVmFsdWUsIGNvbXB1dGVkVGltZSwgdGltZUNvbnN0YW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nID0gMSkge1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgc3RhcnRUaW1lID0gdGhpcy50b1NlY29uZHMoc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc3RhcnRpbmdWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlc1swXSkgKiBzY2FsaW5nO1xuICAgICAgICB0aGlzLnNldFZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShzdGFydGluZ1ZhbHVlKSwgc3RhcnRUaW1lKTtcbiAgICAgICAgY29uc3Qgc2VnVGltZSA9IGR1cmF0aW9uIC8gKHZhbHVlcy5sZW5ndGggLSAxKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHRoaXMuX2Zyb21UeXBlKHZhbHVlc1tpXSkgKiBzY2FsaW5nO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUobnVtZXJpY1ZhbHVlKSwgc3RhcnRUaW1lICsgaSAqIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgYXNzZXJ0KGlzRmluaXRlKGNvbXB1dGVkVGltZSksIGBJbnZhbGlkIGFyZ3VtZW50IHRvIGNhbmNlbFNjaGVkdWxlZFZhbHVlczogJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJjYW5jZWxTY2hlZHVsZWRWYWx1ZXNcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgdmFsdWVBdFRpbWUgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGNvbXB1dGVkVGltZSkpO1xuICAgICAgICAvLyByZW1vdmUgdGhlIHNjaGVkdWxlIGV2ZW50c1xuICAgICAgICBhc3NlcnQoaXNGaW5pdGUoY29tcHV0ZWRUaW1lKSwgYEludmFsaWQgYXJndW1lbnQgdG8gY2FuY2VsQW5kSG9sZEF0VGltZTogJHtKU09OLnN0cmluZ2lmeSh0aW1lKX1gKTtcbiAgICAgICAgdGhpcy5sb2codGhpcy51bml0cywgXCJjYW5jZWxBbmRIb2xkQXRUaW1lXCIsIGNvbXB1dGVkVGltZSwgXCJ2YWx1ZT1cIiArIHZhbHVlQXRUaW1lKTtcbiAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gZXZlbnQgYXQgdGhlIGdpdmVuIGNvbXB1dGVkVGltZVxuICAgICAgICAvLyBhbmQgdGhhdCBldmVuIGlzIG5vdCBhIFwic2V0XCJcbiAgICAgICAgY29uc3QgYmVmb3JlID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBhZnRlciA9IHRoaXMuX2V2ZW50cy5nZXRBZnRlcihjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAoYmVmb3JlICYmIEVRKGJlZm9yZS50aW1lLCBjb21wdXRlZFRpbWUpKSB7XG4gICAgICAgICAgICAvLyByZW1vdmUgZXZlcnl0aGluZyBhZnRlclxuICAgICAgICAgICAgaWYgKGFmdGVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKGFmdGVyLnRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxBbmRIb2xkQXRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzLmNhbmNlbChjb21wdXRlZFRpbWUgKyB0aGlzLnNhbXBsZVRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGFmdGVyKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbS5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICAvLyBjYW5jZWwgdGhlIG5leHQgZXZlbnQocylcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoYWZ0ZXIudGltZSk7XG4gICAgICAgICAgICBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZVwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUodmFsdWVBdFRpbWUpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYWZ0ZXIudHlwZSA9PT0gXCJleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodGhpcy5fdG9UeXBlKHZhbHVlQXRUaW1lKSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGltZTogY29tcHV0ZWRUaW1lLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlQXRUaW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVBdFRpbWUodmFsdWVBdFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByYW1wVG8odmFsdWUsIHJhbXBUaW1lID0gMC4xLCBzdGFydFRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiZnJlcXVlbmN5XCIgfHwgdGhpcy51bml0cyA9PT0gXCJicG1cIiB8fCB0aGlzLnVuaXRzID09PSBcImRlY2liZWxzXCIpIHtcbiAgICAgICAgICAgIHRoaXMuZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcHBseSBhbGwgb2YgdGhlIHByZXZpb3VzbHkgc2NoZWR1bGVkIGV2ZW50cyB0byB0aGUgcGFzc2VkIGluIFBhcmFtIG9yIEF1ZGlvUGFyYW0uXG4gICAgICogVGhlIGFwcGxpZWQgdmFsdWVzIHdpbGwgc3RhcnQgYXQgdGhlIGNvbnRleHQncyBjdXJyZW50IHRpbWUgYW5kIHNjaGVkdWxlXG4gICAgICogYWxsIG9mIHRoZSBldmVudHMgd2hpY2ggYXJlIHNjaGVkdWxlZCBvbiB0aGlzIFBhcmFtIG9udG8gdGhlIHBhc3NlZCBpbiBwYXJhbS5cbiAgICAgKi9cbiAgICBhcHBseShwYXJhbSkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIC8vIHNldCB0aGUgcGFyYW0ncyB2YWx1ZSBhdCB0aGUgY3VycmVudCB0aW1lIGFuZCBzY2hlZHVsZSBldmVyeXRoaW5nIGVsc2VcbiAgICAgICAgcGFyYW0uc2V0VmFsdWVBdFRpbWUodGhpcy5nZXRWYWx1ZUF0VGltZShub3cpLCBub3cpO1xuICAgICAgICAvLyBpZiB0aGUgcHJldmlvdXMgZXZlbnQgd2FzIGEgY3VydmUsIHRoZW4gc2V0IHRoZSByZXN0IG9mIGl0XG4gICAgICAgIGNvbnN0IHByZXZpb3VzRXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0KG5vdyk7XG4gICAgICAgIGlmIChwcmV2aW91c0V2ZW50ICYmIHByZXZpb3VzRXZlbnQudHlwZSA9PT0gXCJzZXRUYXJnZXRBdFRpbWVcIikge1xuICAgICAgICAgICAgLy8gYXBwcm94IGl0IHVudGlsIHRoZSBuZXh0IGV2ZW50IHdpdGggbGluZWFyIHJhbXBzXG4gICAgICAgICAgICBjb25zdCBuZXh0RXZlbnQgPSB0aGlzLl9ldmVudHMuZ2V0QWZ0ZXIocHJldmlvdXNFdmVudC50aW1lKTtcbiAgICAgICAgICAgIC8vIG9yIGZvciAyIHNlY29uZHMgaWYgdGhlcmUgaXMgbm8gZXZlbnRcbiAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBuZXh0RXZlbnQgPyBuZXh0RXZlbnQudGltZSA6IG5vdyArIDI7XG4gICAgICAgICAgICBjb25zdCBzdWJkaXZpc2lvbnMgPSAoZW5kVGltZSAtIG5vdykgLyAxMDtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBub3c7IGkgPCBlbmRUaW1lOyBpICs9IHN1YmRpdmlzaW9ucykge1xuICAgICAgICAgICAgICAgIHBhcmFtLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuZ2V0VmFsdWVBdFRpbWUoaSksIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoQWZ0ZXIodGhpcy5jb250ZXh0LmN1cnJlbnRUaW1lLCBldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJjYW5jZWxTY2hlZHVsZWRWYWx1ZXNcIikge1xuICAgICAgICAgICAgICAgIHBhcmFtLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyhldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwic2V0VGFyZ2V0QXRUaW1lXCIpIHtcbiAgICAgICAgICAgICAgICBwYXJhbS5zZXRUYXJnZXRBdFRpbWUoZXZlbnQudmFsdWUsIGV2ZW50LnRpbWUsIGV2ZW50LmNvbnN0YW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmFtW2V2ZW50LnR5cGVdKGV2ZW50LnZhbHVlLCBldmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXBsYWNlIHRoZSBQYXJhbSdzIGludGVybmFsIEF1ZGlvUGFyYW0uIFdpbGwgYXBwbHkgc2NoZWR1bGVkIGN1cnZlc1xuICAgICAqIG9udG8gdGhlIHBhcmFtZXRlciBhbmQgcmVwbGFjZSB0aGUgY29ubmVjdGlvbnMuXG4gICAgICovXG4gICAgc2V0UGFyYW0ocGFyYW0pIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N3YXBwYWJsZSwgXCJUaGUgUGFyYW0gbXVzdCBiZSBhc3NpZ25lZCBhcyAnc3dhcHBhYmxlJyBpbiB0aGUgY29uc3RydWN0b3JcIik7XG4gICAgICAgIGNvbnN0IGlucHV0ID0gdGhpcy5pbnB1dDtcbiAgICAgICAgaW5wdXQuZGlzY29ubmVjdCh0aGlzLl9wYXJhbSk7XG4gICAgICAgIHRoaXMuYXBwbHkocGFyYW0pO1xuICAgICAgICB0aGlzLl9wYXJhbSA9IHBhcmFtO1xuICAgICAgICBpbnB1dC5jb25uZWN0KHRoaXMuX3BhcmFtKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCBkZWZhdWx0VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90b1R5cGUodGhpcy5fcGFyYW0uZGVmYXVsdFZhbHVlKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRBVVRPTUFUSU9OIENVUlZFIENBTENVTEFUSU9OU1xuICAgIC8vIFx0TUlUIExpY2Vuc2UsIGNvcHlyaWdodCAoYykgMjAxNCBKb3JkYW4gU2FudGVsbFxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgc2V0VGFyZ2V0QXRUaW1lXG4gICAgX2V4cG9uZW50aWFsQXBwcm9hY2godDAsIHYwLCB2MSwgdGltZUNvbnN0YW50LCB0KSB7XG4gICAgICAgIHJldHVybiB2MSArICh2MCAtIHYxKSAqIE1hdGguZXhwKC0odCAtIHQwKSAvIHRpbWVDb25zdGFudCk7XG4gICAgfVxuICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRoZSB2YWx1ZSBhbG9uZyB0aGUgY3VydmUgcHJvZHVjZWQgYnkgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWVcbiAgICBfbGluZWFySW50ZXJwb2xhdGUodDAsIHYwLCB0MSwgdjEsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYwICsgKHYxIC0gdjApICogKCh0IC0gdDApIC8gKHQxIC0gdDApKTtcbiAgICB9XG4gICAgLy8gQ2FsY3VsYXRlcyB0aGUgdGhlIHZhbHVlIGFsb25nIHRoZSBjdXJ2ZSBwcm9kdWNlZCBieSBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lXG4gICAgX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUodDAsIHYwLCB0MSwgdjEsIHQpIHtcbiAgICAgICAgcmV0dXJuIHYwICogTWF0aC5wb3codjEgLyB2MCwgKHQgLSB0MCkgLyAodDEgLSB0MCkpO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBhcmFtLmpzLm1hcCIsImltcG9ydCB7IGlzQXVkaW9Ob2RlLCBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vdXRpbC9BZHZhbmNlZFR5cGVDaGVja1wiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuL1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCwgd2FybiB9IGZyb20gXCIuLi91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFRvbmVBdWRpb05vZGUgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGNsYXNzZXMgd2hpY2ggcHJvY2VzcyBhdWRpby5cbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb05vZGUgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5hbWUgb2YgdGhlIGNsYXNzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb05vZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIExpc3QgYWxsIG9mIHRoZSBub2RlIHRoYXQgbXVzdCBiZSBzZXQgdG8gbWF0Y2ggdGhlIENoYW5uZWxQcm9wZXJ0aWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW5wdXRzIGZlZWRpbmcgaW50byB0aGUgQXVkaW9Ob2RlLlxuICAgICAqIEZvciBzb3VyY2Ugbm9kZXMsIHRoaXMgd2lsbCBiZSAwLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhub2RlLm51bWJlck9mSW5wdXRzKTtcbiAgICAgKi9cbiAgICBnZXQgbnVtYmVyT2ZJbnB1dHMoKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQodGhpcy5pbnB1dCkpIHtcbiAgICAgICAgICAgIGlmIChpc0F1ZGlvUGFyYW0odGhpcy5pbnB1dCkgfHwgdGhpcy5pbnB1dCBpbnN0YW5jZW9mIFBhcmFtKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5udW1iZXJPZklucHV0cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb3V0cHV0cyBvZiB0aGUgQXVkaW9Ob2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9kZSA9IG5ldyBUb25lLkdhaW4oKTtcbiAgICAgKiBjb25zb2xlLmxvZyhub2RlLm51bWJlck9mT3V0cHV0cyk7XG4gICAgICovXG4gICAgZ2V0IG51bWJlck9mT3V0cHV0cygpIHtcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm91dHB1dC5udW1iZXJPZk91dHB1dHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBBVURJTyBQUk9QRVJUSUVTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVXNlZCB0byBkZWNpZGUgd2hpY2ggbm9kZXMgdG8gZ2V0L3NldCBwcm9wZXJ0aWVzIG9uXG4gICAgICovXG4gICAgX2lzQXVkaW9Ob2RlKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIGlzRGVmaW5lZChub2RlKSAmJiAobm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUgfHwgaXNBdWRpb05vZGUobm9kZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIG9mIHRoZSBhdWRpbyBub2RlcyAoZWl0aGVyIGludGVybmFsIG9yIGlucHV0L291dHB1dCkgd2hpY2ggdG9nZXRoZXJcbiAgICAgKiBtYWtlIHVwIGhvdyB0aGUgY2xhc3Mgbm9kZSByZXNwb25kcyB0byBjaGFubmVsIGlucHV0L291dHB1dFxuICAgICAqL1xuICAgIF9nZXRJbnRlcm5hbE5vZGVzKCkge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2ludGVybmFsQ2hhbm5lbHMuc2xpY2UoMCk7XG4gICAgICAgIGlmICh0aGlzLl9pc0F1ZGlvTm9kZSh0aGlzLmlucHV0KSkge1xuICAgICAgICAgICAgbm9kZUxpc3QucHVzaCh0aGlzLmlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5faXNBdWRpb05vZGUodGhpcy5vdXRwdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dCAhPT0gdGhpcy5vdXRwdXQpIHtcbiAgICAgICAgICAgICAgICBub2RlTGlzdC5wdXNoKHRoaXMub3V0cHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9kZUxpc3Q7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYXVkaW8gb3B0aW9ucyBmb3IgdGhpcyBub2RlIHN1Y2ggYXMgY2hhbm5lbEludGVycHJldGF0aW9uXG4gICAgICogY2hhbm5lbENvdW50LCBldGMuXG4gICAgICogQHBhcmFtIG9wdGlvbnNcbiAgICAgKi9cbiAgICBfc2V0Q2hhbm5lbFByb3BlcnRpZXMob3B0aW9ucykge1xuICAgICAgICBjb25zdCBub2RlTGlzdCA9IHRoaXMuX2dldEludGVybmFsTm9kZXMoKTtcbiAgICAgICAgbm9kZUxpc3QuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5vZGUuY2hhbm5lbENvdW50ID0gb3B0aW9ucy5jaGFubmVsQ291bnQ7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxDb3VudE1vZGUgPSBvcHRpb25zLmNoYW5uZWxDb3VudE1vZGU7XG4gICAgICAgICAgICBub2RlLmNoYW5uZWxJbnRlcnByZXRhdGlvbiA9IG9wdGlvbnMuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IGF1ZGlvIG9wdGlvbnMgZm9yIHRoaXMgbm9kZSBzdWNoIGFzIGNoYW5uZWxJbnRlcnByZXRhdGlvblxuICAgICAqIGNoYW5uZWxDb3VudCwgZXRjLlxuICAgICAqL1xuICAgIF9nZXRDaGFubmVsUHJvcGVydGllcygpIHtcbiAgICAgICAgY29uc3Qgbm9kZUxpc3QgPSB0aGlzLl9nZXRJbnRlcm5hbE5vZGVzKCk7XG4gICAgICAgIGFzc2VydChub2RlTGlzdC5sZW5ndGggPiAwLCBcIlRvbmVBdWRpb05vZGUgZG9lcyBub3QgaGF2ZSBhbnkgaW50ZXJuYWwgbm9kZXNcIik7XG4gICAgICAgIC8vIHVzZSB0aGUgZmlyc3Qgbm9kZSB0byBnZXQgcHJvcGVydGllc1xuICAgICAgICAvLyB0aGV5IHNob3VsZCBhbGwgYmUgdGhlIHNhbWVcbiAgICAgICAgY29uc3Qgbm9kZSA9IG5vZGVMaXN0WzBdO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBub2RlLmNoYW5uZWxDb3VudCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudE1vZGU6IG5vZGUuY2hhbm5lbENvdW50TW9kZSxcbiAgICAgICAgICAgIGNoYW5uZWxJbnRlcnByZXRhdGlvbjogbm9kZS5jaGFubmVsSW50ZXJwcmV0YXRpb24sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNoYW5uZWxDb3VudCBpcyB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzIHVzZWQgd2hlbiB1cC1taXhpbmcgYW5kIGRvd24tbWl4aW5nXG4gICAgICogY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS4gVGhlIGRlZmF1bHQgdmFsdWUgaXMgMiBleGNlcHQgZm9yXG4gICAgICogc3BlY2lmaWMgbm9kZXMgd2hlcmUgaXRzIHZhbHVlIGlzIHNwZWNpYWxseSBkZXRlcm1pbmVkLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpLmNoYW5uZWxDb3VudDtcbiAgICB9XG4gICAgc2V0IGNoYW5uZWxDb3VudChjaGFubmVsQ291bnQpIHtcbiAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLl9nZXRDaGFubmVsUHJvcGVydGllcygpO1xuICAgICAgICAvLyBtZXJnZSBpdCB3aXRoIHRoZSBvdGhlciBwcm9wZXJ0aWVzXG4gICAgICAgIHRoaXMuX3NldENoYW5uZWxQcm9wZXJ0aWVzKE9iamVjdC5hc3NpZ24ocHJvcHMsIHsgY2hhbm5lbENvdW50IH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2hhbm5lbENvdW50TW9kZSBkZXRlcm1pbmVzIGhvdyBjaGFubmVscyB3aWxsIGJlIGNvdW50ZWQgd2hlbiB1cC1taXhpbmcgYW5kXG4gICAgICogZG93bi1taXhpbmcgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcIm1heFwiLiBUaGlzIGF0dHJpYnV0ZSBoYXMgbm8gZWZmZWN0IGZvciBub2RlcyB3aXRoIG5vIGlucHV0cy5cbiAgICAgKiAqIFwibWF4XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgdGhlIG1heGltdW0gb2YgdGhlIG51bWJlciBvZiBjaGFubmVscyBvZiBhbGwgY29ubmVjdGlvbnMgdG8gYW4gaW5wdXQuIEluIHRoaXMgbW9kZSBjaGFubmVsQ291bnQgaXMgaWdub3JlZC5cbiAgICAgKiAqIFwiY2xhbXBlZC1tYXhcIiAtIGNvbXB1dGVkTnVtYmVyT2ZDaGFubmVscyBpcyBkZXRlcm1pbmVkIGFzIGZvciBcIm1heFwiIGFuZCB0aGVuIGNsYW1wZWQgdG8gYSBtYXhpbXVtIHZhbHVlIG9mIHRoZSBnaXZlbiBjaGFubmVsQ291bnQuXG4gICAgICogKiBcImV4cGxpY2l0XCIgLSBjb21wdXRlZE51bWJlck9mQ2hhbm5lbHMgaXMgdGhlIGV4YWN0IHZhbHVlIGFzIHNwZWNpZmllZCBieSB0aGUgY2hhbm5lbENvdW50LlxuICAgICAqL1xuICAgIGdldCBjaGFubmVsQ291bnRNb2RlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKS5jaGFubmVsQ291bnRNb2RlO1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbENvdW50TW9kZShjaGFubmVsQ291bnRNb2RlKSB7XG4gICAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5fZ2V0Q2hhbm5lbFByb3BlcnRpZXMoKTtcbiAgICAgICAgLy8gbWVyZ2UgaXQgd2l0aCB0aGUgb3RoZXIgcHJvcGVydGllc1xuICAgICAgICB0aGlzLl9zZXRDaGFubmVsUHJvcGVydGllcyhPYmplY3QuYXNzaWduKHByb3BzLCB7IGNoYW5uZWxDb3VudE1vZGUgfSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFubmVsSW50ZXJwcmV0YXRpb24gZGV0ZXJtaW5lcyBob3cgaW5kaXZpZHVhbCBjaGFubmVscyB3aWxsIGJlIHRyZWF0ZWRcbiAgICAgKiB3aGVuIHVwLW1peGluZyBhbmQgZG93bi1taXhpbmcgY29ubmVjdGlvbnMgdG8gYW55IGlucHV0cyB0byB0aGUgbm9kZS5cbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBcInNwZWFrZXJzXCIuXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxJbnRlcnByZXRhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCkuY2hhbm5lbEludGVycHJldGF0aW9uO1xuICAgIH1cbiAgICBzZXQgY2hhbm5lbEludGVycHJldGF0aW9uKGNoYW5uZWxJbnRlcnByZXRhdGlvbikge1xuICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuX2dldENoYW5uZWxQcm9wZXJ0aWVzKCk7XG4gICAgICAgIC8vIG1lcmdlIGl0IHdpdGggdGhlIG90aGVyIHByb3BlcnRpZXNcbiAgICAgICAgdGhpcy5fc2V0Q2hhbm5lbFByb3BlcnRpZXMoT2JqZWN0LmFzc2lnbihwcm9wcywgeyBjaGFubmVsSW50ZXJwcmV0YXRpb24gfSkpO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBDT05ORUNUSU9OU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG91dHB1dCBvZiBhIFRvbmVBdWRpb05vZGUgdG8gYW4gQXVkaW9QYXJhbSwgQXVkaW9Ob2RlLCBvciBUb25lQXVkaW9Ob2RlXG4gICAgICogQHBhcmFtIGRlc3RpbmF0aW9uIFRoZSBvdXRwdXQgdG8gY29ubmVjdCB0b1xuICAgICAqIEBwYXJhbSBvdXRwdXROdW0gVGhlIG91dHB1dCB0byBjb25uZWN0IGZyb21cbiAgICAgKiBAcGFyYW0gaW5wdXROdW0gVGhlIGlucHV0IHRvIGNvbm5lY3QgdG9cbiAgICAgKi9cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgY29ubmVjdCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBvdXRwdXQgdG8gdGhlIGNvbnRleHQncyBkZXN0aW5hdGlvbiBub2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcihcIkMyXCIpLnN0YXJ0KCk7XG4gICAgICogb3NjLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKi9cbiAgICB0b0Rlc3RpbmF0aW9uKCkge1xuICAgICAgICB0aGlzLmNvbm5lY3QodGhpcy5jb250ZXh0LmRlc3RpbmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbm5lY3QgdGhlIG91dHB1dCB0byB0aGUgY29udGV4dCdzIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICogU2VlIFtbdG9EZXN0aW5hdGlvbl1dXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICB0b01hc3RlcigpIHtcbiAgICAgICAgd2FybihcInRvTWFzdGVyKCkgaGFzIGJlZW4gcmVuYW1lZCB0b0Rlc3RpbmF0aW9uKClcIik7XG4gICAgICAgIHJldHVybiB0aGlzLnRvRGVzdGluYXRpb24oKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogZGlzY29ubmVjdCB0aGUgb3V0cHV0XG4gICAgICovXG4gICAgZGlzY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGRpc2Nvbm5lY3QodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gc2VyaWVzLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9oYW5kZHJ1bS1sb29wLm1wM1wiKTtcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKDQpLnN0YXJ0KCk7XG4gICAgICogY29uc3QgZGlzdG9ydGlvbiA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC41KTtcbiAgICAgKiAvLyBjb25uZWN0IHRoZSBwbGF5ZXIgdG8gdGhlIGZpbHRlciwgZGlzdG9ydGlvbiBhbmQgdGhlbiB0byB0aGUgbWFzdGVyIG91dHB1dFxuICAgICAqIHBsYXllci5jaGFpbihmaWx0ZXIsIGRpc3RvcnRpb24sIFRvbmUuRGVzdGluYXRpb24pO1xuICAgICAqL1xuICAgIGNoYWluKC4uLm5vZGVzKSB7XG4gICAgICAgIGNvbm5lY3RTZXJpZXModGhpcywgLi4ubm9kZXMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoaXMgbm9kZSB0byB0aGUgcmVzdCBvZiB0aGUgbm9kZXMgaW4gcGFyYWxsZWwuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vZHJ1bS1zYW1wbGVzL2NvbmdhLXJoeXRobS5tcDNcIik7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogY29uc3QgcGl0Y2hTaGlmdCA9IG5ldyBUb25lLlBpdGNoU2hpZnQoNCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IGZpbHRlciA9IG5ldyBUb25lLkZpbHRlcihcIkc1XCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBjb25uZWN0IGEgbm9kZSB0byB0aGUgcGl0Y2ggc2hpZnQgYW5kIGZpbHRlciBpbiBwYXJhbGxlbFxuICAgICAqIHBsYXllci5mYW4ocGl0Y2hTaGlmdCwgZmlsdGVyKTtcbiAgICAgKi9cbiAgICBmYW4oLi4ubm9kZXMpIHtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHRoaXMuY29ubmVjdChub2RlKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEaXNwb3NlIGFuZCBkaXNjb25uZWN0XG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pbnB1dCBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzQXVkaW9Ob2RlKHRoaXMuaW5wdXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzRGVmaW5lZCh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm91dHB1dCBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0F1ZGlvTm9kZSh0aGlzLm91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm91dHB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFtdO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENPTk5FQ1RJT05TXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8qKlxuICogY29ubmVjdCB0b2dldGhlciBhbGwgb2YgdGhlIGFyZ3VtZW50cyBpbiBzZXJpZXNcbiAqIEBwYXJhbSBub2Rlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdFNlcmllcyguLi5ub2Rlcykge1xuICAgIGNvbnN0IGZpcnN0ID0gbm9kZXMuc2hpZnQoKTtcbiAgICBub2Rlcy5yZWR1Y2UoKHByZXYsIGN1cnJlbnQpID0+IHtcbiAgICAgICAgaWYgKHByZXYgaW5zdGFuY2VvZiBUb25lQXVkaW9Ob2RlKSB7XG4gICAgICAgICAgICBwcmV2LmNvbm5lY3QoY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNBdWRpb05vZGUocHJldikpIHtcbiAgICAgICAgICAgIGNvbm5lY3QocHJldiwgY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGN1cnJlbnQ7XG4gICAgfSwgZmlyc3QpO1xufVxuLyoqXG4gKiBDb25uZWN0IHR3byBub2RlcyB0b2dldGhlciBzbyB0aGF0IHNpZ25hbCBmbG93cyBmcm9tIHRoZVxuICogZmlyc3Qgbm9kZSB0byB0aGUgc2Vjb25kLiBPcHRpb25hbGx5IHNwZWNpZnkgdGhlIGlucHV0IGFuZCBvdXRwdXQgY2hhbm5lbHMuXG4gKiBAcGFyYW0gc3JjTm9kZSBUaGUgc291cmNlIG5vZGVcbiAqIEBwYXJhbSBkc3ROb2RlIFRoZSBkZXN0aW5hdGlvbiBub2RlXG4gKiBAcGFyYW0gb3V0cHV0TnVtYmVyIFRoZSBvdXRwdXQgY2hhbm5lbCBvZiB0aGUgc3JjTm9kZVxuICogQHBhcmFtIGlucHV0TnVtYmVyIFRoZSBpbnB1dCBjaGFubmVsIG9mIHRoZSBkc3ROb2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25uZWN0KHNyY05vZGUsIGRzdE5vZGUsIG91dHB1dE51bWJlciA9IDAsIGlucHV0TnVtYmVyID0gMCkge1xuICAgIGFzc2VydChpc0RlZmluZWQoc3JjTm9kZSksIFwiQ2Fubm90IGNvbm5lY3QgZnJvbSB1bmRlZmluZWQgbm9kZVwiKTtcbiAgICBhc3NlcnQoaXNEZWZpbmVkKGRzdE5vZGUpLCBcIkNhbm5vdCBjb25uZWN0IHRvIHVuZGVmaW5lZCBub2RlXCIpO1xuICAgIGlmIChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBpc0F1ZGlvTm9kZShkc3ROb2RlKSkge1xuICAgICAgICBhc3NlcnQoZHN0Tm9kZS5udW1iZXJPZklucHV0cyA+IDAsIFwiQ2Fubm90IGNvbm5lY3QgdG8gbm9kZSB3aXRoIG5vIGlucHV0c1wiKTtcbiAgICB9XG4gICAgYXNzZXJ0KHNyY05vZGUubnVtYmVyT2ZPdXRwdXRzID4gMCwgXCJDYW5ub3QgY29ubmVjdCBmcm9tIG5vZGUgd2l0aCBubyBvdXRwdXRzXCIpO1xuICAgIC8vIHJlc29sdmUgdGhlIGlucHV0IG9mIHRoZSBkc3ROb2RlXG4gICAgd2hpbGUgKChkc3ROb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSB8fCBkc3ROb2RlIGluc3RhbmNlb2YgUGFyYW0pKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoZHN0Tm9kZS5pbnB1dCkpIHtcbiAgICAgICAgICAgIGRzdE5vZGUgPSBkc3ROb2RlLmlucHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIHdoaWxlIChzcmNOb2RlIGluc3RhbmNlb2YgVG9uZUF1ZGlvTm9kZSkge1xuICAgICAgICBpZiAoaXNEZWZpbmVkKHNyY05vZGUub3V0cHV0KSkge1xuICAgICAgICAgICAgc3JjTm9kZSA9IHNyY05vZGUub3V0cHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIG1ha2UgdGhlIGNvbm5lY3Rpb25cbiAgICBpZiAoaXNBdWRpb1BhcmFtKGRzdE5vZGUpKSB7XG4gICAgICAgIHNyY05vZGUuY29ubmVjdChkc3ROb2RlLCBvdXRwdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3JjTm9kZS5jb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgIH1cbn1cbi8qKlxuICogRGlzY29ubmVjdCBhIG5vZGUgZnJvbSBhbGwgbm9kZXMgb3Igb3B0aW9uYWxseSBpbmNsdWRlIGEgZGVzdGluYXRpb24gbm9kZSBhbmQgaW5wdXQvb3V0cHV0IGNoYW5uZWxzLlxuICogQHBhcmFtIHNyY05vZGUgVGhlIHNvdXJjZSBub2RlXG4gKiBAcGFyYW0gZHN0Tm9kZSBUaGUgZGVzdGluYXRpb24gbm9kZVxuICogQHBhcmFtIG91dHB1dE51bWJlciBUaGUgb3V0cHV0IGNoYW5uZWwgb2YgdGhlIHNyY05vZGVcbiAqIEBwYXJhbSBpbnB1dE51bWJlciBUaGUgaW5wdXQgY2hhbm5lbCBvZiB0aGUgZHN0Tm9kZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGlzY29ubmVjdChzcmNOb2RlLCBkc3ROb2RlLCBvdXRwdXROdW1iZXIgPSAwLCBpbnB1dE51bWJlciA9IDApIHtcbiAgICAvLyByZXNvbHZlIHRoZSBkZXN0aW5hdGlvbiBub2RlXG4gICAgaWYgKGlzRGVmaW5lZChkc3ROb2RlKSkge1xuICAgICAgICB3aGlsZSAoZHN0Tm9kZSBpbnN0YW5jZW9mIFRvbmVBdWRpb05vZGUpIHtcbiAgICAgICAgICAgIGRzdE5vZGUgPSBkc3ROb2RlLmlucHV0O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIHJlc29sdmUgdGhlIHNyYyBub2RlXG4gICAgd2hpbGUgKCEoaXNBdWRpb05vZGUoc3JjTm9kZSkpKSB7XG4gICAgICAgIGlmIChpc0RlZmluZWQoc3JjTm9kZS5vdXRwdXQpKSB7XG4gICAgICAgICAgICBzcmNOb2RlID0gc3JjTm9kZS5vdXRwdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzQXVkaW9QYXJhbShkc3ROb2RlKSkge1xuICAgICAgICBzcmNOb2RlLmRpc2Nvbm5lY3QoZHN0Tm9kZSwgb3V0cHV0TnVtYmVyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoaXNBdWRpb05vZGUoZHN0Tm9kZSkpIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KGRzdE5vZGUsIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3JjTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvTm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogQSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBOYXRpdmUgV2ViIEF1ZGlvIEdhaW5Ob2RlLlxuICogVGhlIEdhaW5Ob2RlIGlzIGEgYmFzaWMgYnVpbGRpbmcgYmxvY2sgb2YgdGhlIFdlYiBBdWRpb1xuICogQVBJIGFuZCBpcyB1c2VmdWwgZm9yIHJvdXRpbmcgYXVkaW8gYW5kIGFkanVzdGluZyBnYWlucy5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGdhaW5Ob2RlID0gbmV3IFRvbmUuR2FpbigwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMzApLmNvbm5lY3QoZ2Fpbk5vZGUpLnN0YXJ0KCk7XG4gKiBcdGdhaW5Ob2RlLmdhaW4ucmFtcFRvKDEsIDAuMSk7XG4gKiBcdGdhaW5Ob2RlLmdhaW4ucmFtcFRvKDAsIDAuNCwgMC4yKTtcbiAqIH0sIDAuNywgMSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBHYWluIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdhaW4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJnYWluXCIsIFwidW5pdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYWluXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgd3JhcHBlZCBHYWluTm9kZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUdhaW4oKTtcbiAgICAgICAgLy8gaW5wdXQgPSBvdXRwdXRcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2dhaW5Ob2RlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoR2Fpbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImdhaW5cIiwgXCJ1bml0c1wiXSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZ2Fpbk5vZGUuZ2FpbixcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImdhaW5cIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgZ2FpbjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImdhaW5cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYWluLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUsIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgZmlyZS1hbmQtZm9yZ2V0IG5vZGVzXG4gKi9cbmV4cG9ydCBjbGFzcyBPbmVTaG90U291cmNlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgdGhlXG4gICAgICAgICAqIHNvdXJjZSBpcyBkb25lIHBsYXlpbmcuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9uZW5kZWQgPSBub09wO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0YXJ0IHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXJ0VGltZSA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN0b3AgdGltZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpZCBvZiB0aGUgdGltZW91dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZW91dCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHB1YmxpYyBvdXRwdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgZ2FpbiBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZ2Fpbk5vZGUgPSB0aGlzLm91dHB1dDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEdldCB0aGUgcGxheWJhY2sgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZ2V0U3RhdGVBdFRpbWUgPSBmdW5jdGlvbiAodGltZSkge1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhcnRUaW1lICE9PSAtMSAmJlxuICAgICAgICAgICAgICAgIGNvbXB1dGVkVGltZSA+PSB0aGlzLl9zdGFydFRpbWUgJiZcbiAgICAgICAgICAgICAgICAodGhpcy5fc3RvcFRpbWUgPT09IC0xIHx8IGNvbXB1dGVkVGltZSA8PSB0aGlzLl9zdG9wVGltZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdGFydGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgICAgICB0aGlzLl9jdXJ2ZSA9IG9wdGlvbnMuY3VydmU7XG4gICAgICAgIHRoaXMub25lbmRlZCA9IG9wdGlvbnMub25lbmRlZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGN1cnZlOiBcImxpbmVhclwiLFxuICAgICAgICAgICAgZmFkZUluOiAwLFxuICAgICAgICAgICAgZmFkZU91dDogMCxcbiAgICAgICAgICAgIG9uZW5kZWQ6IG5vT3AsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RhcnQgdGhlIHNvdXJjZVxuICAgICAqL1xuICAgIF9zdGFydEdhaW4odGltZSwgZ2FpbiA9IDEpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSA9PT0gLTEsIFwiU291cmNlIGNhbm5vdCBiZSBzdGFydGVkIG1vcmUgdGhhbiBvbmNlXCIpO1xuICAgICAgICAvLyBhcHBseSBhIGZhZGUgaW4gZW52ZWxvcGVcbiAgICAgICAgY29uc3QgZmFkZUluVGltZSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuX2ZhZGVJbik7XG4gICAgICAgIC8vIHJlY29yZCB0aGUgc3RhcnQgdGltZVxuICAgICAgICB0aGlzLl9zdGFydFRpbWUgPSB0aW1lICsgZmFkZUluVGltZTtcbiAgICAgICAgdGhpcy5fc3RhcnRUaW1lID0gTWF0aC5tYXgodGhpcy5fc3RhcnRUaW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgZW52ZWxvcGVcbiAgICAgICAgaWYgKGZhZGVJblRpbWUgPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX2N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZ2Fpbk5vZGUuZ2Fpbi5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZShnYWluLCB0aW1lICsgZmFkZUluVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nYWluTm9kZS5nYWluLmV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZShnYWluLCB0aW1lLCBmYWRlSW5UaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoZ2FpbiwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBub2RlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgc291cmNlXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcEdhaW4odGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgc291cmNlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdG8gc3RvcCB0aGUgc291cmNlXG4gICAgICovXG4gICAgX3N0b3BHYWluKHRpbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuX3N0YXJ0VGltZSAhPT0gLTEsIFwiJ3N0YXJ0JyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgJ3N0b3AnXCIpO1xuICAgICAgICAvLyBjYW5jZWwgdGhlIHByZXZpb3VzIHN0b3BcbiAgICAgICAgdGhpcy5jYW5jZWxTdG9wKCk7XG4gICAgICAgIC8vIHRoZSBmYWRlT3V0IHRpbWVcbiAgICAgICAgY29uc3QgZmFkZU91dFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLl9mYWRlT3V0KTtcbiAgICAgICAgLy8gc2NoZWR1bGUgdGhlIHN0b3AgY2FsbGJhY2tcbiAgICAgICAgdGhpcy5fc3RvcFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKSArIGZhZGVPdXRUaW1lO1xuICAgICAgICB0aGlzLl9zdG9wVGltZSA9IE1hdGgubWF4KHRoaXMuX3N0b3BUaW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICBpZiAoZmFkZU91dFRpbWUgPiAwKSB7XG4gICAgICAgICAgICAvLyBzdGFydCB0aGUgZmFkZSBvdXQgY3VydmUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICAgIGlmICh0aGlzLl9jdXJ2ZSA9PT0gXCJsaW5lYXJcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4ubGluZWFyUmFtcFRvKDAsIGZhZGVPdXRUaW1lLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4udGFyZ2V0UmFtcFRvKDAsIGZhZGVPdXRUaW1lLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHN0b3AgYW55IG9uZ29pbmcgcmFtcHMsIGFuZCBzZXQgdGhlIHZhbHVlIHRvIDBcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICAgICAgdGhpcy5fdGltZW91dCA9IHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vIGFsbG93IGFkZGl0aW9uYWwgdGltZSBmb3IgdGhlIGV4cG9uZW50aWFsIGN1cnZlIHRvIGZ1bGx5IGRlY2F5XG4gICAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsVGFpbCA9IHRoaXMuX2N1cnZlID09PSBcImV4cG9uZW50aWFsXCIgPyBmYWRlT3V0VGltZSAqIDIgOiAwO1xuICAgICAgICAgICAgdGhpcy5fc3RvcFNvdXJjZSh0aGlzLm5vdygpICsgYWRkaXRpb25hbFRhaWwpO1xuICAgICAgICAgICAgdGhpcy5fb25lbmRlZCgpO1xuICAgICAgICB9LCB0aGlzLl9zdG9wVGltZSAtIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIG9uZW5kZWQgY2FsbGJhY2tcbiAgICAgKi9cbiAgICBfb25lbmRlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMub25lbmRlZCAhPT0gbm9PcCkge1xuICAgICAgICAgICAgdGhpcy5vbmVuZGVkKHRoaXMpO1xuICAgICAgICAgICAgLy8gb3ZlcndyaXRlIG9uZW5kZWQgdG8gbWFrZSBzdXJlIGl0IG9ubHkgaXMgY2FsbGVkIG9uY2VcbiAgICAgICAgICAgIHRoaXMub25lbmRlZCA9IG5vT3A7XG4gICAgICAgICAgICAvLyBkaXNwb3NlIHdoZW4gaXQncyBlbmRlZCB0byBmcmVlIHVwIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24gb25seSBpbiB0aGUgb25saW5lIGNvbnRleHRcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRpc3Bvc2VDYWxsYmFjayA9ICgpID0+IHRoaXMuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5yZXF1ZXN0SWRsZUNhbGxiYWNrICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LnJlcXVlc3RJZGxlQ2FsbGJhY2soZGlzcG9zZUNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZGlzcG9zZUNhbGxiYWNrLCAxMDAwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGUgY3VycmVudCB0aW1lXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FuY2VsIGEgc2NoZWR1bGVkIHN0b3AgZXZlbnRcbiAgICAgKi9cbiAgICBjYW5jZWxTdG9wKCkge1xuICAgICAgICB0aGlzLmxvZyhcImNhbmNlbFN0b3BcIik7XG4gICAgICAgIGFzc2VydCh0aGlzLl9zdGFydFRpbWUgIT09IC0xLCBcIlNvdXJjZSBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBzdG9wIGVudmVsb3BlXG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMuX3N0YXJ0VGltZSArIHRoaXMuc2FtcGxlVGltZSk7XG4gICAgICAgIHRoaXMuY29udGV4dC5jbGVhclRpbWVvdXQodGhpcy5fdGltZW91dCk7XG4gICAgICAgIHRoaXMuX3N0b3BUaW1lID0gLTE7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T25lU2hvdFNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgT25lU2hvdFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvT25lU2hvdFNvdXJjZVwiO1xuLyoqXG4gKiBXcmFwcGVyIGFyb3VuZCB0aGUgbmF0aXZlIGZpcmUtYW5kLWZvcmdldCBDb25zdGFudFNvdXJjZS5cbiAqIEFkZHMgdGhlIGFiaWxpdHkgdG8gcmVzY2hlZHVsZSB0aGUgc3RvcCBtZXRob2QuXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBUb25lQ29uc3RhbnRTb3VyY2UgZXh0ZW5kcyBPbmVTaG90U291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUNvbnN0YW50U291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib2Zmc2V0XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUNvbnN0YW50U291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc2lnbmFsIGdlbmVyYXRvclxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnN0YW50U291cmNlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQ29uc3RhbnRTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJvZmZzZXRcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NvdXJjZSwgdGhpcy5fZ2Fpbk5vZGUpO1xuICAgICAgICB0aGlzLm9mZnNldCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fc291cmNlLm9mZnNldCxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub2Zmc2V0LFxuICAgICAgICAgICAgbWluVmFsdWU6IG9wdGlvbnMubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogb3B0aW9ucy5tYXhWYWx1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb252ZXJ0OiB0cnVlLFxuICAgICAgICAgICAgb2Zmc2V0OiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwibnVtYmVyXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgc291cmNlIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgc291cmNlXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJzdGFydFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydEdhaW4oY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc291cmNlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5vZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQ29uc3RhbnRTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBpc0F1ZGlvUGFyYW0gfSBmcm9tIFwiLi4vY29yZS91dGlsL0FkdmFuY2VkVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRvbmVDb25zdGFudFNvdXJjZSB9IGZyb20gXCIuL1RvbmVDb25zdGFudFNvdXJjZVwiO1xuLyoqXG4gKiBBIHNpZ25hbCBpcyBhbiBhdWRpby1yYXRlIHZhbHVlLiBUb25lLlNpZ25hbCBpcyBhIGNvcmUgY29tcG9uZW50IG9mIHRoZSBsaWJyYXJ5LlxuICogVW5saWtlIGEgbnVtYmVyLCBTaWduYWxzIGNhbiBiZSBzY2hlZHVsZWQgd2l0aCBzYW1wbGUtbGV2ZWwgYWNjdXJhY3kuIFRvbmUuU2lnbmFsXG4gKiBoYXMgYWxsIG9mIHRoZSBtZXRob2RzIGF2YWlsYWJsZSB0byBuYXRpdmUgV2ViIEF1ZGlvXG4gKiBbQXVkaW9QYXJhbV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyN0aGUtYXVkaW9wYXJhbS1pbnRlcmZhY2UpXG4gKiBhcyB3ZWxsIGFzIGFkZGl0aW9uYWwgY29udmVuaWVuY2VzLiBSZWFkIG1vcmUgYWJvdXQgd29ya2luZyB3aXRoIHNpZ25hbHNcbiAqIFtoZXJlXShodHRwczovL2dpdGh1Yi5jb20vVG9uZWpzL1RvbmUuanMvd2lraS9TaWduYWxzKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogLy8gYSBzY2hlZHVsZWFibGUgc2lnbmFsIHdoaWNoIGNhbiBiZSBjb25uZWN0ZWQgdG8gY29udHJvbCBhbiBBdWRpb1BhcmFtIG9yIGFub3RoZXIgU2lnbmFsXG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoe1xuICogXHR2YWx1ZTogXCJDNFwiLFxuICogXHR1bml0czogXCJmcmVxdWVuY3lcIlxuICogfSkuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAqIC8vIHRoZSBzY2hlZHVsZWQgcmFtcCBjb250cm9scyB0aGUgY29ubmVjdGVkIHNpZ25hbFxuICogc2lnbmFsLnJhbXBUbyhcIkMyXCIsIDQsIFwiKzAuNVwiKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25hbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2lnbmFsXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmRpY2F0ZXMgaWYgdGhlIHZhbHVlIHNob3VsZCBiZSBvdmVycmlkZGVuIG9uIGNvbm5lY3Rpb24uXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gdHJ1ZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCIsIFwidW5pdHNcIl0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2NvbnN0YW50U291cmNlID0gbmV3IFRvbmVDb25zdGFudFNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBvcHRpb25zLmNvbnZlcnQsXG4gICAgICAgICAgICBvZmZzZXQ6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIG1pblZhbHVlOiBvcHRpb25zLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IG9wdGlvbnMubWF4VmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5zdGFydCgwKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3BhcmFtID0gdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY29udmVydDogdHJ1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBjb25uZWN0KGRlc3RpbmF0aW9uLCBvdXRwdXROdW0gPSAwLCBpbnB1dE51bSA9IDApIHtcbiAgICAgICAgLy8gc3RhcnQgaXQgb25seSB3aGVuIGNvbm5lY3RlZCB0byBzb21ldGhpbmdcbiAgICAgICAgY29ubmVjdFNpZ25hbCh0aGlzLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gQUJTVFJBQ1QgUEFSQU0gSU5URVJGQUNFXG4gICAgLy8ganVzdCBhIHByb3h5IGZvciB0aGUgQ29uc3RhbnRTb3VyY2VOb2RlJ3Mgb2Zmc2V0IEF1ZGlvUGFyYW1cbiAgICAvLyBhbGwgZG9jcyBhcmUgZ2VuZXJhdGVkIGZyb20gQWJzdHJhY3RQYXJhbS50c1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldFZhbHVlQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBzZXRSYW1wUG9pbnQodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5zZXRSYW1wUG9pbnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICB0aGlzLl9wYXJhbS5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBleHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIHN0YXJ0VGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0udGFyZ2V0UmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsQXBwcm9hY2hWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSwgcmFtcFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lLCByYW1wVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzZXRUYXJnZXRBdFRpbWUodmFsdWUsIHN0YXJ0VGltZSwgdGltZUNvbnN0YW50KSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLnNldFRhcmdldEF0VGltZSh2YWx1ZSwgc3RhcnRUaW1lLCB0aW1lQ29uc3RhbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIHN0YXJ0VGltZSwgZHVyYXRpb24sIHNjYWxpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNhbmNlbEFuZEhvbGRBdFRpbWUodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICByYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0ucmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcmFtLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fcGFyYW0udmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgZ2V0IGNvbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5jb252ZXJ0O1xuICAgIH1cbiAgICBzZXQgY29udmVydChjb252ZXJ0KSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLmNvbnZlcnQgPSBjb252ZXJ0O1xuICAgIH1cbiAgICBnZXQgdW5pdHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS51bml0cztcbiAgICB9XG4gICAgZ2V0IG92ZXJyaWRkZW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5vdmVycmlkZGVuO1xuICAgIH1cbiAgICBzZXQgb3ZlcnJpZGRlbihvdmVycmlkZGVuKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLm92ZXJyaWRkZW4gPSBvdmVycmlkZGVuO1xuICAgIH1cbiAgICBnZXQgbWF4VmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tYXhWYWx1ZTtcbiAgICB9XG4gICAgZ2V0IG1pblZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0ubWluVmFsdWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlZSBbW1BhcmFtLmFwcGx5XV0uXG4gICAgICovXG4gICAgYXBwbHkocGFyYW0pIHtcbiAgICAgICAgdGhpcy5fcGFyYW0uYXBwbHkocGFyYW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIFdoZW4gY29ubmVjdGluZyBmcm9tIGEgc2lnbmFsLCBpdCdzIG5lY2Vzc2FyeSB0byB6ZXJvIG91dCB0aGUgbm9kZSBkZXN0aW5hdGlvblxuICogbm9kZSBpZiB0aGF0IG5vZGUgaXMgYWxzbyBhIHNpZ25hbC4gSWYgdGhlIGRlc3RpbmF0aW9uIGlzIG5vdCAwLCB0aGVuIHRoZSB2YWx1ZXNcbiAqIHdpbGwgYmUgc3VtbWVkLiBUaGlzIG1ldGhvZCBpbnN1cmVzIHRoYXQgdGhlIG91dHB1dCBvZiB0aGUgZGVzdGluYXRpb24gc2lnbmFsIHdpbGxcbiAqIGJlIHRoZSBzYW1lIGFzIHRoZSBzb3VyY2Ugc2lnbmFsLCBtYWtpbmcgdGhlIGRlc3RpbmF0aW9uIHNpZ25hbCBhIHBhc3MgdGhyb3VnaCBub2RlLlxuICogQHBhcmFtIHNpZ25hbCBUaGUgb3V0cHV0IHNpZ25hbCB0byBjb25uZWN0IGZyb21cbiAqIEBwYXJhbSBkZXN0aW5hdGlvbiB0aGUgZGVzdGluYXRpb24gdG8gY29ubmVjdCB0b1xuICogQHBhcmFtIG91dHB1dE51bSB0aGUgb3B0aW9uYWwgb3V0cHV0IG51bWJlclxuICogQHBhcmFtIGlucHV0TnVtIHRoZSBpbnB1dCBudW1iZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RTaWduYWwoc2lnbmFsLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSkge1xuICAgIGlmIChkZXN0aW5hdGlvbiBpbnN0YW5jZW9mIFBhcmFtIHx8IGlzQXVkaW9QYXJhbShkZXN0aW5hdGlvbikgfHxcbiAgICAgICAgKGRlc3RpbmF0aW9uIGluc3RhbmNlb2YgU2lnbmFsICYmIGRlc3RpbmF0aW9uLm92ZXJyaWRlKSkge1xuICAgICAgICAvLyBjYW5jZWwgY2hhbmdlc1xuICAgICAgICBkZXN0aW5hdGlvbi5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoMCk7XG4gICAgICAgIC8vIHJlc2V0IHRoZSB2YWx1ZVxuICAgICAgICBkZXN0aW5hdGlvbi5zZXRWYWx1ZUF0VGltZSgwLCAwKTtcbiAgICAgICAgLy8gbWFyayB0aGUgdmFsdWUgYXMgb3ZlcnJpZGRlblxuICAgICAgICBpZiAoZGVzdGluYXRpb24gaW5zdGFuY2VvZiBTaWduYWwpIHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uLm92ZXJyaWRkZW4gPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbm5lY3Qoc2lnbmFsLCBkZXN0aW5hdGlvbiwgb3V0cHV0TnVtLCBpbnB1dE51bSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaWduYWwuanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNVbmRlZiB9IGZyb20gXCIuLi91dGlsL1R5cGVDaGVja1wiO1xuLyoqXG4gKiBBIFBhcmFtIGNsYXNzIGp1c3QgZm9yIGNvbXB1dGluZyB0aWNrcy4gU2ltaWxhciB0byB0aGUgW1tQYXJhbV1dIGNsYXNzLFxuICogYnV0IG9mZmVycyBjb252ZXJzaW9uIHRvIEJQTSB2YWx1ZXMgYXMgd2VsbCBhcyBhYmlsaXR5IHRvIGNvbXB1dGUgdGlja1xuICogZHVyYXRpb24gYW5kIGVsYXBzZWQgdGlja3NcbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tQYXJhbSBleHRlbmRzIFBhcmFtIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1BhcmFtLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrUGFyYW1cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lbGluZSB3aGljaCB0cmFja3MgYWxsIG9mIHRoZSBhdXRvbWF0aW9ucy5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBUaW1lbGluZShJbmZpbml0eSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW50ZXJuYWwgaG9sZGVyIGZvciB0aGUgbXVsdGlwbGllciB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbXVsdGlwbGllciA9IDE7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrUGFyYW0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIC8vIHNldCB0aGUgbXVsdGlwbGllclxuICAgICAgICB0aGlzLl9tdWx0aXBsaWVyID0gb3B0aW9ucy5tdWx0aXBsaWVyO1xuICAgICAgICAvLyBjbGVhciB0aGUgdGlja3MgZnJvbSB0aGUgYmVnaW5uaW5nXG4gICAgICAgIHRoaXMuX2V2ZW50cy5jYW5jZWwoMCk7XG4gICAgICAgIC8vIHNldCBhbiBpbml0aWFsIGV2ZW50XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoe1xuICAgICAgICAgICAgdGlja3M6IDAsXG4gICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzZXRWYWx1ZUF0VGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuX2Zyb21UeXBlKG9wdGlvbnMudmFsdWUpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihQYXJhbS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtdWx0aXBsaWVyOiAxLFxuICAgICAgICAgICAgdW5pdHM6IFwiaGVydHpcIixcbiAgICAgICAgICAgIHZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCB0aW1lLCBjb25zdGFudCkge1xuICAgICAgICAvLyBhcHByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuc2V0UmFtcFBvaW50KHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFZhbHVlID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBzdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG4gICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgxIC8gY29uc3RhbnQsIDEpKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gc2VnbWVudHM7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc2VnVGltZSA9IGNvbnN0YW50ICogaSArIHRpbWU7XG4gICAgICAgICAgICBjb25zdCByYW1wVmFsID0gdGhpcy5fZXhwb25lbnRpYWxBcHByb2FjaChwcmV2RXZlbnQudGltZSwgcHJldkV2ZW50LnZhbHVlLCBjb21wdXRlZFZhbHVlLCBjb25zdGFudCwgc2VnVGltZSk7XG4gICAgICAgICAgICB0aGlzLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHRoaXMuX3RvVHlwZShyYW1wVmFsKSwgc2VnVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBzdXBlci5zZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICBjb25zdCB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBldmVudC50aWNrcyA9IE1hdGgubWF4KHRpY2tzVW50aWxUaW1lLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICBjb25zdCB0aWNrc1VudGlsVGltZSA9IHRoaXMuX2dldFRpY2tzVW50aWxFdmVudChwcmV2aW91c0V2ZW50LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICBldmVudC50aWNrcyA9IE1hdGgubWF4KHRpY2tzVW50aWxUaW1lLCAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgLy8gYXByb3hpbWF0ZSBpdCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wc1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVmFsID0gdGhpcy5fZnJvbVR5cGUodmFsdWUpO1xuICAgICAgICAvLyBzdGFydCBmcm9tIHByZXZpb3VzbHkgc2NoZWR1bGVkIHZhbHVlXG4gICAgICAgIGNvbnN0IHByZXZFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIC8vIGFwcHJveCAxMCBzZWdtZW50cyBwZXIgc2Vjb25kXG4gICAgICAgIGNvbnN0IHNlZ21lbnRzID0gTWF0aC5yb3VuZChNYXRoLm1heCgodGltZSAtIHByZXZFdmVudC50aW1lKSAqIDEwLCAxKSk7XG4gICAgICAgIGNvbnN0IHNlZ21lbnREdXIgPSAoKHRpbWUgLSBwcmV2RXZlbnQudGltZSkgLyBzZWdtZW50cyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHNlZ21lbnRzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlZ1RpbWUgPSBzZWdtZW50RHVyICogaSArIHByZXZFdmVudC50aW1lO1xuICAgICAgICAgICAgY29uc3QgcmFtcFZhbCA9IHRoaXMuX2V4cG9uZW50aWFsSW50ZXJwb2xhdGUocHJldkV2ZW50LnRpbWUsIHByZXZFdmVudC52YWx1ZSwgdGltZSwgY29tcHV0ZWRWYWwsIHNlZ1RpbWUpO1xuICAgICAgICAgICAgdGhpcy5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh0aGlzLl90b1R5cGUocmFtcFZhbCksIHNlZ1RpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcbiAgICAgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG4gICAgICogQHBhcmFtICBldmVudCBUaGUgdGltZSB0byBnZXQgdGhlIHRpY2sgY291bnQgYXRcbiAgICAgKiBAcmV0dXJuIFRoZSBudW1iZXIgb2YgdGlja3Mgd2hpY2ggaGF2ZSBlbGFwc2VkIGF0IHRoZSB0aW1lIGdpdmVuIGFueSBhdXRvbWF0aW9ucy5cbiAgICAgKi9cbiAgICBfZ2V0VGlja3NVbnRpbEV2ZW50KGV2ZW50LCB0aW1lKSB7XG4gICAgICAgIGlmIChldmVudCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZXZlbnQgPSB7XG4gICAgICAgICAgICAgICAgdGlja3M6IDAsXG4gICAgICAgICAgICAgICAgdGltZTogMCxcbiAgICAgICAgICAgICAgICB0eXBlOiBcInNldFZhbHVlQXRUaW1lXCIsXG4gICAgICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzVW5kZWYoZXZlbnQudGlja3MpKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fZXZlbnRzLnByZXZpb3VzRXZlbnQoZXZlbnQpO1xuICAgICAgICAgICAgZXZlbnQudGlja3MgPSB0aGlzLl9nZXRUaWNrc1VudGlsRXZlbnQocHJldmlvdXNFdmVudCwgZXZlbnQudGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsMCA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUoZXZlbnQudGltZSkpO1xuICAgICAgICBsZXQgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSkpO1xuICAgICAgICAvLyBpZiBpdCdzIHJpZ2h0IG9uIHRoZSBsaW5lLCB0YWtlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgICBjb25zdCBvblRoZUxpbmVFdmVudCA9IHRoaXMuX2V2ZW50cy5nZXQodGltZSk7XG4gICAgICAgIGlmIChvblRoZUxpbmVFdmVudCAmJiBvblRoZUxpbmVFdmVudC50aW1lID09PSB0aW1lICYmIG9uVGhlTGluZUV2ZW50LnR5cGUgPT09IFwic2V0VmFsdWVBdFRpbWVcIikge1xuICAgICAgICAgICAgdmFsMSA9IHRoaXMuX2Zyb21UeXBlKHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSAtIHRoaXMuc2FtcGxlVGltZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwLjUgKiAodGltZSAtIGV2ZW50LnRpbWUpICogKHZhbDAgKyB2YWwxKSArIGV2ZW50LnRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aWNrIHZhbHVlIGF0IHRoZSB0aW1lLiBUYWtlcyBpbnRvIGFjY291bnRcbiAgICAgKiBhbnkgYXV0b21hdGlvbiBjdXJ2ZXMgc2NoZWR1bGVkIG9uIHRoZSBzaWduYWwuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgdGljayBjb3VudCBhdFxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrcyB3aGljaCBoYXZlIGVsYXBzZWQgYXQgdGhlIHRpbWUgZ2l2ZW4gYW55IGF1dG9tYXRpb25zLlxuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fZXZlbnRzLmdldChjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgodGhpcy5fZ2V0VGlja3NVbnRpbEV2ZW50KGV2ZW50LCBjb21wdXRlZFRpbWUpLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHRpbWUgb2YgdGhlIG51bWJlciBvZiB0aWNrcyBmcm9tIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtIHRpY2tzIFRoZSBudW1iZXIgb2YgdGlja3MgdG8gY2FsY3VsYXRlXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHRvIGdldCB0aGUgbmV4dCB0aWNrIGZyb21cbiAgICAgKiBAcmV0dXJuIFRoZSBkdXJhdGlvbiBvZiB0aGUgbnVtYmVyIG9mIHRpY2tzIGZyb20gdGhlIGdpdmVuIHRpbWUgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIGdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgY3VycmVudFRpY2sgPSB0aGlzLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUaW1lT2ZUaWNrKGN1cnJlbnRUaWNrICsgdGlja3MpIC0gY29tcHV0ZWRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHaXZlbiBhIHRpY2ssIHJldHVybnMgdGhlIHRpbWUgdGhhdCB0aWNrIG9jY3VycyBhdC5cbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIHRoYXQgdGhlIHRpY2sgb2NjdXJzLlxuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaykge1xuICAgICAgICBjb25zdCBiZWZvcmUgPSB0aGlzLl9ldmVudHMuZ2V0KHRpY2ssIFwidGlja3NcIik7XG4gICAgICAgIGNvbnN0IGFmdGVyID0gdGhpcy5fZXZlbnRzLmdldEFmdGVyKHRpY2ssIFwidGlja3NcIik7XG4gICAgICAgIGlmIChiZWZvcmUgJiYgYmVmb3JlLnRpY2tzID09PSB0aWNrKSB7XG4gICAgICAgICAgICByZXR1cm4gYmVmb3JlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlICYmIGFmdGVyICYmXG4gICAgICAgICAgICBhZnRlci50eXBlID09PSBcImxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lXCIgJiZcbiAgICAgICAgICAgIGJlZm9yZS52YWx1ZSAhPT0gYWZ0ZXIudmFsdWUpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbDAgPSB0aGlzLl9mcm9tVHlwZSh0aGlzLmdldFZhbHVlQXRUaW1lKGJlZm9yZS50aW1lKSk7XG4gICAgICAgICAgICBjb25zdCB2YWwxID0gdGhpcy5fZnJvbVR5cGUodGhpcy5nZXRWYWx1ZUF0VGltZShhZnRlci50aW1lKSk7XG4gICAgICAgICAgICBjb25zdCBkZWx0YSA9ICh2YWwxIC0gdmFsMCkgLyAoYWZ0ZXIudGltZSAtIGJlZm9yZS50aW1lKTtcbiAgICAgICAgICAgIGNvbnN0IGsgPSBNYXRoLnNxcnQoTWF0aC5wb3codmFsMCwgMikgLSAyICogZGVsdGEgKiAoYmVmb3JlLnRpY2tzIC0gdGljaykpO1xuICAgICAgICAgICAgY29uc3Qgc29sMSA9ICgtdmFsMCArIGspIC8gZGVsdGE7XG4gICAgICAgICAgICBjb25zdCBzb2wyID0gKC12YWwwIC0gaykgLyBkZWx0YTtcbiAgICAgICAgICAgIHJldHVybiAoc29sMSA+IDAgPyBzb2wxIDogc29sMikgKyBiZWZvcmUudGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiZWZvcmUpIHtcbiAgICAgICAgICAgIGlmIChiZWZvcmUudmFsdWUgPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gSW5maW5pdHk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYmVmb3JlLnRpbWUgKyAodGljayAtIGJlZm9yZS50aWNrcykgLyBiZWZvcmUudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGljayAvIHRoaXMuX2luaXRpYWxWYWx1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IHNvbWUgbnVtYmVyIG9mIHRpY2tzIHRoZWlyIHRoZSBkdXJhdGlvbiBpbiBzZWNvbmRzIGFjY291bnRpbmdcbiAgICAgKiBmb3IgYW55IGF1dG9tYXRpb24gY3VydmVzIHN0YXJ0aW5nIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGlja3MgVGhlIG51bWJlciBvZiB0aWNrcyB0byBjb252ZXJ0IHRvIHNlY29uZHMuXG4gICAgICogQHBhcmFtICB3aGVuICBXaGVuIGFsb25nIHRoZSBhdXRvbWF0aW9uIHRpbWVsaW5lIHRvIGNvbnZlcnQgdGhlIHRpY2tzLlxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgb2YgdGhlIHRpY2tzLlxuICAgICAqL1xuICAgIHRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldER1cmF0aW9uT2ZUaWNrcyh0aWNrcywgd2hlbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbnZlcnNlIG9mIFtbdGlja3NUb1RpbWVdXS4gQ29udmVydCBhIGR1cmF0aW9uIGluXG4gICAgICogc2Vjb25kcyB0byB0aGUgY29ycmVzcG9uZGluZyBudW1iZXIgb2YgdGlja3MgYWNjb3VudGluZyBmb3IgYW55XG4gICAgICogYXV0b21hdGlvbiBjdXJ2ZXMgc3RhcnRpbmcgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICBkdXJhdGlvbiBUaGUgdGltZSBpbnRlcnZhbCB0byBjb252ZXJ0IHRvIHRpY2tzLlxuICAgICAqIEBwYXJhbSAgd2hlbiBXaGVuIGFsb25nIHRoZSBhdXRvbWF0aW9uIHRpbWVsaW5lIHRvIGNvbnZlcnQgdGhlIHRpY2tzLlxuICAgICAqIEByZXR1cm4gVGhlIGR1cmF0aW9uIGluIHRpY2tzLlxuICAgICAqL1xuICAgIHRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBjb25zdCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICBjb25zdCBzdGFydFRpY2tzID0gdGhpcy5nZXRUaWNrc0F0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICBjb25zdCBlbmRUaWNrcyA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgIHJldHVybiBlbmRUaWNrcyAtIHN0YXJ0VGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgZnJvbSB0aGUgdHlwZSB3aGVuIHRoZSB1bml0IHZhbHVlIGlzIEJQTVxuICAgICAqL1xuICAgIF9mcm9tVHlwZSh2YWwpIHtcbiAgICAgICAgaWYgKHRoaXMudW5pdHMgPT09IFwiYnBtXCIgJiYgdGhpcy5tdWx0aXBsaWVyKSB7XG4gICAgICAgICAgICByZXR1cm4gMSAvICg2MCAvIHZhbCAvIHRoaXMubXVsdGlwbGllcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIuX2Zyb21UeXBlKHZhbCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lhbCBjYXNlIG9mIHR5cGUgY29udmVyc2lvbiB3aGVyZSB0aGUgdW5pdHMgPT09IFwiYnBtXCJcbiAgICAgKi9cbiAgICBfdG9UeXBlKHZhbCkge1xuICAgICAgICBpZiAodGhpcy51bml0cyA9PT0gXCJicG1cIiAmJiB0aGlzLm11bHRpcGxpZXIpIHtcbiAgICAgICAgICAgIHJldHVybiAodmFsIC8gdGhpcy5tdWx0aXBsaWVyKSAqIDYwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHN1cGVyLl90b1R5cGUodmFsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIG11bHRpcGxpZXIgb24gdGhlIGJwbSB2YWx1ZS4gVXNlZnVsIGZvciBzZXR0aW5nIGEgUFBRIHJlbGF0aXZlIHRvIHRoZSBiYXNlIGZyZXF1ZW5jeSB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgbXVsdGlwbGllcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX211bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBtdWx0aXBsaWVyKG0pIHtcbiAgICAgICAgLy8gZ2V0IGFuZCByZXNldCB0aGUgY3VycmVudCB2YWx1ZSB3aXRoIHRoZSBuZXcgbXVsdGlwbGllclxuICAgICAgICAvLyBtaWdodCBiZSBuZWNlc3NhcnkgdG8gY2xlYXIgYWxsIHRoZSBwcmV2aW91cyB2YWx1ZXNcbiAgICAgICAgY29uc3QgY3VycmVudFZhbCA9IHRoaXMudmFsdWU7XG4gICAgICAgIHRoaXMuX211bHRpcGxpZXIgPSBtO1xuICAgICAgICB0aGlzLmNhbmNlbFNjaGVkdWxlZFZhbHVlcygwKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShjdXJyZW50VmFsLCAwKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrUGFyYW0uanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRpY2tQYXJhbSB9IGZyb20gXCIuL1RpY2tQYXJhbVwiO1xuLyoqXG4gKiBUaWNrU2lnbmFsIGV4dGVuZHMgVG9uZS5TaWduYWwsIGJ1dCBhZGRzIHRoZSBjYXBhYmlsaXR5XG4gKiB0byBjYWxjdWxhdGUgdGhlIG51bWJlciBvZiBlbGFwc2VkIHRpY2tzLiBleHBvbmVudGlhbCBhbmQgdGFyZ2V0IGN1cnZlc1xuICogYXJlIGFwcHJveGltYXRlZCB3aXRoIG11bHRpcGxlIGxpbmVhciByYW1wcy5cbiAqXG4gKiBUaGFuayB5b3UgQnJ1bm8gRGlhcywgSC4gU29maWEgUGludG8sIGFuZCBEYXZpZCBNLiBNYXRvcyxcbiAqIGZvciB5b3VyIFtXQUMgcGFwZXJdKGh0dHBzOi8vc21hcnRlY2guZ2F0ZWNoLmVkdS9iaXRzdHJlYW0vaGFuZGxlLzE4NTMvNTQ1ODgvV0FDMjAxNi00OS5wZGYpXG4gKiBkZXNjcmliaW5nIGludGVncmF0aW5nIHRpbWluZyBmdW5jdGlvbnMgZm9yIHRlbXBvIGNhbGN1bGF0aW9ucy5cbiAqL1xuZXhwb3J0IGNsYXNzIFRpY2tTaWduYWwgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrU2lnbmFsXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUaWNrU2lnbmFsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fcGFyYW0gPSBuZXcgVGlja1BhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IG9wdGlvbnMuY29udmVydCxcbiAgICAgICAgICAgIG11bHRpcGxpZXI6IG9wdGlvbnMubXVsdGlwbGllcixcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQsXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnZhbHVlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTaWduYWwuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXVsdGlwbGllcjogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgICAgICB2YWx1ZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRpY2tzVG9UaW1lKHRpY2tzLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS50aWNrc1RvVGltZSh0aWNrcywgd2hlbik7XG4gICAgfVxuICAgIHRpbWVUb1RpY2tzKGR1cmF0aW9uLCB3aGVuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS50aW1lVG9UaWNrcyhkdXJhdGlvbiwgd2hlbik7XG4gICAgfVxuICAgIGdldFRpbWVPZlRpY2sodGljaykge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFyYW0uZ2V0VGltZU9mVGljayh0aWNrKTtcbiAgICB9XG4gICAgZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXREdXJhdGlvbk9mVGlja3ModGlja3MsIHRpbWUpO1xuICAgIH1cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSBtdWx0aXBsaWVyIG9uIHRoZSBicG0gdmFsdWUuIFVzZWZ1bCBmb3Igc2V0dGluZyBhIFBQUSByZWxhdGl2ZSB0byB0aGUgYmFzZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IG11bHRpcGxpZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJhbS5tdWx0aXBsaWVyO1xuICAgIH1cbiAgICBzZXQgbXVsdGlwbGllcihtKSB7XG4gICAgICAgIHRoaXMuX3BhcmFtLm11bHRpcGxpZXIgPSBtO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcmFtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGlja1NpZ25hbC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBUaWNrU2lnbmFsIH0gZnJvbSBcIi4vVGlja1NpZ25hbFwiO1xuaW1wb3J0IHsgRVEgfSBmcm9tIFwiLi4vdXRpbC9NYXRoXCI7XG4vKipcbiAqIFVzZXMgW1RpY2tTaWduYWxdKFRpY2tTaWduYWwpIHRvIHRyYWNrIGVsYXBzZWQgdGlja3Mgd2l0aCBjb21wbGV4IGF1dG9tYXRpb24gY3VydmVzLlxuICovXG5leHBvcnQgY2xhc3MgVGlja1NvdXJjZSBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRpY2tTb3VyY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrU291cmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgc3RhdGUgdGltZWxpbmVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvZmZzZXQgdmFsdWVzIG9mIHRoZSB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGlja09mZnNldCA9IG5ldyBUaW1lbGluZSgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVGlja1NvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFRpY2tTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IG9wdGlvbnMudW5pdHMsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHN0YXRlXG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCAwKTtcbiAgICAgICAgLy8gYWRkIHRoZSBmaXJzdCBldmVudFxuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKDAsIDApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgIH0sIFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgZWl0aGVyIFwic3RhcnRlZFwiLCBcInN0b3BwZWRcIiBvciBcInBhdXNlZFwiLlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U3RhdGVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBjbG9jayBhdCB0aGUgZ2l2ZW4gdGltZS4gT3B0aW9uYWxseSBwYXNzIGluIGFuIG9mZnNldFxuICAgICAqIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSBvZmZzZXQgVGhlIG51bWJlciBvZiB0aWNrcyB0byBzdGFydCB0aGUgc291cmNlIGF0XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKGlzRGVmaW5lZChvZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUaWNrc0F0VGltZShvZmZzZXQsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGNsb2NrLiBTdG9wcGluZyB0aGUgY2xvY2sgcmVzZXRzIHRoZSB0aWNrIGNvdW50ZXIgdG8gMC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoZXZlbnQgJiYgZXZlbnQudGltZSA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbChldmVudC50aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoZXZlbnQudGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKDAsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwicGF1c2VkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBzdGFydC9zdG9wL3BhdXNlIGFuZCBzZXRUaWNrQXRUaW1lIGV2ZW50cyBzY2hlZHVsZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0byBjbGVhciB0aGUgZXZlbnRzIGFmdGVyXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuY2FuY2VsKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBlbGFwc2VkIHRpY2tzIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgdGljayB2YWx1ZVxuICAgICAqIEByZXR1cm4gVGhlIG51bWJlciBvZiB0aWNrc1xuICAgICAqL1xuICAgIGdldFRpY2tzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShcInN0b3BwZWRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgLy8gdGhpcyBldmVudCBhbGxvd3MgZm9yRWFjaEJldHdlZW4gdG8gaXRlcmF0ZSB1bnRpbCB0aGUgY3VycmVudCB0aW1lXG4gICAgICAgIGNvbnN0IHRtcEV2ZW50ID0geyBzdGF0ZTogXCJwYXVzZWRcIiwgdGltZTogY29tcHV0ZWRUaW1lIH07XG4gICAgICAgIHRoaXMuX3N0YXRlLmFkZCh0bXBFdmVudCk7XG4gICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgdGhlIHByZXZpb3VzIG9mZnNldCBldmVudFxuICAgICAgICBsZXQgbGFzdFN0YXRlID0gc3RvcEV2ZW50O1xuICAgICAgICBsZXQgZWxhcHNlZFRpY2tzID0gMDtcbiAgICAgICAgLy8gaXRlcmF0ZSB0aHJvdWdoIGFsbCB0aGUgZXZlbnRzIHNpbmNlIHRoZSBsYXN0IHN0b3BcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEJldHdlZW4oc3RvcEV2ZW50LnRpbWUsIGNvbXB1dGVkVGltZSArIHRoaXMuc2FtcGxlVGltZSwgZSA9PiB7XG4gICAgICAgICAgICBsZXQgcGVyaW9kU3RhcnRUaW1lID0gbGFzdFN0YXRlLnRpbWU7XG4gICAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBvZmZzZXQgZXZlbnQgaW4gdGhpcyBwZXJpb2QgdXNlIHRoYXRcbiAgICAgICAgICAgIGNvbnN0IG9mZnNldEV2ZW50ID0gdGhpcy5fdGlja09mZnNldC5nZXQoZS50aW1lKTtcbiAgICAgICAgICAgIGlmIChvZmZzZXRFdmVudCAmJiBvZmZzZXRFdmVudC50aW1lID49IGxhc3RTdGF0ZS50aW1lKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzID0gb2Zmc2V0RXZlbnQudGlja3M7XG4gICAgICAgICAgICAgICAgcGVyaW9kU3RhcnRUaW1lID0gb2Zmc2V0RXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGUuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFRpY2tzICs9IHRoaXMuZnJlcXVlbmN5LmdldFRpY2tzQXRUaW1lKGUudGltZSkgLSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShwZXJpb2RTdGFydFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlID0gZTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG4gICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgdGlja3NcbiAgICAgICAgcmV0dXJuIGVsYXBzZWRUaWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiB0aW1lcyB0aGUgY2FsbGJhY2sgd2FzIGludm9rZWQuIFN0YXJ0cyBjb3VudGluZyBhdCAwXG4gICAgICogYW5kIGluY3JlbWVudHMgYWZ0ZXIgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBSZXR1cm5zIC0xIHdoZW4gc3RvcHBlZC5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFRpY2tzQXRUaW1lKHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgdGlja3ModCkge1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHQsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaW5jZSB0aWNrcz0wIHRoYXQgdGhlIFRpY2tTb3VyY2UgaGFzIGJlZW4gcnVubmluZy4gQWNjb3VudHNcbiAgICAgKiBmb3IgdGVtcG8gY3VydmVzXG4gICAgICovXG4gICAgZ2V0IHNlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNlY29uZHNBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmZyZXF1ZW5jeS50aW1lVG9UaWNrcyhzLCBub3cpO1xuICAgICAgICB0aGlzLnNldFRpY2tzQXRUaW1lKHRpY2tzLCBub3cpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldExhc3RTdGF0ZShcInN0b3BwZWRcIiwgdGltZSk7XG4gICAgICAgIC8vIHRoaXMgZXZlbnQgYWxsb3dzIGZvckVhY2hCZXR3ZWVuIHRvIGl0ZXJhdGUgdW50aWwgdGhlIGN1cnJlbnQgdGltZVxuICAgICAgICBjb25zdCB0bXBFdmVudCA9IHsgc3RhdGU6IFwicGF1c2VkXCIsIHRpbWUgfTtcbiAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHRtcEV2ZW50KTtcbiAgICAgICAgLy8ga2VlcCB0cmFjayBvZiB0aGUgcHJldmlvdXMgb2Zmc2V0IGV2ZW50XG4gICAgICAgIGxldCBsYXN0U3RhdGUgPSBzdG9wRXZlbnQ7XG4gICAgICAgIGxldCBlbGFwc2VkU2Vjb25kcyA9IDA7XG4gICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgdGhlIGV2ZW50cyBzaW5jZSB0aGUgbGFzdCBzdG9wXG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0b3BFdmVudC50aW1lLCB0aW1lICsgdGhpcy5zYW1wbGVUaW1lLCBlID0+IHtcbiAgICAgICAgICAgIGxldCBwZXJpb2RTdGFydFRpbWUgPSBsYXN0U3RhdGUudGltZTtcbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIG9mZnNldCBldmVudCBpbiB0aGlzIHBlcmlvZCB1c2UgdGhhdFxuICAgICAgICAgICAgY29uc3Qgb2Zmc2V0RXZlbnQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChlLnRpbWUpO1xuICAgICAgICAgICAgaWYgKG9mZnNldEV2ZW50ICYmIG9mZnNldEV2ZW50LnRpbWUgPj0gbGFzdFN0YXRlLnRpbWUpIHtcbiAgICAgICAgICAgICAgICBlbGFwc2VkU2Vjb25kcyA9IG9mZnNldEV2ZW50LnNlY29uZHM7XG4gICAgICAgICAgICAgICAgcGVyaW9kU3RhcnRUaW1lID0gb2Zmc2V0RXZlbnQudGltZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsYXN0U3RhdGUuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIGUuc3RhdGUgIT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgZWxhcHNlZFNlY29uZHMgKz0gZS50aW1lIC0gcGVyaW9kU3RhcnRUaW1lO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGFzdFN0YXRlID0gZTtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGV2ZW50XG4gICAgICAgIHRoaXMuX3N0YXRlLnJlbW92ZSh0bXBFdmVudCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgdGlja3NcbiAgICAgICAgcmV0dXJuIGVsYXBzZWRTZWNvbmRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICovXG4gICAgc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90aWNrT2Zmc2V0LmNhbmNlbCh0aW1lKTtcbiAgICAgICAgdGhpcy5fdGlja09mZnNldC5hZGQoe1xuICAgICAgICAgICAgc2Vjb25kczogdGhpcy5mcmVxdWVuY3kuZ2V0RHVyYXRpb25PZlRpY2tzKHRpY2tzLCB0aW1lKSxcbiAgICAgICAgICAgIHRpY2tzLFxuICAgICAgICAgICAgdGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBzY2hlZHVsZWQgc3RhdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSB0byBxdWVyeS5cbiAgICAgKi9cbiAgICBnZXRTdGF0ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcbiAgICAgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuICAgICAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLlxuICAgICAqIEBwYXJhbSAgdGljayBUaGUgdGljayBudW1iZXIuXG4gICAgICogQHBhcmFtICBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGUgdGlja1xuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlID0gdGhpcy5ub3coKSkge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLl90aWNrT2Zmc2V0LmdldChiZWZvcmUpO1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3N0YXRlLmdldChiZWZvcmUpO1xuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBNYXRoLm1heChvZmZzZXQudGltZSwgZXZlbnQudGltZSk7XG4gICAgICAgIGNvbnN0IGFic29sdXRlVGlja3MgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShzdGFydFRpbWUpICsgdGljayAtIG9mZnNldC50aWNrcztcbiAgICAgICAgcmV0dXJuIHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soYWJzb2x1dGVUaWNrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2sgZXZlbnQgYXQgYWxsIHNjaGVkdWxlZCB0aWNrcyBiZXR3ZWVuIHRoZVxuICAgICAqIHN0YXJ0IHRpbWUgYW5kIHRoZSBlbmQgdGltZVxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lICBUaGUgYmVnaW5uaW5nIG9mIHRoZSBzZWFyY2ggcmFuZ2VcbiAgICAgKiBAcGFyYW0gIGVuZFRpbWUgICAgVGhlIGVuZCBvZiB0aGUgc2VhcmNoIHJhbmdlXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBlYWNoIHRpY2tcbiAgICAgKi9cbiAgICBmb3JFYWNoVGlja0JldHdlZW4oc3RhcnRUaW1lLCBlbmRUaW1lLCBjYWxsYmFjaykge1xuICAgICAgICAvLyBvbmx5IGl0ZXJhdGUgdGhyb3VnaCB0aGUgc2VjdGlvbnMgd2hlcmUgaXQgaXMgXCJzdGFydGVkXCJcbiAgICAgICAgbGV0IGxhc3RTdGF0ZUV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHN0YXJ0VGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZXZlbnQgPT4ge1xuICAgICAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50ICYmIGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJiBldmVudC5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZvckVhY2hUaWNrQmV0d2VlbihNYXRoLm1heChsYXN0U3RhdGVFdmVudC50aW1lLCBzdGFydFRpbWUpLCBldmVudC50aW1lIC0gdGhpcy5zYW1wbGVUaW1lLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsYXN0U3RhdGVFdmVudCA9IGV2ZW50O1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGVycm9yID0gbnVsbDtcbiAgICAgICAgaWYgKGxhc3RTdGF0ZUV2ZW50ICYmIGxhc3RTdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgY29uc3QgbWF4U3RhcnRUaW1lID0gTWF0aC5tYXgobGFzdFN0YXRlRXZlbnQudGltZSwgc3RhcnRUaW1lKTtcbiAgICAgICAgICAgIC8vIGZpZ3VyZSBvdXQgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZnJlcXVlbmN5IHRpY2tzIGFuZCB0aGVcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0VGlja3MgPSB0aGlzLmZyZXF1ZW5jeS5nZXRUaWNrc0F0VGltZShtYXhTdGFydFRpbWUpO1xuICAgICAgICAgICAgY29uc3QgdGlja3NBdFN0YXJ0ID0gdGhpcy5mcmVxdWVuY3kuZ2V0VGlja3NBdFRpbWUobGFzdFN0YXRlRXZlbnQudGltZSk7XG4gICAgICAgICAgICBjb25zdCBkaWZmID0gc3RhcnRUaWNrcyAtIHRpY2tzQXRTdGFydDtcbiAgICAgICAgICAgIGxldCBvZmZzZXQgPSBNYXRoLmNlaWwoZGlmZikgLSBkaWZmO1xuICAgICAgICAgICAgLy8gZ3VhcmQgYWdhaW5zdCBmbG9hdGluZyBwb2ludCBpc3N1ZXNcbiAgICAgICAgICAgIG9mZnNldCA9IEVRKG9mZnNldCwgMSkgPyAwIDogb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IG5leHRUaWNrVGltZSA9IHRoaXMuZnJlcXVlbmN5LmdldFRpbWVPZlRpY2soc3RhcnRUaWNrcyArIG9mZnNldCk7XG4gICAgICAgICAgICB3aGlsZSAobmV4dFRpY2tUaW1lIDwgZW5kVGltZSkge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG5leHRUaWNrVGltZSwgTWF0aC5yb3VuZCh0aGlzLmdldFRpY2tzQXRUaW1lKG5leHRUaWNrVGltZSkpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV4dFRpY2tUaW1lICs9IHRoaXMuZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcygxLCBuZXh0VGlja1RpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RpY2tPZmZzZXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRpY2tTb3VyY2UuanMubWFwIiwiaW1wb3J0IHsgVG9uZVdpdGhDb250ZXh0IH0gZnJvbSBcIi4uL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFN0YXRlVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBUaWNrU291cmNlIH0gZnJvbSBcIi4vVGlja1NvdXJjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0Q29udGV4dFJ1bm5pbmcgfSBmcm9tIFwiLi4vdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBBIHNhbXBsZSBhY2N1cmF0ZSBjbG9jayB3aGljaCBwcm92aWRlcyBhIGNhbGxiYWNrIGF0IHRoZSBnaXZlbiByYXRlLlxuICogV2hpbGUgdGhlIGNhbGxiYWNrIGlzIG5vdCBzYW1wbGUtYWNjdXJhdGUgKGl0IGlzIHN0aWxsIHN1c2NlcHRpYmxlIHRvXG4gKiBsb29zZSBKUyB0aW1pbmcpLCB0aGUgdGltZSBwYXNzZWQgaW4gYXMgdGhlIGFyZ3VtZW50IHRvIHRoZSBjYWxsYmFja1xuICogaXMgcHJlY2lzZS4gRm9yIG1vc3QgYXBwbGljYXRpb25zLCBpdCBpcyBiZXR0ZXIgdG8gdXNlIFRvbmUuVHJhbnNwb3J0XG4gKiBpbnN0ZWFkIG9mIHRoZSBDbG9jayBieSBpdHNlbGYgc2luY2UgeW91IGNhbiBzeW5jaHJvbml6ZSBtdWx0aXBsZSBjYWxsYmFja3MuXG4gKiBAZXhhbXBsZVxuICogLy8gdGhlIGNhbGxiYWNrIHdpbGwgYmUgaW52b2tlZCBhcHByb3hpbWF0ZWx5IG9uY2UgYSBzZWNvbmRcbiAqIC8vIGFuZCB3aWxsIHByaW50IHRoZSB0aW1lIGV4YWN0bHkgb25jZSBhIHNlY29uZCBhcGFydC5cbiAqIGNvbnN0IGNsb2NrID0gbmV3IFRvbmUuQ2xvY2sodGltZSA9PiB7XG4gKiBcdGNvbnNvbGUubG9nKHRpbWUpO1xuICogfSwgMSk7XG4gKiBjbG9jay5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIENsb2NrIGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2xvY2suZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNsb2NrXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlIGF0IHRoZSBzY2hlZHVsZWQgdGljay5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBub09wO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxhc3QgdGltZSB0aGUgbG9vcCBjYWxsYmFjayB3YXMgaW52b2tlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbGFzdFVwZGF0ZSA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBwbGF5YmFjayBzdGF0ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhdGUgPSBuZXcgU3RhdGVUaW1lbGluZShcInN0b3BwZWRcIik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb250ZXh0IGJvdW5kIHJlZmVyZW5jZSB0byB0aGUgX2xvb3AgbWV0aG9kXG4gICAgICAgICAqIFRoaXMgaXMgbmVjZXNzYXJ5IHRvIHJlbW92ZSB0aGUgZXZlbnQgaW4gdGhlIGVuZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kTG9vcCA9IHRoaXMuX2xvb3AuYmluZCh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENsb2NrLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZSA9IG5ldyBUaWNrU291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogb3B0aW9ucy51bml0cyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSAwO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX3RpY2tTb3VyY2UuZnJlcXVlbmN5O1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgLy8gYWRkIGFuIGluaXRpYWwgc3RhdGVcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIDApO1xuICAgICAgICAvLyBiaW5kIGEgY2FsbGJhY2sgdG8gdGhlIHdvcmtlciB0aHJlYWRcbiAgICAgICAgdGhpcy5jb250ZXh0Lm9uKFwidGlja1wiLCB0aGlzLl9ib3VuZExvb3ApO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSxcbiAgICAgICAgICAgIHVuaXRzOiBcImhlcnR6XCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIsIFwic3RvcHBlZFwiIG9yIFwicGF1c2VkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBjbG9jayBhdCB0aGUgZ2l2ZW4gdGltZS4gT3B0aW9uYWxseSBwYXNzIGluIGFuIG9mZnNldFxuICAgICAqIG9mIHdoZXJlIHRvIHN0YXJ0IHRoZSB0aWNrIGNvdW50ZXIgZnJvbS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgVGhlIHRpbWUgdGhlIGNsb2NrIHNob3VsZCBzdGFydFxuICAgICAqIEBwYXJhbSBvZmZzZXQgIFdoZXJlIHRoZSB0aWNrIGNvdW50ZXIgc3RhcnRzIGNvdW50aW5nIGZyb20uXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgY29udGV4dCBpcyBydW5uaW5nXG4gICAgICAgIGFzc2VydENvbnRleHRSdW5uaW5nKHRoaXMuY29udGV4dCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBsb29wXG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmxvZyhcInN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdGFydGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLnN0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChjb21wdXRlZFRpbWUgPCB0aGlzLl9sYXN0VXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lLCBvZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBjbG9jay4gU3RvcHBpbmcgdGhlIGNsb2NrIHJlc2V0cyB0aGUgdGljayBjb3VudGVyIHRvIDAuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgY2xvY2sgc2hvdWxkIHN0b3AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBjbG9jayA9IG5ldyBUb25lLkNsb2NrKHRpbWUgPT4ge1xuICAgICAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gICAgICogfSwgMSk7XG4gICAgICogY2xvY2suc3RhcnQoKTtcbiAgICAgKiAvLyBzdG9wIHRoZSBjbG9jayBhZnRlciAxMCBzZWNvbmRzXG4gICAgICogY2xvY2suc3RvcChcIisxMFwiKTtcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgY2xvY2suIFBhdXNpbmcgZG9lcyBub3QgcmVzZXQgdGhlIHRpY2sgY291bnRlci5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSBjbG9jayBzaG91bGQgc3RvcC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwicGF1c2VkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLnBhdXNlKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICBpZiAoY29tcHV0ZWRUaW1lIDwgdGhpcy5fbGFzdFVwZGF0ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdChcInBhdXNlXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgdGltZXMgdGhlIGNhbGxiYWNrIHdhcyBpbnZva2VkLiBTdGFydHMgY291bnRpbmcgYXQgMFxuICAgICAqIGFuZCBpbmNyZW1lbnRzIGFmdGVyIHRoZSBjYWxsYmFjayB3YXMgaW52b2tlZC5cbiAgICAgKi9cbiAgICBnZXQgdGlja3MoKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmNlaWwodGhpcy5nZXRUaWNrc0F0VGltZSh0aGlzLm5vdygpKSk7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UudGlja3MgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdGltZSBzaW5jZSB0aWNrcz0wIHRoYXQgdGhlIENsb2NrIGhhcyBiZWVuIHJ1bm5pbmcuIEFjY291bnRzIGZvciB0ZW1wbyBjdXJ2ZXNcbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2Uuc2Vjb25kcztcbiAgICB9XG4gICAgc2V0IHNlY29uZHMocykge1xuICAgICAgICB0aGlzLl90aWNrU291cmNlLnNlY29uZHMgPSBzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIGVsYXBzZWQgc2Vjb25kcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSBlbGFwc2VkIHNlY29uZHNcbiAgICAgKiBAcmV0dXJuICBUaGUgbnVtYmVyIG9mIGVsYXBzZWQgc2Vjb25kc1xuICAgICAqL1xuICAgIGdldFNlY29uZHNBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRTZWNvbmRzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGNsb2NrJ3MgdGlja3MgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aWNrcyBUaGUgdGljayB2YWx1ZSB0byBzZXRcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICovXG4gICAgc2V0VGlja3NBdFRpbWUodGlja3MsIHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdGlja1NvdXJjZS5zZXRUaWNrc0F0VGltZSh0aWNrcywgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIGdpdmVuIHRpY2suIFRoZSBzZWNvbmQgYXJndW1lbnRcbiAgICAgKiBpcyB3aGVuIHRvIHRlc3QgYmVmb3JlLiBTaW5jZSB0aWNrcyBjYW4gYmUgc2V0ICh3aXRoIHNldFRpY2tzQXRUaW1lKVxuICAgICAqIHRoZXJlIG1heSBiZSBtdWx0aXBsZSB0aW1lcyBmb3IgYSBnaXZlbiB0aWNrIHZhbHVlLlxuICAgICAqIEBwYXJhbSAgdGljayBUaGUgdGljayBudW1iZXIuXG4gICAgICogQHBhcmFtICBiZWZvcmUgV2hlbiB0byBtZWFzdXJlIHRoZSB0aWNrIHZhbHVlIGZyb20uXG4gICAgICogQHJldHVybiBUaGUgdGltZSBvZiB0aGUgdGlja1xuICAgICAqL1xuICAgIGdldFRpbWVPZlRpY2sodGljaywgYmVmb3JlID0gdGhpcy5ub3coKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdGlja1NvdXJjZS5nZXRUaW1lT2ZUaWNrKHRpY2ssIGJlZm9yZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgdGljayB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90aWNrU291cmNlLmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHRpbWUgb2YgdGhlIG5leHQgdGlja1xuICAgICAqIEBwYXJhbSAgb2Zmc2V0IFRoZSB0aWNrIG51bWJlci5cbiAgICAgKi9cbiAgICBuZXh0VGlja1RpbWUob2Zmc2V0LCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBjb25zdCBjdXJyZW50VGljayA9IHRoaXMuZ2V0VGlja3NBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpY2tTb3VyY2UuZ2V0VGltZU9mVGljayhjdXJyZW50VGljayArIG9mZnNldCwgY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNjaGVkdWxpbmcgbG9vcC5cbiAgICAgKi9cbiAgICBfbG9vcCgpIHtcbiAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gdGhpcy5fbGFzdFVwZGF0ZTtcbiAgICAgICAgY29uc3QgZW5kVGltZSA9IHRoaXMubm93KCk7XG4gICAgICAgIHRoaXMuX2xhc3RVcGRhdGUgPSBlbmRUaW1lO1xuICAgICAgICB0aGlzLmxvZyhcImxvb3BcIiwgc3RhcnRUaW1lLCBlbmRUaW1lKTtcbiAgICAgICAgaWYgKHN0YXJ0VGltZSAhPT0gZW5kVGltZSkge1xuICAgICAgICAgICAgLy8gdGhlIHN0YXRlIGNoYW5nZSBldmVudHNcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hCZXR3ZWVuKHN0YXJ0VGltZSwgZW5kVGltZSwgZSA9PiB7XG4gICAgICAgICAgICAgICAgc3dpdGNoIChlLnN0YXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgXCJzdGFydGVkXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLl90aWNrU291cmNlLmdldFRpY2tzQXRUaW1lKGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdGFydFwiLCBlLnRpbWUsIG9mZnNldCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInN0b3BwZWRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlLnRpbWUgIT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJzdG9wXCIsIGUudGltZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBcInBhdXNlZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwicGF1c2VcIiwgZS50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gdGhlIHRpY2sgY2FsbGJhY2tzXG4gICAgICAgICAgICB0aGlzLl90aWNrU291cmNlLmZvckVhY2hUaWNrQmV0d2VlbihzdGFydFRpbWUsIGVuZFRpbWUsICh0aW1lLCB0aWNrcykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSwgdGlja3MpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgc2NoZWR1bGVkIHN0YXRlIGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIHRpbWUgdG8gcXVlcnkuXG4gICAgICogQHJldHVybiAgVGhlIG5hbWUgb2YgdGhlIHN0YXRlIGlucHV0IGluIHNldFN0YXRlQXRUaW1lLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygpO1xuICAgICAqIGNsb2NrLnN0YXJ0KFwiKzAuMVwiKTtcbiAgICAgKiBjbG9jay5nZXRTdGF0ZUF0VGltZShcIiswLjFcIik7IC8vIHJldHVybnMgXCJzdGFydGVkXCJcbiAgICAgKi9cbiAgICBnZXRTdGF0ZUF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC5vZmYoXCJ0aWNrXCIsIHRoaXMuX2JvdW5kTG9vcCk7XG4gICAgICAgIHRoaXMuX3RpY2tTb3VyY2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbkVtaXR0ZXIubWl4aW4oQ2xvY2spO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q2xvY2suanMubWFwIiwiaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIFdlYiBBdWRpbydzIG5hdGl2ZSBbRGVsYXlOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1kZWxheW5vZGUtaW50ZXJmYWNlKS5cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGRlbGF5ID0gbmV3IFRvbmUuRGVsYXkoMC4xKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIGNvbm5lY3QgdGhlIHNpZ25hbCB0byBib3RoIHRoZSBkZWxheSBhbmQgdGhlIGRlc3RpbmF0aW9uXG4gKiBcdGNvbnN0IHB1bHNlID0gbmV3IFRvbmUuUHVsc2VPc2NpbGxhdG9yKCkuY29ubmVjdChkZWxheSkudG9EZXN0aW5hdGlvbigpO1xuICogXHQvLyBzdGFydCBhbmQgc3RvcCB0aGUgcHVsc2VcbiAqIFx0cHVsc2Uuc3RhcnQoMCkuc3RvcCgwLjAxKTtcbiAqIH0sIDAuNSwgMSk7XG4gKi9cbmV4cG9ydCBjbGFzcyBEZWxheSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcIm1heERlbGF5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGVsYXlcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKERlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwibWF4RGVsYXlcIl0pO1xuICAgICAgICBjb25zdCBtYXhEZWxheUluU2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKG9wdGlvbnMubWF4RGVsYXkpO1xuICAgICAgICB0aGlzLl9tYXhEZWxheSA9IE1hdGgubWF4KG1heERlbGF5SW5TZWNvbmRzLCB0aGlzLnRvU2Vjb25kcyhvcHRpb25zLmRlbGF5VGltZSkpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLmNvbnRleHQuY3JlYXRlRGVsYXkobWF4RGVsYXlJblNlY29uZHMpO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZGVsYXlOb2RlLmRlbGF5VGltZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIG1pblZhbHVlOiAwLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMCxcbiAgICAgICAgICAgIG1heERlbGF5OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gZGVsYXkgdGltZS4gVGhpcyBjYW5ub3QgYmUgY2hhbmdlZCBhZnRlclxuICAgICAqIHRoZSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IuXG4gICAgICovXG4gICAgZ2V0IG1heERlbGF5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWF4RGVsYXk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGdldENvbnRleHQsIHNldENvbnRleHQgfSBmcm9tIFwiLi4vR2xvYmFsXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuL09mZmxpbmVDb250ZXh0XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi9Ub25lQXVkaW9CdWZmZXJcIjtcbi8qKlxuICogR2VuZXJhdGUgYSBidWZmZXIgYnkgcmVuZGVyaW5nIGFsbCBvZiB0aGUgVG9uZS5qcyBjb2RlIHdpdGhpbiB0aGUgY2FsbGJhY2sgdXNpbmcgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHQuXG4gKiBUaGUgT2ZmbGluZUF1ZGlvQ29udGV4dCBpcyBjYXBhYmxlIG9mIHJlbmRlcmluZyBtdWNoIGZhc3RlciB0aGFuIHJlYWwgdGltZSBpbiBtYW55IGNhc2VzLlxuICogVGhlIGNhbGxiYWNrIGZ1bmN0aW9uIGFsc28gcGFzc2VzIGluIGFuIG9mZmxpbmUgaW5zdGFuY2Ugb2YgW1tDb250ZXh0XV0gd2hpY2ggY2FuIGJlIHVzZWRcbiAqIHRvIHNjaGVkdWxlIGV2ZW50cyBhbG9uZyB0aGUgVHJhbnNwb3J0LlxuICogQHBhcmFtICBjYWxsYmFjayAgQWxsIFRvbmUuanMgbm9kZXMgd2hpY2ggYXJlIGNyZWF0ZWQgYW5kIHNjaGVkdWxlZCB3aXRoaW4gdGhpcyBjYWxsYmFjayBhcmUgcmVjb3JkZWQgaW50byB0aGUgb3V0cHV0IEJ1ZmZlci5cbiAqIEBwYXJhbSAgZHVyYXRpb24gICAgIHRoZSBhbW91bnQgb2YgdGltZSB0byByZWNvcmQgZm9yLlxuICogQHJldHVybiAgVGhlIHByb21pc2Ugd2hpY2ggaXMgaW52b2tlZCB3aXRoIHRoZSBUb25lQXVkaW9CdWZmZXIgb2YgdGhlIHJlY29yZGVkIG91dHB1dC5cbiAqIEBleGFtcGxlXG4gKiAvLyByZW5kZXIgMiBzZWNvbmRzIG9mIHRoZSBvc2NpbGxhdG9yXG4gKiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHQvLyBvbmx5IG5vZGVzIGNyZWF0ZWQgaW4gdGhpcyBjYWxsYmFjayB3aWxsIGJlIHJlY29yZGVkXG4gKiBcdGNvbnN0IG9zY2lsbGF0b3IgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KDApO1xuICogfSwgMikudGhlbigoYnVmZmVyKSA9PiB7XG4gKiBcdC8vIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlcik7XG4gKiB9KTtcbiAqIEBleGFtcGxlXG4gKiAvLyBjYW4gYWxzbyBzY2hlZHVsZSBldmVudHMgYWxvbmcgdGhlIFRyYW5zcG9ydFxuICogLy8gdXNpbmcgdGhlIHBhc3NlZCBpbiBPZmZsaW5lIFRyYW5zcG9ydFxuICogVG9uZS5PZmZsaW5lKCh7IHRyYW5zcG9ydCB9KSA9PiB7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdHRyYW5zcG9ydC5zY2hlZHVsZSh0aW1lID0+IHtcbiAqIFx0XHRvc2Muc3RhcnQodGltZSkuc3RvcCh0aW1lICsgMC4xKTtcbiAqIFx0fSwgMSk7XG4gKiBcdC8vIG1ha2Ugc3VyZSB0byBzdGFydCB0aGUgdHJhbnNwb3J0XG4gKiBcdHRyYW5zcG9ydC5zdGFydCgwLjIpO1xuICogfSwgNCkudGhlbigoYnVmZmVyKSA9PiB7XG4gKiBcdC8vIGRvIHNvbWV0aGluZyB3aXRoIHRoZSBvdXRwdXQgYnVmZmVyXG4gKiBcdGNvbnNvbGUubG9nKGJ1ZmZlcik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBPZmZsaW5lKGNhbGxiYWNrLCBkdXJhdGlvbiwgY2hhbm5lbHMgPSAyLCBzYW1wbGVSYXRlID0gZ2V0Q29udGV4dCgpLnNhbXBsZVJhdGUpIHtcbiAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAvLyBzZXQgdGhlIE9mZmxpbmVBdWRpb0NvbnRleHQgYmFzZWQgb24gdGhlIGN1cnJlbnQgY29udGV4dFxuICAgICAgICBjb25zdCBvcmlnaW5hbENvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoY2hhbm5lbHMsIGR1cmF0aW9uLCBzYW1wbGVSYXRlKTtcbiAgICAgICAgc2V0Q29udGV4dChjb250ZXh0KTtcbiAgICAgICAgLy8gaW52b2tlIHRoZSBjYWxsYmFjay9zY2hlZHVsaW5nXG4gICAgICAgIHlpZWxkIGNhbGxiYWNrKGNvbnRleHQpO1xuICAgICAgICAvLyB0aGVuIHJlbmRlciB0aGUgYXVkaW9cbiAgICAgICAgY29uc3QgYnVmZmVyUHJvbWlzZSA9IGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgIC8vIHJldHVybiB0aGUgb3JpZ2luYWwgQXVkaW9Db250ZXh0XG4gICAgICAgIHNldENvbnRleHQob3JpZ2luYWxDb250ZXh0KTtcbiAgICAgICAgLy8gYXdhaXQgdGhlIHJlbmRlcmluZ1xuICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBidWZmZXJQcm9taXNlO1xuICAgICAgICAvLyByZXR1cm4gdGhlIGF1ZGlvXG4gICAgICAgIHJldHVybiBuZXcgVG9uZUF1ZGlvQnVmZmVyKGJ1ZmZlcik7XG4gICAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PZmZsaW5lLmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL3V0aWwvRGVidWdcIjtcbi8qKlxuICogQSBkYXRhIHN0cnVjdHVyZSBmb3IgaG9sZGluZyBtdWx0aXBsZSBidWZmZXJzIGluIGEgTWFwLWxpa2UgZGF0YXN0cnVjdHVyZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGlhbm9TYW1wbGVzID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVycyh7XG4gKiBcdEExOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9BMS5tcDNcIixcbiAqIFx0QTI6IFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2Nhc2lvL0EyLm1wM1wiLFxuICogfSwgKCkgPT4ge1xuICogXHRjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIHBsYXkgb25lIG9mIHRoZSBzYW1wbGVzIHdoZW4gdGhleSBhbGwgbG9hZFxuICogXHRwbGF5ZXIuYnVmZmVyID0gcGlhbm9TYW1wbGVzLmdldChcIkEyXCIpO1xuICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAqIH0pO1xuICogQGV4YW1wbGVcbiAqIC8vIFRvIHBhc3MgaW4gYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGluIHRoZSBzZWNvbmQgcGFyYW1ldGVyXG4gKiBjb25zdCBidWZmZXJzID0gbmV3IFRvbmUuVG9uZUF1ZGlvQnVmZmVycyh7XG4gKiBcdCB1cmxzOiB7XG4gKiBcdFx0IEExOiBcIkExLm1wM1wiLFxuICogXHRcdCBBMjogXCJBMi5tcDNcIixcbiAqIFx0IH0sXG4gKiBcdCBvbmxvYWQ6ICgpID0+IGNvbnNvbGUubG9nKFwibG9hZGVkXCIpLFxuICogXHQgYmFzZVVybDogXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vY2FzaW8vXCJcbiAqIH0pO1xuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb0J1ZmZlcnMgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lQXVkaW9CdWZmZXJzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGJ1ZmZlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgbG9hZGVkIGJ1ZmZlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudCA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQXVkaW9CdWZmZXJzLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgdGhpcy5iYXNlVXJsID0gb3B0aW9ucy5iYXNlVXJsO1xuICAgICAgICAvLyBhZGQgZWFjaCBvbmVcbiAgICAgICAgT2JqZWN0LmtleXMob3B0aW9ucy51cmxzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgICAgICAgdGhpcy5fbG9hZGluZ0NvdW50Kys7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBvcHRpb25zLnVybHNbbmFtZV07XG4gICAgICAgICAgICB0aGlzLmFkZChuYW1lLCB1cmwsIHRoaXMuX2J1ZmZlckxvYWRlZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSwgb3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRydWUgaWYgdGhlIGJ1ZmZlcnMgb2JqZWN0IGhhcyBhIGJ1ZmZlciBieSB0aGF0IG5hbWUuXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUga2V5IG9yIGluZGV4IG9mIHRoZSBidWZmZXIuXG4gICAgICovXG4gICAgaGFzKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuaGFzKG5hbWUudG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBhIGJ1ZmZlciBieSBuYW1lLiBJZiBhbiBhcnJheSB3YXMgbG9hZGVkLFxuICAgICAqIHRoZW4gdXNlIHRoZSBhcnJheSBpbmRleC5cbiAgICAgKiBAcGFyYW0gIG5hbWUgIFRoZSBrZXkgb3IgaW5kZXggb2YgdGhlIGJ1ZmZlci5cbiAgICAgKi9cbiAgICBnZXQobmFtZSkge1xuICAgICAgICBhc3NlcnQodGhpcy5oYXMobmFtZSksIGBUb25lQXVkaW9CdWZmZXJzIGhhcyBubyBidWZmZXIgbmFtZWQ6ICR7bmFtZX1gKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnMuZ2V0KG5hbWUudG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEEgYnVmZmVyIHdhcyBsb2FkZWQuIGRlY3JlbWVudCB0aGUgY291bnRlci5cbiAgICAgKi9cbiAgICBfYnVmZmVyTG9hZGVkKGNhbGxiYWNrKSB7XG4gICAgICAgIHRoaXMuX2xvYWRpbmdDb3VudC0tO1xuICAgICAgICBpZiAodGhpcy5fbG9hZGluZ0NvdW50ID09PSAwICYmIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXJzIGFyZSBsb2FkZWQgb3Igbm90XG4gICAgICovXG4gICAgZ2V0IGxvYWRlZCgpIHtcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5fYnVmZmVycykuZXZlcnkoKFtfLCBidWZmZXJdKSA9PiBidWZmZXIubG9hZGVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgYnVmZmVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgQnVmZmVyc1xuICAgICAqIEBwYXJhbSAgbmFtZSAgICAgIEEgdW5pcXVlIG5hbWUgdG8gZ2l2ZSB0aGUgYnVmZmVyXG4gICAgICogQHBhcmFtICB1cmwgIEVpdGhlciB0aGUgdXJsIG9mIHRoZSBidWZlciwgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2hlbiB0aGUgdXJsIGlzIGxvYWRlZC5cbiAgICAgKiBAcGFyYW0gIG9uZXJyb3IgIEludm9rZWQgaWYgdGhlIGJ1ZmZlciBjYW4ndCBiZSBsb2FkZWRcbiAgICAgKi9cbiAgICBhZGQobmFtZSwgdXJsLCBjYWxsYmFjayA9IG5vT3AsIG9uZXJyb3IgPSBub09wKSB7XG4gICAgICAgIGlmIChpc1N0cmluZyh1cmwpKSB7XG4gICAgICAgICAgICB0aGlzLl9idWZmZXJzLnNldChuYW1lLnRvU3RyaW5nKCksIG5ldyBUb25lQXVkaW9CdWZmZXIodGhpcy5iYXNlVXJsICsgdXJsLCBjYWxsYmFjaywgb25lcnJvcikpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVycy5zZXQobmFtZS50b1N0cmluZygpLCBuZXcgVG9uZUF1ZGlvQnVmZmVyKHVybCwgY2FsbGJhY2ssIG9uZXJyb3IpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmZvckVhY2goYnVmZmVyID0+IGJ1ZmZlci5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9idWZmZXJzLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVBdWRpb0J1ZmZlcnMuanMubWFwIiwiaW1wb3J0IHsgZ2V0Q29udGV4dCB9IGZyb20gXCIuLi9HbG9iYWxcIjtcbmltcG9ydCB7IGZ0b20sIG10b2YgfSBmcm9tIFwiLi9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgRnJlcXVlbmN5Q2xhc3MgfSBmcm9tIFwiLi9GcmVxdWVuY3lcIjtcbi8qKlxuICogTWlkaSBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIE1pZGkgY2FuIGJlIGNvbnN0cnVjdGVkIHdpdGggb3Igd2l0aG91dCB0aGUgYG5ld2Aga2V5d29yZC4gTWlkaSBjYW4gYmUgcGFzc2VkXG4gKiBpbnRvIHRoZSBwYXJhbWV0ZXIgb2YgYW55IG1ldGhvZCB3aGljaCB0YWtlcyB0aW1lIGFzIGFuIGFyZ3VtZW50LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZGlDbGFzcyBleHRlbmRzIEZyZXF1ZW5jeUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRpQ2xhc3NcIjtcbiAgICAgICAgdGhpcy5kZWZhdWx0VW5pdHMgPSBcIm1pZGlcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBmcmVxdWVuY3kgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfZnJlcXVlbmN5VG9Vbml0cyhmcmVxKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9mcmVxdWVuY3lUb1VuaXRzKGZyZXEpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSB0aWNrIGluIHRoZSBjdXJyZW50IHRpbWUgdW5pdHNcbiAgICAgKi9cbiAgICBfdGlja3NUb1VuaXRzKHRpY2tzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl90aWNrc1RvVW5pdHModGlja3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiBmdG9tKHN1cGVyLl9iZWF0c1RvVW5pdHMoYmVhdHMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgdmFsdWUgb2YgYSBzZWNvbmQgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykge1xuICAgICAgICByZXR1cm4gZnRvbShzdXBlci5fc2Vjb25kc1RvVW5pdHMoc2Vjb25kcykpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBmcmVxdWVuY3kgYXMgYSBNSURJIG5vdGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaSg2MCkudG9NaWRpKCk7IC8vIDYwXG4gICAgICovXG4gICAgdG9NaWRpKCkge1xuICAgICAgICByZXR1cm4gdGhpcy52YWx1ZU9mKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIGZyZXF1ZW5jeSBhcyBhIE1JREkgbm90ZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogVG9uZS5NaWRpKDYwKS50b0ZyZXF1ZW5jeSgpOyAvLyAyNjEuNjI1NTY1MzAwNTk4NlxuICAgICAqL1xuICAgIHRvRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gbXRvZih0aGlzLnRvTWlkaSgpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJhbnNwb3NlcyB0aGUgZnJlcXVlbmN5IGJ5IHRoZSBnaXZlbiBudW1iZXIgb2Ygc2VtaXRvbmVzLlxuICAgICAqIEByZXR1cm4gQSBuZXcgdHJhbnNwb3NlZCBNaWRpQ2xhc3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuTWlkaShcIkE0XCIpLnRyYW5zcG9zZSgzKTsgLy8gXCJDNVwiXG4gICAgICovXG4gICAgdHJhbnNwb3NlKGludGVydmFsKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgdGhpcy50b01pZGkoKSArIGludGVydmFsKTtcbiAgICB9XG59XG4vKipcbiAqIENvbnZlcnQgYSB2YWx1ZSBpbnRvIGEgRnJlcXVlbmN5Q2xhc3Mgb2JqZWN0LlxuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIE1pZGkodmFsdWUsIHVuaXRzKSB7XG4gICAgcmV0dXJuIG5ldyBNaWRpQ2xhc3MoZ2V0Q29udGV4dCgpLCB2YWx1ZSwgdW5pdHMpO1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkaS5qcy5tYXAiLCJpbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4uL0dsb2JhbFwiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4vVHJhbnNwb3J0VGltZVwiO1xuLyoqXG4gKiBUaWNrcyBpcyBhIHByaW1pdGl2ZSB0eXBlIGZvciBlbmNvZGluZyBUaW1lIHZhbHVlcy5cbiAqIFRpY2tzIGNhbiBiZSBjb25zdHJ1Y3RlZCB3aXRoIG9yIHdpdGhvdXQgdGhlIGBuZXdgIGtleXdvcmQuIFRpY2tzIGNhbiBiZSBwYXNzZWRcbiAqIGludG8gdGhlIHBhcmFtZXRlciBvZiBhbnkgbWV0aG9kIHdoaWNoIHRha2VzIHRpbWUgYXMgYW4gYXJndW1lbnQuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdCA9IFRvbmUuVGlja3MoXCI0blwiKTsgLy8gYSBxdWFydGVyIG5vdGUgYXMgdGlja3NcbiAqIEBjYXRlZ29yeSBVbml0XG4gKi9cbmV4cG9ydCBjbGFzcyBUaWNrc0NsYXNzIGV4dGVuZHMgVHJhbnNwb3J0VGltZUNsYXNzIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaWNrc1wiO1xuICAgICAgICB0aGlzLmRlZmF1bHRVbml0cyA9IFwiaVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdGltZSBpbiB0aGUgZ2l2ZW4gdW5pdHNcbiAgICAgKi9cbiAgICBfbm93KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC50aWNrcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB2YWx1ZSBvZiB0aGUgYmVhdHMgaW4gdGhlIGN1cnJlbnQgdW5pdHNcbiAgICAgKi9cbiAgICBfYmVhdHNUb1VuaXRzKGJlYXRzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRQUFEoKSAqIGJlYXRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNlY29uZCBpbiB0aGUgY3VycmVudCB1bml0c1xuICAgICAqL1xuICAgIF9zZWNvbmRzVG9Vbml0cyhzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBNYXRoLmZsb29yKHNlY29uZHMgLyAoNjAgLyB0aGlzLl9nZXRCcG0oKSkgKiB0aGlzLl9nZXRQUFEoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHZhbHVlIG9mIGEgdGljayBpbiB0aGUgY3VycmVudCB0aW1lIHVuaXRzXG4gICAgICovXG4gICAgX3RpY2tzVG9Vbml0cyh0aWNrcykge1xuICAgICAgICByZXR1cm4gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybiB0aGUgdGltZSBpbiB0aWNrc1xuICAgICAqL1xuICAgIHRvVGlja3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnZhbHVlT2YoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB0aW1lIGluIHNlY29uZHNcbiAgICAgKi9cbiAgICB0b1NlY29uZHMoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy52YWx1ZU9mKCkgLyB0aGlzLl9nZXRQUFEoKSkgKiAoNjAgLyB0aGlzLl9nZXRCcG0oKSk7XG4gICAgfVxufVxuLyoqXG4gKiBDb252ZXJ0IGEgdGltZSByZXByZXNlbnRhdGlvbiB0byB0aWNrc1xuICogQGNhdGVnb3J5IFVuaXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFRpY2tzKHZhbHVlLCB1bml0cykge1xuICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyhnZXRDb250ZXh0KCksIHZhbHVlLCB1bml0cyk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UaWNrcy5qcy5tYXAiLCJpbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29udGV4dC9Ub25lV2l0aENvbnRleHRcIjtcbmltcG9ydCB7IFRpbWVsaW5lIH0gZnJvbSBcIi4vVGltZWxpbmVcIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4uL2NvbnRleHQvQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG4vKipcbiAqIERyYXcgaXMgdXNlZnVsIGZvciBzeW5jaHJvbml6aW5nIHZpc3VhbHMgYW5kIGF1ZGlvIGV2ZW50cy5cbiAqIENhbGxiYWNrcyBmcm9tIFRvbmUuVHJhbnNwb3J0IG9yIGFueSBvZiB0aGUgVG9uZS5FdmVudCBjbGFzc2VzXG4gKiBhbHdheXMgaGFwcGVuIF9iZWZvcmVfIHRoZSBzY2hlZHVsZWQgdGltZSBhbmQgYXJlIG5vdCBzeW5jaHJvbml6ZWRcbiAqIHRvIHRoZSBhbmltYXRpb24gZnJhbWUgc28gdGhleSBhcmUgbm90IGdvb2QgZm9yIHRyaWdnZXJpbmcgdGlnaHRseVxuICogc3luY2hyb25pemVkIHZpc3VhbHMgYW5kIHNvdW5kLiBEcmF3IG1ha2VzIGl0IGVhc3kgdG8gc2NoZWR1bGVcbiAqIGNhbGxiYWNrcyB1c2luZyB0aGUgQXVkaW9Db250ZXh0IHRpbWUgYW5kIHVzZXMgcmVxdWVzdEFuaW1hdGlvbkZyYW1lLlxuICogQGV4YW1wbGVcbiAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKCh0aW1lKSA9PiB7XG4gKiBcdC8vIHVzZSB0aGUgdGltZSBhcmd1bWVudCB0byBzY2hlZHVsZSBhIGNhbGxiYWNrIHdpdGggRHJhd1xuICogXHRUb25lLkRyYXcuc2NoZWR1bGUoKCkgPT4ge1xuICogXHRcdC8vIGRvIGRyYXdpbmcgb3IgRE9NIG1hbmlwdWxhdGlvbiBoZXJlXG4gKiBcdFx0Y29uc29sZS5sb2codGltZSk7XG4gKiBcdH0sIHRpbWUpO1xuICogfSwgXCIrMC41XCIpO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBEcmF3IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEcmF3XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZHVyYXRpb24gYWZ0ZXIgd2hpY2ggZXZlbnRzIGFyZSBub3QgaW52b2tlZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZXhwaXJhdGlvbiA9IDAuMjU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSBzY2hlZHVsZWQgdGltZVxuICAgICAgICAgKiB0aGF0IHRoZSBjYWxsYmFjayBjYW4gYmUgaW52b2tlZC4gRGVmYXVsdCBpc1xuICAgICAgICAgKiBoYWxmIHRoZSB0aW1lIG9mIGFuIGFuaW1hdGlvbiBmcmFtZSAoMC4wMDggc2Vjb25kcykuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFudGljaXBhdGlvbiA9IDAuMDA4O1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBldmVudHMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBkcmF3IGxvb3BcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kRHJhd0xvb3AgPSB0aGlzLl9kcmF3TG9vcC5iaW5kKHRoaXMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFuaW1hdGlvbiBmcmFtZSBpZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSAtMTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgYSBmdW5jdGlvbiBhdCB0aGUgZ2l2ZW4gdGltZSB0byBiZSBpbnZva2VkXG4gICAgICogb24gdGhlIG5lYXJlc3QgYW5pbWF0aW9uIGZyYW1lLlxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgIENhbGxiYWNrIGlzIGludm9rZWQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgICAgVGhlIHRpbWUgcmVsYXRpdmUgdG8gdGhlIEF1ZGlvQ29udGV4dCB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2suXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aW1lID0+IHtcbiAgICAgKiBcdFRvbmUuRHJhdy5zY2hlZHVsZSgoKSA9PiBjb25zb2xlLmxvZyh0aW1lKSwgdGltZSk7XG4gICAgICogfSwgMSk7XG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudHMuYWRkKHtcbiAgICAgICAgICAgIGNhbGxiYWNrLFxuICAgICAgICAgICAgdGltZTogdGhpcy50b1NlY29uZHModGltZSksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB0aGUgZHJhdyBsb29wIG9uIHRoZSBmaXJzdCBldmVudFxuICAgICAgICBpZiAodGhpcy5fZXZlbnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgdGhpcy5fYW5pbWF0aW9uRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodGhpcy5fYm91bmREcmF3TG9vcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBldmVudHMgc2NoZWR1bGVkIGFmdGVyIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICBhZnRlciAgVGltZSBhZnRlciB3aGljaCBzY2hlZHVsZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBzY2hlZHVsaW5nIHRpbWVsaW5lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9ldmVudHMuY2FuY2VsKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHJhdyBsb29wXG4gICAgICovXG4gICAgX2RyYXdMb29wKCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aGlzLmNvbnRleHQuY3VycmVudFRpbWU7XG4gICAgICAgIHdoaWxlICh0aGlzLl9ldmVudHMubGVuZ3RoICYmIHRoaXMuX2V2ZW50cy5wZWVrKCkudGltZSAtIHRoaXMuYW50aWNpcGF0aW9uIDw9IG5vdykge1xuICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9ldmVudHMuc2hpZnQoKTtcbiAgICAgICAgICAgIGlmIChldmVudCAmJiBub3cgLSBldmVudC50aW1lIDw9IHRoaXMuZXhwaXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGV2ZW50LmNhbGxiYWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2V2ZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmltYXRpb25GcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLl9ib3VuZERyYXdMb29wKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuX2FuaW1hdGlvbkZyYW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBcdElOSVRJQUxJWkFUSU9OXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbm9uQ29udGV4dEluaXQoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5kcmF3ID0gbmV3IERyYXcoeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRyYXcuZGlzcG9zZSgpO1xufSk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EcmF3LmpzLm1hcCIsImltcG9ydCB7IFRvbmUgfSBmcm9tIFwiLi4vVG9uZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4vVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi9EZWJ1Z1wiO1xuLyoqXG4gKiBTaW1pbGFyIHRvIFRvbmUuVGltZWxpbmUsIGJ1dCBhbGwgZXZlbnRzIHJlcHJlc2VudFxuICogaW50ZXJ2YWxzIHdpdGggYm90aCBcInRpbWVcIiBhbmQgXCJkdXJhdGlvblwiIHRpbWVzLiBUaGVcbiAqIGV2ZW50cyBhcmUgcGxhY2VkIGluIGEgdHJlZSBzdHJ1Y3R1cmUgb3B0aW1pemVkXG4gKiBmb3IgcXVlcnlpbmcgYW4gaW50ZXJzZWN0aW9uIHBvaW50IHdpdGggdGhlIHRpbWVsaW5lXG4gKiBldmVudHMuIEludGVybmFsbHkgdXNlcyBhbiBbSW50ZXJ2YWwgVHJlZV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSW50ZXJ2YWxfdHJlZSlcbiAqIHRvIHJlcHJlc2VudCB0aGUgZGF0YS5cbiAqL1xuZXhwb3J0IGNsYXNzIEludGVydmFsVGltZWxpbmUgZXh0ZW5kcyBUb25lIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJJbnRlcnZhbFRpbWVsaW5lXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgcm9vdCBub2RlIG9mIHRoZSBpbnRldmFsIHRyZWVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgICogS2VlcCB0cmFjayBvZiB0aGUgbGVuZ3RoIG9mIHRoZSB0aW1lbGluZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xlbmd0aCA9IDA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCB0byBhZGQgdG8gdGhlIHRpbWVsaW5lLiBBbGwgZXZlbnRzIG11c3RcbiAgICAgKiBoYXZlIGEgdGltZSBhbmQgZHVyYXRpb24gdmFsdWVcbiAgICAgKiBAcGFyYW0gIGV2ZW50ICBUaGUgZXZlbnQgdG8gYWRkIHRvIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIGFkZChldmVudCkge1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKGV2ZW50LnRpbWUpLCBcIkV2ZW50cyBtdXN0IGhhdmUgYSB0aW1lIHByb3BlcnR5XCIpO1xuICAgICAgICBhc3NlcnQoaXNEZWZpbmVkKGV2ZW50LmR1cmF0aW9uKSwgXCJFdmVudHMgbXVzdCBoYXZlIGEgZHVyYXRpb24gcGFyYW1ldGVyXCIpO1xuICAgICAgICBldmVudC50aW1lID0gZXZlbnQudGltZS52YWx1ZU9mKCk7XG4gICAgICAgIGxldCBub2RlID0gbmV3IEludGVydmFsTm9kZShldmVudC50aW1lLCBldmVudC50aW1lICsgZXZlbnQuZHVyYXRpb24sIGV2ZW50KTtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5pbnNlcnQobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbGVuZ3RoKys7XG4gICAgICAgIC8vIFJlc3RydWN0dXJlIHRyZWUgdG8gYmUgYmFsYW5jZWRcbiAgICAgICAgd2hpbGUgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUudXBkYXRlSGVpZ2h0KCk7XG4gICAgICAgICAgICBub2RlLnVwZGF0ZU1heCgpO1xuICAgICAgICAgICAgdGhpcy5fcmViYWxhbmNlKG5vZGUpO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYW4gZXZlbnQgZnJvbSB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIHJlbW92ZSBmcm9tIHRoZSB0aW1lbGluZVxuICAgICAqL1xuICAgIHJlbW92ZShldmVudCkge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2goZXZlbnQudGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgcmVzdWx0cykge1xuICAgICAgICAgICAgICAgIGlmIChub2RlLmV2ZW50ID09PSBldmVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZW1vdmVOb2RlKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9sZW5ndGgtLTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcmVhZE9ubHlcbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgZXZlbnRzIHdob3NlIHRpbWUgdGltZSBpcyBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSAgYWZ0ZXIgIFRoZSB0aW1lIHRvIHF1ZXJ5LlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLmZvckVhY2hGcm9tKGFmdGVyLCBldmVudCA9PiB0aGlzLnJlbW92ZShldmVudCkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSByb290IG5vZGUgYXMgdGhlIGdpdmVuIG5vZGVcbiAgICAgKi9cbiAgICBfc2V0Um9vdChub2RlKSB7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBub2RlO1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5wYXJlbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2UgdGhlIHJlZmVyZW5jZXMgdG8gdGhlIG5vZGUgaW4gdGhlIG5vZGUncyBwYXJlbnRcbiAgICAgKiB3aXRoIHRoZSByZXBsYWNlbWVudCBub2RlLlxuICAgICAqL1xuICAgIF9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIHJlcGxhY2VtZW50KSB7XG4gICAgICAgIGlmIChub2RlLnBhcmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LmxlZnQgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUucGFyZW50LnJpZ2h0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2Uobm9kZS5wYXJlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChyZXBsYWNlbWVudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHRoZSBub2RlIGZyb20gdGhlIHRyZWUgYW5kIHJlcGxhY2UgaXQgd2l0aFxuICAgICAqIGEgc3VjY2Vzc29yIHdoaWNoIGZvbGxvd3MgdGhlIHNjaGVtYS5cbiAgICAgKi9cbiAgICBfcmVtb3ZlTm9kZShub2RlKSB7XG4gICAgICAgIGlmIChub2RlLmxlZnQgPT09IG51bGwgJiYgbm9kZS5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fcmVwbGFjZU5vZGVJblBhcmVudChub2RlLCBudWxsKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUubGVmdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5sZWZ0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXBsYWNlTm9kZUluUGFyZW50KG5vZGUsIG5vZGUucmlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYmFsYW5jZSA9IG5vZGUuZ2V0QmFsYW5jZSgpO1xuICAgICAgICAgICAgbGV0IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgbGV0IHRlbXAgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGJhbGFuY2UgPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUubGVmdC5yaWdodCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQucmlnaHQgPSBub2RlLnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IG5vZGUubGVmdC5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHJlcGxhY2VtZW50LnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXBsYWNlbWVudC5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50LmxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQucGFyZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQubGVmdCA9IG5vZGUubGVmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50LnJpZ2h0ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG5vZGUucmlnaHQubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodDtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgIHRlbXAgPSByZXBsYWNlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gbm9kZS5yaWdodC5sZWZ0O1xuICAgICAgICAgICAgICAgIHdoaWxlIChyZXBsYWNlbWVudC5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50ID0gcmVwbGFjZW1lbnQubGVmdDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHJlcGxhY2VtZW50LnBhcmVudCkge1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5wYXJlbnQubGVmdCA9IHJlcGxhY2VtZW50LnJpZ2h0O1xuICAgICAgICAgICAgICAgICAgICB0ZW1wID0gcmVwbGFjZW1lbnQucGFyZW50O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5sZWZ0ID0gbm9kZS5sZWZ0O1xuICAgICAgICAgICAgICAgICAgICByZXBsYWNlbWVudC5yaWdodCA9IG5vZGUucmlnaHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vZGUucGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWZ0Q2hpbGQoKSkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5sZWZ0ID0gcmVwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnBhcmVudC5yaWdodCA9IHJlcGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocmVwbGFjZW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRlbXApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yZWJhbGFuY2UodGVtcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbm9kZS5kaXNwb3NlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgbGVmdFxuICAgICAqL1xuICAgIF9yb3RhdGVMZWZ0KG5vZGUpIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gbm9kZS5wYXJlbnQ7XG4gICAgICAgIGNvbnN0IGlzTGVmdENoaWxkID0gbm9kZS5pc0xlZnRDaGlsZCgpO1xuICAgICAgICAvLyBNYWtlIG5vZGUucmlnaHQgdGhlIG5ldyByb290IG9mIHRoaXMgc3ViIHRyZWUgKGluc3RlYWQgb2Ygbm9kZSlcbiAgICAgICAgY29uc3QgcGl2b3ROb2RlID0gbm9kZS5yaWdodDtcbiAgICAgICAgaWYgKHBpdm90Tm9kZSkge1xuICAgICAgICAgICAgbm9kZS5yaWdodCA9IHBpdm90Tm9kZS5sZWZ0O1xuICAgICAgICAgICAgcGl2b3ROb2RlLmxlZnQgPSBub2RlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChpc0xlZnRDaGlsZCkge1xuICAgICAgICAgICAgICAgIHBhcmVudC5sZWZ0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGFyZW50LnJpZ2h0ID0gcGl2b3ROb2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fc2V0Um9vdChwaXZvdE5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJvdGF0ZSB0aGUgdHJlZSB0byB0aGUgcmlnaHRcbiAgICAgKi9cbiAgICBfcm90YXRlUmlnaHQobm9kZSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBub2RlLnBhcmVudDtcbiAgICAgICAgY29uc3QgaXNMZWZ0Q2hpbGQgPSBub2RlLmlzTGVmdENoaWxkKCk7XG4gICAgICAgIC8vIE1ha2Ugbm9kZS5sZWZ0IHRoZSBuZXcgcm9vdCBvZiB0aGlzIHN1YiB0cmVlIChpbnN0ZWFkIG9mIG5vZGUpXG4gICAgICAgIGNvbnN0IHBpdm90Tm9kZSA9IG5vZGUubGVmdDtcbiAgICAgICAgaWYgKHBpdm90Tm9kZSkge1xuICAgICAgICAgICAgbm9kZS5sZWZ0ID0gcGl2b3ROb2RlLnJpZ2h0O1xuICAgICAgICAgICAgcGl2b3ROb2RlLnJpZ2h0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoaXNMZWZ0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQubGVmdCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhcmVudC5yaWdodCA9IHBpdm90Tm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX3NldFJvb3QocGl2b3ROb2RlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBCYWxhbmNlIHRoZSBCU1RcbiAgICAgKi9cbiAgICBfcmViYWxhbmNlKG5vZGUpIHtcbiAgICAgICAgY29uc3QgYmFsYW5jZSA9IG5vZGUuZ2V0QmFsYW5jZSgpO1xuICAgICAgICBpZiAoYmFsYW5jZSA+IDEgJiYgbm9kZS5sZWZ0KSB7XG4gICAgICAgICAgICBpZiAobm9kZS5sZWZ0LmdldEJhbGFuY2UoKSA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVMZWZ0KG5vZGUubGVmdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb3RhdGVSaWdodChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiYWxhbmNlIDwgLTEgJiYgbm9kZS5yaWdodCkge1xuICAgICAgICAgICAgaWYgKG5vZGUucmlnaHQuZ2V0QmFsYW5jZSgpID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3JvdGF0ZVJpZ2h0KG5vZGUucmlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcm90YXRlTGVmdChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgYW4gZXZlbnQgd2hvc2UgdGltZSBhbmQgZHVyYXRpb24gc3BhbiB0aGUgZ2l2ZSB0aW1lLiBXaWxsXG4gICAgICogcmV0dXJuIHRoZSBtYXRjaCB3aG9zZSBcInRpbWVcIiB2YWx1ZSBpcyBjbG9zZXN0IHRvIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEByZXR1cm4gIFRoZSBldmVudCB3aGljaCBzcGFucyB0aGUgZGVzaXJlZCB0aW1lXG4gICAgICovXG4gICAgZ2V0KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Jvb3QgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3Quc2VhcmNoKHRpbWUsIHJlc3VsdHMpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIGxldCBtYXggPSByZXN1bHRzWzBdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0c1tpXS5sb3cgPiBtYXgubG93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtYXggPSByZXN1bHRzW2ldO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBtYXguZXZlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSB0aW1lbGluZS5cbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaChjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgYWxsTm9kZXMgPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3Jvb3QudHJhdmVyc2Uobm9kZSA9PiBhbGxOb2Rlcy5wdXNoKG5vZGUpKTtcbiAgICAgICAgICAgIGFsbE5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBpbiB3aGljaCB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIG92ZXJsYXBzIHdpdGggdGhlIHRpbWUgYW5kIGR1cmF0aW9uIHRpbWUgb2YgdGhlIGV2ZW50LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSB0byBjaGVjayBpZiBpdGVtcyBhcmUgb3ZlcmxhcHBpbmdcbiAgICAgKiBAcGFyYW0gIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBpbnZva2Ugd2l0aCBldmVyeSBpdGVtXG4gICAgICovXG4gICAgZm9yRWFjaEF0VGltZSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2godGltZSwgcmVzdWx0cyk7XG4gICAgICAgICAgICByZXN1bHRzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobm9kZS5ldmVudCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBldmVyeXRoaW5nIGluIHRoZSBhcnJheSBpbiB3aGljaCB0aGUgdGltZSBpcyBncmVhdGVyXG4gICAgICogdGhhbiBvciBlcXVhbCB0byB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdG8gY2hlY2sgaWYgaXRlbXMgYXJlIGJlZm9yZVxuICAgICAqIEBwYXJhbSAgY2FsbGJhY2sgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aXRoIGV2ZXJ5IGl0ZW1cbiAgICAgKi9cbiAgICBmb3JFYWNoRnJvbSh0aW1lLCBjYWxsYmFjaykge1xuICAgICAgICBpZiAodGhpcy5fcm9vdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fcm9vdC5zZWFyY2hBZnRlcih0aW1lLCByZXN1bHRzKTtcbiAgICAgICAgICAgIHJlc3VsdHMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5ldmVudCkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhub2RlLmV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIGlmICh0aGlzLl9yb290ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLl9yb290LnRyYXZlcnNlKG5vZGUgPT4gbm9kZS5kaXNwb3NlKCkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5URVJWQUwgTk9ERSBIRUxQRVJcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLyoqXG4gKiBSZXByZXNlbnRzIGEgbm9kZSBpbiB0aGUgYmluYXJ5IHNlYXJjaCB0cmVlLCB3aXRoIHRoZSBhZGRpdGlvblxuICogb2YgYSBcImhpZ2hcIiB2YWx1ZSB3aGljaCBrZWVwcyB0cmFjayBvZiB0aGUgaGlnaGVzdCB2YWx1ZSBvZlxuICogaXRzIGNoaWxkcmVuLlxuICogUmVmZXJlbmNlczpcbiAqIGh0dHBzOi8vYnJvb2tub3Zhay53b3JkcHJlc3MuY29tLzIwMTMvMTIvMDcvYXVnbWVudGVkLWludGVydmFsLXRyZWUtaW4tYy9cbiAqIGh0dHA6Ly93d3cubWlmLnZ1Lmx0L352YWxkYXMvQUxHT1JJVE1BSS9MSVRFUkFUVVJBL0Nvcm1lbi9Db3JtZW4ucGRmXG4gKiBAcGFyYW0gbG93XG4gKiBAcGFyYW0gaGlnaFxuICovXG5jbGFzcyBJbnRlcnZhbE5vZGUge1xuICAgIGNvbnN0cnVjdG9yKGxvdywgaGlnaCwgZXZlbnQpIHtcbiAgICAgICAgLy8gdGhlIG5vZGVzIHRvIHRoZSBsZWZ0XG4gICAgICAgIHRoaXMuX2xlZnQgPSBudWxsO1xuICAgICAgICAvLyB0aGUgbm9kZXMgdG8gdGhlIHJpZ2h0XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIHBhcmVudCBub2RlXG4gICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICAgICAgLy8gdGhlIG51bWJlciBvZiBjaGlsZCBub2Rlc1xuICAgICAgICB0aGlzLmhlaWdodCA9IDA7XG4gICAgICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICAgICAgLy8gdGhlIGxvdyB2YWx1ZVxuICAgICAgICB0aGlzLmxvdyA9IGxvdztcbiAgICAgICAgLy8gdGhlIGhpZ2ggdmFsdWVcbiAgICAgICAgdGhpcy5oaWdoID0gaGlnaDtcbiAgICAgICAgLy8gdGhlIGhpZ2ggdmFsdWUgZm9yIHRoaXMgYW5kIGFsbCBjaGlsZCBub2Rlc1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zZXJ0IGEgbm9kZSBpbnRvIHRoZSBjb3JyZWN0IHNwb3QgaW4gdGhlIHRyZWVcbiAgICAgKi9cbiAgICBpbnNlcnQobm9kZSkge1xuICAgICAgICBpZiAobm9kZS5sb3cgPD0gdGhpcy5sb3cpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlZnQgPSBub2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWZ0Lmluc2VydChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0ID0gbm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmlnaHQuaW5zZXJ0KG5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNlYXJjaCB0aGUgdHJlZSBmb3Igbm9kZXMgd2hpY2ggb3ZlcmxhcFxuICAgICAqIHdpdGggdGhlIGdpdmVuIHBvaW50XG4gICAgICogQHBhcmFtICBwb2ludCAgVGhlIHBvaW50IHRvIHF1ZXJ5XG4gICAgICogQHBhcmFtICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG4gICAgICovXG4gICAgc2VhcmNoKHBvaW50LCByZXN1bHRzKSB7XG4gICAgICAgIC8vIElmIHAgaXMgdG8gdGhlIHJpZ2h0IG9mIHRoZSByaWdodG1vc3QgcG9pbnQgb2YgYW55IGludGVydmFsXG4gICAgICAgIC8vIGluIHRoaXMgbm9kZSBhbmQgYWxsIGNoaWxkcmVuLCB0aGVyZSB3b24ndCBiZSBhbnkgbWF0Y2hlcy5cbiAgICAgICAgaWYgKHBvaW50ID4gdGhpcy5tYXgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBTZWFyY2ggbGVmdCBjaGlsZHJlblxuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxlZnQuc2VhcmNoKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBDaGVjayB0aGlzIG5vZGVcbiAgICAgICAgaWYgKHRoaXMubG93IDw9IHBvaW50ICYmIHRoaXMuaGlnaCA+IHBvaW50KSB7XG4gICAgICAgICAgICByZXN1bHRzLnB1c2godGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgcCBpcyB0byB0aGUgbGVmdCBvZiB0aGUgdGltZSBvZiB0aGlzIGludGVydmFsLFxuICAgICAgICAvLyB0aGVuIGl0IGNhbid0IGJlIGluIGFueSBjaGlsZCB0byB0aGUgcmlnaHQuXG4gICAgICAgIGlmICh0aGlzLmxvdyA+IHBvaW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VhcmNoIHJpZ2h0IGNoaWxkcmVuXG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaChwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VhcmNoIHRoZSB0cmVlIGZvciBub2RlcyB3aGljaCBhcmUgbGVzc1xuICAgICAqIHRoYW4gdGhlIGdpdmVuIHBvaW50XG4gICAgICogQHBhcmFtICBwb2ludCAgVGhlIHBvaW50IHRvIHF1ZXJ5XG4gICAgICogQHBhcmFtICByZXN1bHRzICBUaGUgYXJyYXkgdG8gcHV0IHRoZSByZXN1bHRzXG4gICAgICovXG4gICAgc2VhcmNoQWZ0ZXIocG9pbnQsIHJlc3VsdHMpIHtcbiAgICAgICAgLy8gQ2hlY2sgdGhpcyBub2RlXG4gICAgICAgIGlmICh0aGlzLmxvdyA+PSBwb2ludCkge1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHRoaXMpO1xuICAgICAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVmdC5zZWFyY2hBZnRlcihwb2ludCwgcmVzdWx0cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2VhcmNoIHRoZSByaWdodCBzaWRlXG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnNlYXJjaEFmdGVyKHBvaW50LCByZXN1bHRzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGNhbGxiYWNrIG9uIHRoaXMgZWxlbWVudCBhbmQgYm90aCBpdCdzIGJyYW5jaGVzXG4gICAgICogQHBhcmFtICB7RnVuY3Rpb259ICBjYWxsYmFja1xuICAgICAqL1xuICAgIHRyYXZlcnNlKGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrKHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmxlZnQudHJhdmVyc2UoY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnJpZ2h0LnRyYXZlcnNlKGNhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGhlaWdodCBvZiB0aGUgbm9kZVxuICAgICAqL1xuICAgIHVwZGF0ZUhlaWdodCgpIHtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IE1hdGgubWF4KHRoaXMubGVmdC5oZWlnaHQsIHRoaXMucmlnaHQuaGVpZ2h0KSArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5yaWdodCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSB0aGlzLnJpZ2h0LmhlaWdodCArIDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMubGVmdC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB0aGUgaGVpZ2h0IG9mIHRoZSBub2RlXG4gICAgICovXG4gICAgdXBkYXRlTWF4KCkge1xuICAgICAgICB0aGlzLm1heCA9IHRoaXMuaGlnaDtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5tYXggPSBNYXRoLm1heCh0aGlzLm1heCwgdGhpcy5sZWZ0Lm1heCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMubWF4ID0gTWF0aC5tYXgodGhpcy5tYXgsIHRoaXMucmlnaHQubWF4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFsYW5jZSBpcyBob3cgdGhlIGxlYWZzIGFyZSBkaXN0cmlidXRlZCBvbiB0aGUgbm9kZVxuICAgICAqIEByZXR1cm4gIE5lZ2F0aXZlIG51bWJlcnMgYXJlIGJhbGFuY2VkIHRvIHRoZSByaWdodFxuICAgICAqL1xuICAgIGdldEJhbGFuY2UoKSB7XG4gICAgICAgIGxldCBiYWxhbmNlID0gMDtcbiAgICAgICAgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBiYWxhbmNlID0gdGhpcy5sZWZ0LmhlaWdodCAtIHRoaXMucmlnaHQuaGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgYmFsYW5jZSA9IHRoaXMubGVmdC5oZWlnaHQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMucmlnaHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGJhbGFuY2UgPSAtKHRoaXMucmlnaHQuaGVpZ2h0ICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhbGFuY2U7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEByZXR1cm5zIHRydWUgaWYgdGhpcyBub2RlIGlzIHRoZSBsZWZ0IGNoaWxkIG9mIGl0cyBwYXJlbnRcbiAgICAgKi9cbiAgICBpc0xlZnRDaGlsZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50ICE9PSBudWxsICYmIHRoaXMucGFyZW50LmxlZnQgPT09IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGdldC9zZXQgdGhlIGxlZnQgbm9kZVxuICAgICAqL1xuICAgIGdldCBsZWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGVmdDtcbiAgICB9XG4gICAgc2V0IGxlZnQobm9kZSkge1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQvc2V0IHRoZSByaWdodCBub2RlXG4gICAgICovXG4gICAgZ2V0IHJpZ2h0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmlnaHQ7XG4gICAgfVxuICAgIHNldCByaWdodChub2RlKSB7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5vZGUucGFyZW50ID0gdGhpcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCgpO1xuICAgICAgICB0aGlzLnVwZGF0ZU1heCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBudWxsIG91dCByZWZlcmVuY2VzLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fbGVmdCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3JpZ2h0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5ldmVudCA9IG51bGw7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW50ZXJ2YWxUaW1lbGluZS5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9jbG9jay9DbG9ja1wiO1xuLy8gZXhwb3J0ICogZnJvbSBcIi4vY2xvY2svVHJhbnNwb3J0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L0NvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvQmFzZUNvbnRleHRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvRGVsYXlcIjtcbi8vIGV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvRGVzdGluYXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NvbnRleHQvR2FpblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9PZmZsaW5lXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1BhcmFtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvRnJlcXVlbmN5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi90eXBlL01pZGlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGUvVGltZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UaWNrc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgXCIuL3V0aWwvRHJhd1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9FbWl0dGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsL0ludGVydmFsVGltZWxpbmVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3V0aWwvU3RhdGVUaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9UaW1lbGluZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbC9UeXBlQ2hlY2tcIjtcbmV4cG9ydCB7IGRiVG9HYWluLCBnYWluVG9EYiwgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvLCBmdG9tLCBtdG9mIH0gZnJvbSBcIi4vdHlwZS9Db252ZXJzaW9uc1wiO1xuZXhwb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMsIGRlZmF1bHRBcmcgfSBmcm9tIFwiLi91dGlsL0RlZmF1bHRzXCI7XG4vLyBnZXQgdGhlIHVuaXRzIGFuZCBleHBvcnQgdGhlbSB1bmRlciB0aGUgXCJVbml0XCIgbmFtZXNwYWNlXG5pbXBvcnQgKiBhcyBVbml0IGZyb20gXCIuL3R5cGUvVW5pdHNcIjtcbmV4cG9ydCB7IFVuaXQgfTtcbi8vIGV4cG9ydCB0aGUgZGVidWcgc3R1ZmYgYXMgRGVidWdcbmltcG9ydCAqIGFzIGRlYnVnIGZyb20gXCIuL3V0aWwvRGVidWdcIjtcbmV4cG9ydCB7IGRlYnVnIH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogVm9sdW1lIGlzIGEgc2ltcGxlIHZvbHVtZSBub2RlLCB1c2VmdWwgZm9yIGNyZWF0aW5nIGEgdm9sdW1lIGZhZGVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCB2b2wgPSBuZXcgVG9uZS5Wb2x1bWUoLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdCh2b2wpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBWb2x1bWUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVm9sdW1lLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVm9sdW1lXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhWb2x1bWUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLnZvbHVtZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMub3V0cHV0LmdhaW47XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLl91bm11dGVkVm9sdW1lID0gb3B0aW9ucy52b2x1bWU7XG4gICAgICAgIC8vIHNldCB0aGUgbXV0ZSBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCB2b2wgPSBuZXcgVG9uZS5Wb2x1bWUoLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3Qodm9sKS5zdGFydCgpO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIHZvbC5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudm9sdW1lLnZhbHVlID09PSAtSW5maW5pdHk7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLm11dGUgJiYgbXV0ZSkge1xuICAgICAgICAgICAgdGhpcy5fdW5tdXRlZFZvbHVtZSA9IHRoaXMudm9sdW1lLnZhbHVlO1xuICAgICAgICAgICAgLy8gbWF5YmUgaXQgc2hvdWxkIHJhbXAgaGVyZT9cbiAgICAgICAgICAgIHRoaXMudm9sdW1lLnZhbHVlID0gLUluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMubXV0ZSAmJiAhbXV0ZSkge1xuICAgICAgICAgICAgdGhpcy52b2x1bWUudmFsdWUgPSB0aGlzLl91bm11dGVkVm9sdW1lO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Wb2x1bWUuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgb25Db250ZXh0Q2xvc2UsIG9uQ29udGV4dEluaXQgfSBmcm9tIFwiLi9Db250ZXh0SW5pdGlhbGl6YXRpb25cIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4vVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBBIHNpbmdsZSBtYXN0ZXIgb3V0cHV0IHdoaWNoIGlzIGNvbm5lY3RlZCB0byB0aGVcbiAqIEF1ZGlvRGVzdGluYXRpb25Ob2RlIChha2EgeW91ciBzcGVha2VycykuXG4gKiBJdCBwcm92aWRlcyB1c2VmdWwgY29udmVuaWVuY2VzIHN1Y2ggYXMgdGhlIGFiaWxpdHlcbiAqIHRvIHNldCB0aGUgdm9sdW1lIGFuZCBtdXRlIHRoZSBlbnRpcmUgYXBwbGljYXRpb24uXG4gKiBJdCBhbHNvIGdpdmVzIHlvdSB0aGUgYWJpbGl0eSB0byBhcHBseSBtYXN0ZXIgZWZmZWN0cyB0byB5b3VyIGFwcGxpY2F0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnN0YXJ0KCk7XG4gKiAvLyB0aGUgYXVkaW8gd2lsbCBnbyBmcm9tIHRoZSBvc2NpbGxhdG9yIHRvIHRoZSBzcGVha2Vyc1xuICogb3NjaWxsYXRvci5jb25uZWN0KFRvbmUuZ2V0RGVzdGluYXRpb24oKSk7XG4gKiAvLyBhIGNvbnZlbmllbmNlIGZvciBjb25uZWN0aW5nIHRvIHRoZSBtYXN0ZXIgb3V0cHV0IGlzIGFsc28gcHJvdmlkZWQ6XG4gKiBvc2NpbGxhdG9yLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBEZXN0aW5hdGlvbiBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEZXN0aW5hdGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJEZXN0aW5hdGlvblwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IFZvbHVtZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2b2x1bWUgb2YgdGhlIG1hc3RlciBvdXRwdXQgaW4gZGVjaWJlbHMuIC1JbmZpbml0eSBpcyBzaWxlbnQsIGFuZCAwIGlzIG5vIGNoYW5nZS5cbiAgICAgICAgICogQGV4YW1wbGVcbiAgICAgICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgICogb3NjLnN0YXJ0KCk7XG4gICAgICAgICAqIC8vIHJhbXAgdGhlIHZvbHVtZSBkb3duIHRvIHNpbGVudCBvdmVyIDEwIHNlY29uZHNcbiAgICAgICAgICogVG9uZS5nZXREZXN0aW5hdGlvbigpLnZvbHVtZS5yYW1wVG8oLUluZmluaXR5LCAxMCk7XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuaW5wdXQudm9sdW1lO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGVzdGluYXRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCB0aGlzLm91dHB1dCwgdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24pO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5pbnB1dCwgdGhpcy5jb250ZXh0LnJhd0NvbnRleHQuZGVzdGluYXRpb24sIHRoaXMub3V0cHV0XTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgKiBcdC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIFx0VG9uZS5EZXN0aW5hdGlvbi5tdXRlID0gdHJ1ZTtcbiAgICAgKiB9LCAxMDAwKTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5wdXQubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLmlucHV0Lm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgYSBtYXN0ZXIgZWZmZWN0cyBjaGFpbi4gTk9URTogdGhpcyB3aWxsIGRpc2Nvbm5lY3QgYW55IG5vZGVzIHdoaWNoIHdlcmUgcHJldmlvdXNseVxuICAgICAqIGNoYWluZWQgaW4gdGhlIG1hc3RlciBlZmZlY3RzIGNoYWluLlxuICAgICAqIEBwYXJhbSBhcmdzIEFsbCBhcmd1bWVudHMgd2lsbCBiZSBjb25uZWN0ZWQgaW4gYSByb3cgYW5kIHRoZSBNYXN0ZXIgd2lsbCBiZSByb3V0ZWQgdGhyb3VnaCBpdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHJvdXRlIGFsbCBhdWRpbyB0aHJvdWdoIGEgZmlsdGVyIGFuZCBjb21wcmVzc29yXG4gICAgICogY29uc3QgbG93cGFzcyA9IG5ldyBUb25lLkZpbHRlcig4MDAsIFwibG93cGFzc1wiKTtcbiAgICAgKiBjb25zdCBjb21wcmVzc29yID0gbmV3IFRvbmUuQ29tcHJlc3NvcigtMTgpO1xuICAgICAqIFRvbmUuRGVzdGluYXRpb24uY2hhaW4obG93cGFzcywgY29tcHJlc3Nvcik7XG4gICAgICovXG4gICAgY2hhaW4oLi4uYXJncykge1xuICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgYXJncy51bnNoaWZ0KHRoaXMuaW5wdXQpO1xuICAgICAgICBhcmdzLnB1c2godGhpcy5vdXRwdXQpO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLmFyZ3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYW5uZWxzIHRoZSBzeXN0ZW0gY2FuIG91dHB1dFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc29sZS5sb2coVG9uZS5EZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQpO1xuICAgICAqL1xuICAgIGdldCBtYXhDaGFubmVsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5kZXN0aW5hdGlvbi5tYXhDaGFubmVsQ291bnQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQuZGVzdGluYXRpb24gPSBuZXcgRGVzdGluYXRpb24oeyBjb250ZXh0IH0pO1xufSk7XG5vbkNvbnRleHRDbG9zZShjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0LmRlc3RpbmF0aW9uLmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVzdGluYXRpb24uanMubWFwIiwiaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi9UaW1lbGluZVwiO1xuaW1wb3J0IHsgVG9uZSB9IGZyb20gXCIuLi9Ub25lXCI7XG4vKipcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgdmFsdWUgd2hpY2ggaXMgZ2V0dGFibGUgYW5kIHNldHRhYmxlIGluIGEgdGltZWQgd2F5XG4gKi9cbmV4cG9ydCBjbGFzcyBUaW1lbGluZVZhbHVlIGV4dGVuZHMgVG9uZSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIGluaXRpYWxWYWx1ZSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIHRoZXJlIGlzIG5vIHNjaGVkdWxlZCB2YWx1ZXNcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihpbml0aWFsVmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUaW1lbGluZVZhbHVlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdGltZWxpbmUgd2hpY2ggc3RvcmVzIHRoZSB2YWx1ZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RpbWVsaW5lID0gbmV3IFRpbWVsaW5lKHsgbWVtb3J5OiAxMCB9KTtcbiAgICAgICAgdGhpcy5faW5pdGlhbFZhbHVlID0gaW5pdGlhbFZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiB0aW1lXG4gICAgICovXG4gICAgc2V0KHZhbHVlLCB0aW1lKSB7XG4gICAgICAgIHRoaXMuX3RpbWVsaW5lLmFkZCh7XG4gICAgICAgICAgICB2YWx1ZSwgdGltZVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKi9cbiAgICBnZXQodGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX3RpbWVsaW5lLmdldCh0aW1lKTtcbiAgICAgICAgaWYgKGV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQudmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5faW5pdGlhbFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VGltZWxpbmVWYWx1ZS5qcy5tYXAiLCJpbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFRyYW5zcG9ydEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgW1tUcmFuc3BvcnRdXVxuICogdG8gc2NoZWR1bGUgZXZlbnRzLiBEbyBubyBpbnZva2UgdGhpcyBjbGFzcyBkaXJlY3RseSwgaXQgaXNcbiAqIGhhbmRsZWQgZnJvbSB3aXRoaW4gVG9uZS5UcmFuc3BvcnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRFdmVudCB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtIHRyYW5zcG9ydCBUaGUgdHJhbnNwb3J0IG9iamVjdCB3aGljaCB0aGUgZXZlbnQgYmVsb25ncyB0b1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHRyYW5zcG9ydCwgb3B0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHVuaXF1ZSBpZCBvZiB0aGUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaWQgPSBUcmFuc3BvcnRFdmVudC5fZXZlbnRJZCsrO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gT2JqZWN0LmFzc2lnbihUcmFuc3BvcnRFdmVudC5nZXREZWZhdWx0cygpLCBvcHRzKTtcbiAgICAgICAgdGhpcy50cmFuc3BvcnQgPSB0cmFuc3BvcnQ7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLl9vbmNlID0gb3B0aW9ucy5vbmNlO1xuICAgICAgICB0aGlzLnRpbWUgPSBvcHRpb25zLnRpbWU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgb25jZTogZmFsc2UsXG4gICAgICAgICAgICB0aW1lOiAwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGV2ZW50IGNhbGxiYWNrLlxuICAgICAqIEBwYXJhbSAgdGltZSAgVGhlIEF1ZGlvQ29udGV4dCB0aW1lIGluIHNlY29uZHMgb2YgdGhlIGV2ZW50XG4gICAgICovXG4gICAgaW52b2tlKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMuY2FsbGJhY2sodGltZSk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb25jZSkge1xuICAgICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0LmNsZWFyKHRoaXMuaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLyoqXG4gKiBDdXJyZW50IElEIGNvdW50ZXJcbiAqL1xuVHJhbnNwb3J0RXZlbnQuX2V2ZW50SWQgPSAwO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0RXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydEV2ZW50XCI7XG4vKipcbiAqIFRyYW5zcG9ydFJlcGVhdEV2ZW50IGlzIGFuIGludGVybmFsIGNsYXNzIHVzZWQgYnkgVG9uZS5UcmFuc3BvcnRcbiAqIHRvIHNjaGVkdWxlIHJlcGVhdCBldmVudHMuIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnRSZXBlYXRFdmVudCBleHRlbmRzIFRyYW5zcG9ydEV2ZW50IHtcbiAgICAvKipcbiAgICAgKiBAcGFyYW0gdHJhbnNwb3J0IFRoZSB0cmFuc3BvcnQgb2JqZWN0IHdoaWNoIHRoZSBldmVudCBiZWxvbmdzIHRvXG4gICAgICovXG4gICAgY29uc3RydWN0b3IodHJhbnNwb3J0LCBvcHRzKSB7XG4gICAgICAgIHN1cGVyKHRyYW5zcG9ydCwgb3B0cyk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgSUQgb2YgdGhlIGN1cnJlbnQgdGltZWxpbmUgZXZlbnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2N1cnJlbnRJZCA9IC0xO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIElEIG9mIHRoZSBuZXh0IHRpbWVsaW5lIGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZXh0SWQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0aW1lIG9mIHRoZSBuZXh0IGV2ZW50XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGEgcmVmZXJlbmNlIHRvIHRoZSBib3VuZCBzdGFydCBtZXRob2RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2JvdW5kUmVzdGFydCA9IHRoaXMuX3Jlc3RhcnQuYmluZCh0aGlzKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oVHJhbnNwb3J0UmVwZWF0RXZlbnQuZ2V0RGVmYXVsdHMoKSwgb3B0cyk7XG4gICAgICAgIHRoaXMuZHVyYXRpb24gPSBuZXcgVGlja3NDbGFzcyh0cmFuc3BvcnQuY29udGV4dCwgb3B0aW9ucy5kdXJhdGlvbikudmFsdWVPZigpO1xuICAgICAgICB0aGlzLl9pbnRlcnZhbCA9IG5ldyBUaWNrc0NsYXNzKHRyYW5zcG9ydC5jb250ZXh0LCBvcHRpb25zLmludGVydmFsKS52YWx1ZU9mKCk7XG4gICAgICAgIHRoaXMuX25leHRUaWNrID0gb3B0aW9ucy50aW1lO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMudHJhbnNwb3J0Lm9uKFwibG9vcFN0YXJ0XCIsIHRoaXMuX2JvdW5kUmVzdGFydCk7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IHRoaXMudHJhbnNwb3J0LmNvbnRleHQ7XG4gICAgICAgIHRoaXMuX3Jlc3RhcnQoKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgVHJhbnNwb3J0RXZlbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZHVyYXRpb246IEluZmluaXR5LFxuICAgICAgICAgICAgaW50ZXJ2YWw6IDEsXG4gICAgICAgICAgICBvbmNlOiBmYWxzZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludm9rZSB0aGUgY2FsbGJhY2suIFJldHVybnMgdGhlIHRpY2sgdGltZSB3aGljaFxuICAgICAqIHRoZSBuZXh0IGV2ZW50IHNob3VsZCBiZSBzY2hlZHVsZWQgYXQuXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgQXVkaW9Db250ZXh0IHRpbWUgaW4gc2Vjb25kcyBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICBpbnZva2UodGltZSkge1xuICAgICAgICAvLyBjcmVhdGUgbW9yZSBldmVudHMgaWYgbmVjZXNzYXJ5XG4gICAgICAgIHRoaXMuX2NyZWF0ZUV2ZW50cyh0aW1lKTtcbiAgICAgICAgLy8gY2FsbCB0aGUgc3VwZXIgY2xhc3NcbiAgICAgICAgc3VwZXIuaW52b2tlKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdXNoIG1vcmUgZXZlbnRzIG9udG8gdGhlIHRpbWVsaW5lIHRvIGtlZXAgdXAgd2l0aCB0aGUgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgX2NyZWF0ZUV2ZW50cyh0aW1lKSB7XG4gICAgICAgIC8vIHNjaGVkdWxlIHRoZSBuZXh0IGV2ZW50XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50cmFuc3BvcnQuZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGlmICh0aWNrcyA+PSB0aGlzLnRpbWUgJiYgdGlja3MgPj0gdGhpcy5fbmV4dFRpY2sgJiYgdGhpcy5fbmV4dFRpY2sgKyB0aGlzLl9pbnRlcnZhbCA8IHRoaXMudGltZSArIHRoaXMuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuX25leHRUaWNrICs9IHRoaXMuX2ludGVydmFsO1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudElkID0gdGhpcy5fbmV4dElkO1xuICAgICAgICAgICAgdGhpcy5fbmV4dElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBQdXNoIG1vcmUgZXZlbnRzIG9udG8gdGhlIHRpbWVsaW5lIHRvIGtlZXAgdXAgd2l0aCB0aGUgcG9zaXRpb24gb2YgdGhlIHRpbWVsaW5lXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9jdXJyZW50SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9uZXh0SWQpO1xuICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRyYW5zcG9ydC5nZXRUaWNrc0F0VGltZSh0aW1lKTtcbiAgICAgICAgaWYgKHRpY2tzID4gdGhpcy50aW1lKSB7XG4gICAgICAgICAgICB0aGlzLl9uZXh0VGljayA9IHRoaXMudGltZSArIE1hdGguY2VpbCgodGlja3MgLSB0aGlzLnRpbWUpIC8gdGhpcy5faW50ZXJ2YWwpICogdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY3VycmVudElkID0gdGhpcy50cmFuc3BvcnQuc2NoZWR1bGVPbmNlKHRoaXMuaW52b2tlLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbmV4dFRpY2spLnRvU2Vjb25kcygpKTtcbiAgICAgICAgdGhpcy5fbmV4dFRpY2sgKz0gdGhpcy5faW50ZXJ2YWw7XG4gICAgICAgIHRoaXMuX25leHRJZCA9IHRoaXMudHJhbnNwb3J0LnNjaGVkdWxlT25jZSh0aGlzLmludm9rZS5iaW5kKHRoaXMpLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX25leHRUaWNrKS50b1NlY29uZHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9jdXJyZW50SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5jbGVhcih0aGlzLl9uZXh0SWQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9ib3VuZFJlc3RhcnQpO1xuICAgICAgICB0aGlzLnRyYW5zcG9ydC5vZmYoXCJsb29wU3RhcnRcIiwgdGhpcy5fYm91bmRSZXN0YXJ0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0UmVwZWF0RXZlbnQuanMubWFwIiwiaW1wb3J0IHsgVGltZUNsYXNzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9UaW1lXCI7XG5pbXBvcnQgeyBUaW1lbGluZVZhbHVlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UaW1lbGluZVZhbHVlXCI7XG5pbXBvcnQgeyBvbkNvbnRleHRDbG9zZSwgb25Db250ZXh0SW5pdCB9IGZyb20gXCIuLi9jb250ZXh0L0NvbnRleHRJbml0aWFsaXphdGlvblwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi90eXBlL1RpY2tzXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRUaW1lQ2xhc3MgfSBmcm9tIFwiLi4vdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbWl0dGVyIH0gZnJvbSBcIi4uL3V0aWwvRW1pdHRlclwiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBJbnRlcnZhbFRpbWVsaW5lIH0gZnJvbSBcIi4uL3V0aWwvSW50ZXJ2YWxUaW1lbGluZVwiO1xuaW1wb3J0IHsgVGltZWxpbmUgfSBmcm9tIFwiLi4vdXRpbC9UaW1lbGluZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNEZWZpbmVkIH0gZnJvbSBcIi4uL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBDbG9jayB9IGZyb20gXCIuL0Nsb2NrXCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydEV2ZW50XCI7XG5pbXBvcnQgeyBUcmFuc3BvcnRSZXBlYXRFdmVudCB9IGZyb20gXCIuL1RyYW5zcG9ydFJlcGVhdEV2ZW50XCI7XG4vKipcbiAqIFRyYW5zcG9ydCBmb3IgdGltaW5nIG11c2ljYWwgZXZlbnRzLlxuICogU3VwcG9ydHMgdGVtcG8gY3VydmVzIGFuZCB0aW1lIGNoYW5nZXMuIFVubGlrZSBicm93c2VyLWJhc2VkIHRpbWluZyAoc2V0SW50ZXJ2YWwsIHJlcXVlc3RBbmltYXRpb25GcmFtZSlcbiAqIFRyYW5zcG9ydCB0aW1pbmcgZXZlbnRzIHBhc3MgaW4gdGhlIGV4YWN0IHRpbWUgb2YgdGhlIHNjaGVkdWxlZCBldmVudFxuICogaW4gdGhlIGFyZ3VtZW50IG9mIHRoZSBjYWxsYmFjayBmdW5jdGlvbi4gUGFzcyB0aGF0IHRpbWUgdmFsdWUgdG8gdGhlIG9iamVjdFxuICogeW91J3JlIHNjaGVkdWxpbmcuIDxicj48YnI+XG4gKiBBIHNpbmdsZSB0cmFuc3BvcnQgaXMgY3JlYXRlZCBmb3IgeW91IHdoZW4gdGhlIGxpYnJhcnkgaXMgaW5pdGlhbGl6ZWQuXG4gKiA8YnI+PGJyPlxuICogVGhlIHRyYW5zcG9ydCBlbWl0cyB0aGUgZXZlbnRzOiBcInN0YXJ0XCIsIFwic3RvcFwiLCBcInBhdXNlXCIsIGFuZCBcImxvb3BcIiB3aGljaCBhcmVcbiAqIGNhbGxlZCB3aXRoIHRoZSB0aW1lIG9mIHRoYXQgZXZlbnQgYXMgdGhlIGFyZ3VtZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcmVwZWF0ZWQgZXZlbnQgZXZlcnkgOHRoIG5vdGVcbiAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlUmVwZWF0KCh0aW1lKSA9PiB7XG4gKiBcdC8vIHVzZSB0aGUgY2FsbGJhY2sgdGltZSB0byBzY2hlZHVsZSBldmVudHNcbiAqIFx0b3NjLnN0YXJ0KHRpbWUpLnN0b3AodGltZSArIDAuMSk7XG4gKiB9LCBcIjhuXCIpO1xuICogLy8gdHJhbnNwb3J0IG11c3QgYmUgc3RhcnRlZCBiZWZvcmUgaXQgc3RhcnRzIGludm9raW5nIGV2ZW50c1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFuc3BvcnQgZXh0ZW5kcyBUb25lV2l0aENvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUcmFuc3BvcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJhbnNwb3J0XCI7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdExPT1BJTkdcbiAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgdHJhbnNwb3J0IGxvb3BzIG9yIG5vdC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2xvb3AgPSBuZXcgVGltZWxpbmVWYWx1ZShmYWxzZSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbG9vcCBzdGFydCBwb3NpdGlvbiBpbiB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBsb29wIGVuZCBwb3NpdGlvbiBpbiB0aWNrc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IDA7XG4gICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICAvLyBcdFRJTUVMSU5FIEVWRU5UU1xuICAgICAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFsbCB0aGUgZXZlbnRzIGluIGFuIG9iamVjdCB0byBrZWVwIHRyYWNrIGJ5IElEXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSB7fTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBzY2hlZHVsZWQgZXZlbnRzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fdGltZWxpbmUgPSBuZXcgVGltZWxpbmUoKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlcGVhdGVkIGV2ZW50c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcmVwZWF0ZWRFdmVudHMgPSBuZXcgSW50ZXJ2YWxUaW1lbGluZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogQWxsIG9mIHRoZSBzeW5jZWQgU2lnbmFsc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN3aW5nIGFtb3VudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3dpbmdBbW91bnQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJhbnNwb3J0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIC8vIENMT0NLL1RFTVBPXG4gICAgICAgIHRoaXMuX3BwcSA9IG9wdGlvbnMucHBxO1xuICAgICAgICB0aGlzLl9jbG9jayA9IG5ldyBDbG9jayh7XG4gICAgICAgICAgICBjYWxsYmFjazogdGhpcy5fcHJvY2Vzc1RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHVuaXRzOiBcImJwbVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmluZENsb2NrRXZlbnRzKCk7XG4gICAgICAgIHRoaXMuYnBtID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kubXVsdGlwbGllciA9IG9wdGlvbnMucHBxO1xuICAgICAgICB0aGlzLmJwbS5zZXRWYWx1ZUF0VGltZShvcHRpb25zLmJwbSwgMCk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwiYnBtXCIpO1xuICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gb3B0aW9ucy50aW1lU2lnbmF0dXJlO1xuICAgICAgICAvLyBTV0lOR1xuICAgICAgICB0aGlzLl9zd2luZ1RpY2tzID0gb3B0aW9ucy5wcHEgLyAyOyAvLyA4blxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVXaXRoQ29udGV4dC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBicG06IDEyMCxcbiAgICAgICAgICAgIGxvb3BFbmQ6IFwiNG1cIixcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIHBwcTogMTkyLFxuICAgICAgICAgICAgc3dpbmc6IDAsXG4gICAgICAgICAgICBzd2luZ1N1YmRpdmlzaW9uOiBcIjhuXCIsXG4gICAgICAgICAgICB0aW1lU2lnbmF0dXJlOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRUSUNLU1xuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIGNhbGxlZCBvbiBldmVyeSB0aWNrXG4gICAgICogQHBhcmFtICB0aWNrVGltZSBjbG9jayByZWxhdGl2ZSB0aWNrIHRpbWVcbiAgICAgKi9cbiAgICBfcHJvY2Vzc1RpY2sodGlja1RpbWUsIHRpY2tzKSB7XG4gICAgICAgIC8vIGRvIHRoZSBsb29wIHRlc3RcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AuZ2V0KHRpY2tUaW1lKSkge1xuICAgICAgICAgICAgaWYgKHRpY2tzID49IHRoaXMuX2xvb3BFbmQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wRW5kXCIsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0aGlzLl9sb29wU3RhcnQsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgICAgICB0aWNrcyA9IHRoaXMuX2xvb3BTdGFydDtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wU3RhcnRcIiwgdGlja1RpbWUsIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGlja1RpbWUpKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJsb29wXCIsIHRpY2tUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoYW5kbGUgc3dpbmdcbiAgICAgICAgaWYgKHRoaXMuX3N3aW5nQW1vdW50ID4gMCAmJlxuICAgICAgICAgICAgdGlja3MgJSB0aGlzLl9wcHEgIT09IDAgJiYgLy8gbm90IG9uIGEgZG93bmJlYXRcbiAgICAgICAgICAgIHRpY2tzICUgKHRoaXMuX3N3aW5nVGlja3MgKiAyKSAhPT0gMCkge1xuICAgICAgICAgICAgLy8gYWRkIHNvbWUgc3dpbmdcbiAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gKHRpY2tzICUgKHRoaXMuX3N3aW5nVGlja3MgKiAyKSkgLyAodGhpcy5fc3dpbmdUaWNrcyAqIDIpO1xuICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gTWF0aC5zaW4oKHByb2dyZXNzKSAqIE1hdGguUEkpICogdGhpcy5fc3dpbmdBbW91bnQ7XG4gICAgICAgICAgICB0aWNrVGltZSArPSBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N3aW5nVGlja3MgKiAyIC8gMykudG9TZWNvbmRzKCkgKiBhbW91bnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW52b2tlIHRoZSB0aW1lbGluZSBldmVudHMgc2NoZWR1bGVkIG9uIHRoaXMgdGlja1xuICAgICAgICB0aGlzLl90aW1lbGluZS5mb3JFYWNoQXRUaW1lKHRpY2tzLCBldmVudCA9PiBldmVudC5pbnZva2UodGlja1RpbWUpKTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gXHRTQ0hFRFVMQUJMRSBFVkVOVFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhbiBldmVudCBhbG9uZyB0aGUgdGltZWxpbmUuXG4gICAgICogQHBhcmFtIGNhbGxiYWNrIFRoZSBjYWxsYmFjayB0byBiZSBpbnZva2VkIGF0IHRoZSB0aW1lLlxuICAgICAqIEBwYXJhbSB0aW1lIFRoZSB0aW1lIHRvIGludm9rZSB0aGUgY2FsbGJhY2sgYXQuXG4gICAgICogQHJldHVybiBUaGUgaWQgb2YgdGhlIGV2ZW50IHdoaWNoIGNhbiBiZSB1c2VkIGZvciBjYW5jZWxpbmcgdGhlIGV2ZW50LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc2NoZWR1bGUgYW4gZXZlbnQgb24gdGhlIDE2dGggbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNjaGVkdWxlKCh0aW1lKSA9PiB7XG4gICAgICogXHQvLyBpbnZva2VkIG9uIG1lYXN1cmUgMTZcbiAgICAgKiBcdGNvbnNvbGUubG9nKFwibWVhc3VyZSAxNiFcIik7XG4gICAgICogfSwgXCIxNjowOjBcIik7XG4gICAgICovXG4gICAgc2NoZWR1bGUoY2FsbGJhY2ssIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSBuZXcgVHJhbnNwb3J0RXZlbnQodGhpcywge1xuICAgICAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNjaGVkdWxlIGEgcmVwZWF0ZWQgZXZlbnQgYWxvbmcgdGhlIHRpbWVsaW5lLiBUaGUgZXZlbnQgd2lsbCBmaXJlXG4gICAgICogYXQgdGhlIGBpbnRlcnZhbGAgc3RhcnRpbmcgYXQgdGhlIGBzdGFydFRpbWVgIGFuZCBmb3IgdGhlIHNwZWNpZmllZFxuICAgICAqIGBkdXJhdGlvbmAuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgIFRoZSBjYWxsYmFjayB0byBpbnZva2UuXG4gICAgICogQHBhcmFtICBpbnRlcnZhbCAgIFRoZSBkdXJhdGlvbiBiZXR3ZWVuIHN1Y2Nlc3NpdmUgY2FsbGJhY2tzLiBNdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyLlxuICAgICAqIEBwYXJhbSAgc3RhcnRUaW1lICBXaGVuIGFsb25nIHRoZSB0aW1lbGluZSB0aGUgZXZlbnRzIHNob3VsZCBzdGFydCBiZWluZyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIGV2ZW50IHNob3VsZCByZXBlYXQuXG4gICAgICogQHJldHVybiAgVGhlIElEIG9mIHRoZSBzY2hlZHVsZWQgZXZlbnQuIFVzZSB0aGlzIHRvIGNhbmNlbCB0aGUgZXZlbnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gYSBjYWxsYmFjayBpbnZva2VkIGV2ZXJ5IGVpZ2h0aCBub3RlIGFmdGVyIHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQoKHRpbWUpID0+IHtcbiAgICAgKiBcdG9zYy5zdGFydCh0aW1lKS5zdG9wKHRpbWUgKyAwLjEpO1xuICAgICAqIH0sIFwiOG5cIiwgXCIxbVwiKTtcbiAgICAgKi9cbiAgICBzY2hlZHVsZVJlcGVhdChjYWxsYmFjaywgaW50ZXJ2YWwsIHN0YXJ0VGltZSwgZHVyYXRpb24gPSBJbmZpbml0eSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRSZXBlYXRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIGR1cmF0aW9uOiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgZHVyYXRpb24pLnRvVGlja3MoKSxcbiAgICAgICAgICAgIGludGVydmFsOiBuZXcgVGltZUNsYXNzKHRoaXMuY29udGV4dCwgaW50ZXJ2YWwpLnRvVGlja3MoKSxcbiAgICAgICAgICAgIHRpbWU6IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvVGlja3MoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGtpY2sgaXQgb2ZmIGlmIHRoZSBUcmFuc3BvcnQgaXMgc3RhcnRlZFxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHJldHVybiB0aGlzLl9hZGRFdmVudChldmVudCwgdGhpcy5fcmVwZWF0ZWRFdmVudHMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSBhbiBldmVudCB0aGF0IHdpbGwgYmUgcmVtb3ZlZCBhZnRlciBpdCBpcyBpbnZva2VkLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIG9uY2UuXG4gICAgICogQHBhcmFtIHRpbWUgVGhlIHRpbWUgdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBpbnZva2VkLlxuICAgICAqIEByZXR1cm5zIFRoZSBJRCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50LlxuICAgICAqL1xuICAgIHNjaGVkdWxlT25jZShjYWxsYmFjaywgdGltZSkge1xuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBUcmFuc3BvcnRFdmVudCh0aGlzLCB7XG4gICAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICAgIG9uY2U6IHRydWUsXG4gICAgICAgICAgICB0aW1lOiBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZEV2ZW50KGV2ZW50LCB0aGlzLl90aW1lbGluZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFyIHRoZSBwYXNzZWQgaW4gZXZlbnQgaWQgZnJvbSB0aGUgdGltZWxpbmVcbiAgICAgKiBAcGFyYW0gZXZlbnRJZCBUaGUgaWQgb2YgdGhlIGV2ZW50LlxuICAgICAqL1xuICAgIGNsZWFyKGV2ZW50SWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NjaGVkdWxlZEV2ZW50cy5oYXNPd25Qcm9wZXJ0eShldmVudElkKSkge1xuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudElkLnRvU3RyaW5nKCldO1xuICAgICAgICAgICAgaXRlbS50aW1lbGluZS5yZW1vdmUoaXRlbS5ldmVudCk7XG4gICAgICAgICAgICBpdGVtLmV2ZW50LmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIGRlbGV0ZSB0aGlzLl9zY2hlZHVsZWRFdmVudHNbZXZlbnRJZC50b1N0cmluZygpXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGFuIGV2ZW50IHRvIHRoZSBjb3JyZWN0IHRpbWVsaW5lLiBLZWVwIHRyYWNrIG9mIHRoZVxuICAgICAqIHRpbWVsaW5lIGl0IHdhcyBhZGRlZCB0by5cbiAgICAgKiBAcmV0dXJucyB0aGUgZXZlbnQgaWQgd2hpY2ggd2FzIGp1c3QgYWRkZWRcbiAgICAgKi9cbiAgICBfYWRkRXZlbnQoZXZlbnQsIHRpbWVsaW5lKSB7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50c1tldmVudC5pZC50b1N0cmluZygpXSA9IHtcbiAgICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgICAgdGltZWxpbmUsXG4gICAgICAgIH07XG4gICAgICAgIHRpbWVsaW5lLmFkZChldmVudCk7XG4gICAgICAgIHJldHVybiBldmVudC5pZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHNjaGVkdWxlZCBldmVudHMgZnJvbSB0aGUgdGltZWxpbmUgYWZ0ZXJcbiAgICAgKiB0aGUgZ2l2ZW4gdGltZS4gUmVwZWF0ZWQgZXZlbnRzIHdpbGwgYmUgcmVtb3ZlZFxuICAgICAqIGlmIHRoZWlyIHN0YXJ0VGltZSBpcyBhZnRlciB0aGUgZ2l2ZW4gdGltZVxuICAgICAqIEBwYXJhbSBhZnRlciBDbGVhciBhbGwgZXZlbnRzIGFmdGVyIHRoaXMgdGltZS5cbiAgICAgKi9cbiAgICBjYW5jZWwoYWZ0ZXIgPSAwKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkQWZ0ZXIgPSB0aGlzLnRvVGlja3MoYWZ0ZXIpO1xuICAgICAgICB0aGlzLl90aW1lbGluZS5mb3JFYWNoRnJvbShjb21wdXRlZEFmdGVyLCBldmVudCA9PiB0aGlzLmNsZWFyKGV2ZW50LmlkKSk7XG4gICAgICAgIHRoaXMuX3JlcGVhdGVkRXZlbnRzLmZvckVhY2hGcm9tKGNvbXB1dGVkQWZ0ZXIsIGV2ZW50ID0+IHRoaXMuY2xlYXIoZXZlbnQuaWQpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U1RBUlQvU1RPUC9QQVVTRVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8qKlxuICAgICAqIEJpbmQgc3RhcnQvc3RvcC9wYXVzZSBldmVudHMgZnJvbSB0aGUgY2xvY2sgYW5kIGVtaXQgdGhlbS5cbiAgICAgKi9cbiAgICBfYmluZENsb2NrRXZlbnRzKCkge1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0YXJ0XCIsICh0aW1lLCBvZmZzZXQpID0+IHtcbiAgICAgICAgICAgIG9mZnNldCA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgb2Zmc2V0KS50b1NlY29uZHMoKTtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0YXJ0XCIsIHRpbWUsIG9mZnNldCk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInN0b3BcIiwgKHRpbWUpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdChcInN0b3BcIiwgdGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9jbG9jay5vbihcInBhdXNlXCIsICh0aW1lKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJwYXVzZVwiLCB0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIHBsYXliYWNrIHN0YXRlIG9mIHRoZSBzb3VyY2UsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIsIG9yIFwicGF1c2VkXCJcbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHRyYW5zcG9ydCBhbmQgYWxsIHNvdXJjZXMgc3luY2VkIHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQHBhcmFtICB0aW1lIFRoZSB0aW1lIHdoZW4gdGhlIHRyYW5zcG9ydCBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIHRpbWVsaW5lIG9mZnNldCB0byBzdGFydCB0aGUgdHJhbnNwb3J0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gc3RhcnQgdGhlIHRyYW5zcG9ydCBpbiBvbmUgc2Vjb25kIHN0YXJ0aW5nIGF0IGJlZ2lubmluZyBvZiB0aGUgNXRoIG1lYXN1cmUuXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoXCIrMVwiLCBcIjQ6MDowXCIpO1xuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUsIG9mZnNldCkge1xuICAgICAgICBsZXQgb2Zmc2V0VGlja3M7XG4gICAgICAgIGlmIChpc0RlZmluZWQob2Zmc2V0KSkge1xuICAgICAgICAgICAgb2Zmc2V0VGlja3MgPSB0aGlzLnRvVGlja3Mob2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzdGFydCB0aGUgY2xvY2tcbiAgICAgICAgdGhpcy5fY2xvY2suc3RhcnQodGltZSwgb2Zmc2V0VGlja3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB3aGVuIHRoZSB0cmFuc3BvcnQgc2hvdWxkIHN0b3AuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5zdG9wKCk7XG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgdHJhbnNwb3J0IGFuZCBhbGwgc291cmNlcyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICBwYXVzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLnBhdXNlKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVG9nZ2xlIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB0cmFuc3BvcnQuIElmIGl0IGlzXG4gICAgICogc3RhcnRlZCwgaXQgd2lsbCBzdG9wIGl0LCBvdGhlcndpc2UgaXQgd2lsbCBzdGFydCB0aGUgVHJhbnNwb3J0LlxuICAgICAqIEBwYXJhbSAgdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnRcbiAgICAgKi9cbiAgICB0b2dnbGUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9jbG9jay5nZXRTdGF0ZUF0VGltZSh0aW1lKSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnQodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AodGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFx0U0VUVEVSUy9HRVRURVJTXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgc2lnbmF0dXJlIGFzIGp1c3QgdGhlIG51bWVyYXRvciBvdmVyIDQuXG4gICAgICogRm9yIGV4YW1wbGUgNC80IHdvdWxkIGJlIGp1c3QgNCBhbmQgNi84IHdvdWxkIGJlIDMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBjb21tb24gdGltZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmUgPSA0O1xuICAgICAqIC8vIDcvOFxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnRpbWVTaWduYXR1cmUgPSBbNywgOF07XG4gICAgICogLy8gdGhpcyB3aWxsIGJlIHJlZHVjZWQgdG8gYSBzaW5nbGUgbnVtYmVyXG4gICAgICogVG9uZS5UcmFuc3BvcnQudGltZVNpZ25hdHVyZTsgLy8gcmV0dXJucyAzLjVcbiAgICAgKi9cbiAgICBnZXQgdGltZVNpZ25hdHVyZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RpbWVTaWduYXR1cmU7XG4gICAgfVxuICAgIHNldCB0aW1lU2lnbmF0dXJlKHRpbWVTaWcpIHtcbiAgICAgICAgaWYgKGlzQXJyYXkodGltZVNpZykpIHtcbiAgICAgICAgICAgIHRpbWVTaWcgPSAodGltZVNpZ1swXSAvIHRpbWVTaWdbMV0pICogNDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl90aW1lU2lnbmF0dXJlID0gdGltZVNpZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogV2hlbiB0aGUgVHJhbnNwb3J0Lmxvb3AgPSB0cnVlLCB0aGlzIGlzIHRoZSBzdGFydGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gbmV3IFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KHN0YXJ0UG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKHN0YXJ0UG9zaXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBUcmFuc3BvcnQubG9vcCA9IHRydWUsIHRoaXMgaXMgdGhlIGVuZGluZyBwb3NpdGlvbiBvZiB0aGUgbG9vcC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9sb29wRW5kLCBcImlcIikudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MoZW5kUG9zaXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgdHJhbnNwb3J0IGxvb3BzIG9yIG5vdC5cbiAgICAgKi9cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3AuZ2V0KHRoaXMubm93KCkpO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3Auc2V0KGxvb3AsIHRoaXMubm93KCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIHN0b3AgYXQgdGhlIHNhbWUgdGltZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIGxvb3Agb3ZlciB0aGUgZmlyc3QgbWVhc3VyZVxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnNldExvb3BQb2ludHMoMCwgXCIxbVwiKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5sb29wID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBzZXRMb29wUG9pbnRzKHN0YXJ0UG9zaXRpb24sIGVuZFBvc2l0aW9uKSB7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gc3RhcnRQb3NpdGlvbjtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gZW5kUG9zaXRpb247XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3dpbmcgdmFsdWUuIEJldHdlZW4gMC0xIHdoZXJlIDEgZXF1YWwgdG8gdGhlIG5vdGUgKyBoYWxmIHRoZSBzdWJkaXZpc2lvbi5cbiAgICAgKi9cbiAgICBnZXQgc3dpbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zd2luZ0Ftb3VudDtcbiAgICB9XG4gICAgc2V0IHN3aW5nKGFtb3VudCkge1xuICAgICAgICAvLyBzY2FsZSB0aGUgdmFsdWVzIHRvIGEgbm9ybWFsIHJhbmdlXG4gICAgICAgIHRoaXMuX3N3aW5nQW1vdW50ID0gYW1vdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIHN1YmRpdmlzaW9uIHdoaWNoIHRoZSBzd2luZyB3aWxsIGJlIGFwcGxpZWQgdG8uXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgaXMgYW4gOHRoIG5vdGUuIFZhbHVlIG11c3QgYmUgbGVzc1xuICAgICAqIHRoYW4gYSBxdWFydGVyIG5vdGUuXG4gICAgICovXG4gICAgZ2V0IHN3aW5nU3ViZGl2aXNpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N3aW5nVGlja3MpLnRvTm90YXRpb24oKTtcbiAgICB9XG4gICAgc2V0IHN3aW5nU3ViZGl2aXNpb24oc3ViZGl2aXNpb24pIHtcbiAgICAgICAgdGhpcy5fc3dpbmdUaWNrcyA9IHRoaXMudG9UaWNrcyhzdWJkaXZpc2lvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBCYXJzOkJlYXRzOlNpeHRlZW50aHMuXG4gICAgICogU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBqdW1wIHRvIHRoYXQgcG9zaXRpb24gcmlnaHQgYXdheS5cbiAgICAgKi9cbiAgICBnZXQgcG9zaXRpb24oKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IHRoaXMubm93KCk7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUobm93KTtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGlja3MpLnRvQmFyc0JlYXRzU2l4dGVlbnRocygpO1xuICAgIH1cbiAgICBzZXQgcG9zaXRpb24ocHJvZ3Jlc3MpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3MocHJvZ3Jlc3MpO1xuICAgICAgICB0aGlzLnRpY2tzID0gdGlja3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBUcmFuc3BvcnQncyBwb3NpdGlvbiBpbiBzZWNvbmRzXG4gICAgICogU2V0dGluZyB0aGUgdmFsdWUgd2lsbCBqdW1wIHRvIHRoYXQgcG9zaXRpb24gcmlnaHQgYXdheS5cbiAgICAgKi9cbiAgICBnZXQgc2Vjb25kcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLnNlY29uZHM7XG4gICAgfVxuICAgIHNldCBzZWNvbmRzKHMpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5mcmVxdWVuY3kudGltZVRvVGlja3Mocywgbm93KTtcbiAgICAgICAgdGhpcy50aWNrcyA9IHRpY2tzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgVHJhbnNwb3J0J3MgbG9vcCBwb3NpdGlvbiBhcyBhIG5vcm1hbGl6ZWQgdmFsdWUuIEFsd2F5c1xuICAgICAqIHJldHVybnMgMCBpZiB0aGUgdHJhbnNwb3J0IGlmIGxvb3AgaXMgbm90IHRydWUuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICBpZiAodGhpcy5sb29wKSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgcmV0dXJuICh0aWNrcyAtIHRoaXMuX2xvb3BTdGFydCkgLyAodGhpcy5fbG9vcEVuZCAtIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHJhbnNwb3J0cyBjdXJyZW50IHRpY2sgcG9zaXRpb24uXG4gICAgICovXG4gICAgZ2V0IHRpY2tzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2sudGlja3M7XG4gICAgfVxuICAgIHNldCB0aWNrcyh0KSB7XG4gICAgICAgIGlmICh0aGlzLl9jbG9jay50aWNrcyAhPT0gdCkge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIC8vIHN0b3AgZXZlcnl0aGluZyBzeW5jZWQgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLl9jbG9jay5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgICAgIC8vIHNjaGVkdWxlIHRvIHN0YXJ0IG9uIHRoZSBuZXh0IHRpY2ssICM1NzNcbiAgICAgICAgICAgICAgICBjb25zdCByZW1haW5pbmdUaWNrID0gdGhpcy5fY2xvY2suZnJlcXVlbmN5LmdldER1cmF0aW9uT2ZUaWNrcyhNYXRoLmNlaWwodGlja3MpIC0gdGlja3MsIG5vdyk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGltZSA9IG5vdyArIHJlbWFpbmluZ1RpY2s7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RvcFwiLCB0aW1lKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0LCB0aW1lKTtcbiAgICAgICAgICAgICAgICAvLyByZXN0YXJ0IGl0IHdpdGggdGhlIG5ldyB0aW1lXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwic3RhcnRcIiwgdGltZSwgdGhpcy5fY2xvY2suZ2V0U2Vjb25kc0F0VGltZSh0aW1lKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbG9jay5zZXRUaWNrc0F0VGltZSh0LCBub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY2xvY2sncyB0aWNrcyBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gZ2V0IHRoZSB0aWNrIHZhbHVlXG4gICAgICogQHJldHVybiBUaGUgdGljayB2YWx1ZSBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBnZXRUaWNrc0F0VGltZSh0aW1lKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKHRoaXMuX2Nsb2NrLmdldFRpY2tzQXRUaW1lKHRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSBlbGFwc2VkIHNlY29uZHMgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRvIGdldCB0aGUgZWxhcHNlZCBzZWNvbmRzXG4gICAgICogQHJldHVybiAgVGhlIG51bWJlciBvZiBlbGFwc2VkIHNlY29uZHNcbiAgICAgKi9cbiAgICBnZXRTZWNvbmRzQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLmdldFNlY29uZHNBdFRpbWUodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1bHNlcyBQZXIgUXVhcnRlciBub3RlLiBUaGlzIGlzIHRoZSBzbWFsbGVzdCByZXNvbHV0aW9uXG4gICAgICogdGhlIFRyYW5zcG9ydCB0aW1pbmcgc3VwcG9ydHMuIFRoaXMgc2hvdWxkIGJlIHNldCBvbmNlXG4gICAgICogb24gaW5pdGlhbGl6YXRpb24gYW5kIG5vdCBzZXQgYWdhaW4uIENoYW5naW5nIHRoaXMgdmFsdWVcbiAgICAgKiBhZnRlciBvdGhlciBvYmplY3RzIGhhdmUgYmVlbiBjcmVhdGVkIGNhbiBjYXVzZSBwcm9ibGVtcy5cbiAgICAgKi9cbiAgICBnZXQgUFBRKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvY2suZnJlcXVlbmN5Lm11bHRpcGxpZXI7XG4gICAgfVxuICAgIHNldCBQUFEocHBxKSB7XG4gICAgICAgIHRoaXMuX2Nsb2NrLmZyZXF1ZW5jeS5tdWx0aXBsaWVyID0gcHBxO1xuICAgIH1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBcdFNZTkNJTkdcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSB0aW1lIGFsaWduZWQgdG8gdGhlIG5leHQgc3ViZGl2aXNpb25cbiAgICAgKiBvZiB0aGUgVHJhbnNwb3J0LiBJZiB0aGUgVHJhbnNwb3J0IGlzIG5vdCBzdGFydGVkLFxuICAgICAqIGl0IHdpbGwgcmV0dXJuIDAuXG4gICAgICogTm90ZTogdGhpcyB3aWxsIG5vdCB3b3JrIHByZWNpc2VseSBkdXJpbmcgdGVtcG8gcmFtcHMuXG4gICAgICogQHBhcmFtICBzdWJkaXZpc2lvbiAgVGhlIHN1YmRpdmlzaW9uIHRvIHF1YW50aXplIHRvXG4gICAgICogQHJldHVybiAgVGhlIGNvbnRleHQgdGltZSBvZiB0aGUgbmV4dCBzdWJkaXZpc2lvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIHRoZSB0cmFuc3BvcnQgbXVzdCBiZSBzdGFydGVkLCBvdGhlcndpc2UgcmV0dXJucyAwXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKiBUb25lLlRyYW5zcG9ydC5uZXh0U3ViZGl2aXNpb24oXCI0blwiKTtcbiAgICAgKi9cbiAgICBuZXh0U3ViZGl2aXNpb24oc3ViZGl2aXNpb24pIHtcbiAgICAgICAgc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Moc3ViZGl2aXNpb24pO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIC8vIGlmIHRoZSB0cmFuc3BvcnQncyBub3Qgc3RhcnRlZCwgcmV0dXJuIDBcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIC8vIHRoZSByZW1haW5kZXIgb2YgdGhlIGN1cnJlbnQgdGlja3MgYW5kIHRoZSBzdWJkaXZpc2lvblxuICAgICAgICAgICAgY29uc3QgdHJhbnNwb3J0UG9zID0gdGhpcy5nZXRUaWNrc0F0VGltZShub3cpO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVGlja3MgPSBzdWJkaXZpc2lvbiAtIHRyYW5zcG9ydFBvcyAlIHN1YmRpdmlzaW9uO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2Nsb2NrLm5leHRUaWNrVGltZShyZW1haW5pbmdUaWNrcywgbm93KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBdHRhY2hlcyB0aGUgc2lnbmFsIHRvIHRoZSB0ZW1wbyBjb250cm9sIHNpZ25hbCBzbyB0aGF0XG4gICAgICogYW55IGNoYW5nZXMgaW4gdGhlIHRlbXBvIHdpbGwgY2hhbmdlIHRoZSBzaWduYWwgaW4gdGhlIHNhbWVcbiAgICAgKiByYXRpby5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzaWduYWxcbiAgICAgKiBAcGFyYW0gcmF0aW8gT3B0aW9uYWxseSBwYXNzIGluIHRoZSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gc2lnbmFscy5cbiAgICAgKiBcdFx0XHRPdGhlcndpc2UgaXQgd2lsbCBiZSBjb21wdXRlZCBiYXNlZCBvbiB0aGVpciBjdXJyZW50IHZhbHVlcy5cbiAgICAgKi9cbiAgICBzeW5jU2lnbmFsKHNpZ25hbCwgcmF0aW8pIHtcbiAgICAgICAgaWYgKCFyYXRpbykge1xuICAgICAgICAgICAgLy8gZ2V0IHRoZSBzeW5jIHJhdGlvXG4gICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgaWYgKHNpZ25hbC5nZXRWYWx1ZUF0VGltZShub3cpICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYnBtID0gdGhpcy5icG0uZ2V0VmFsdWVBdFRpbWUobm93KTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb21wdXRlZEZyZXEgPSAxIC8gKDYwIC8gYnBtIC8gdGhpcy5QUFEpO1xuICAgICAgICAgICAgICAgIHJhdGlvID0gc2lnbmFsLmdldFZhbHVlQXRUaW1lKG5vdykgLyBjb21wdXRlZEZyZXE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByYXRpbyA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmF0aW9TaWduYWwgPSBuZXcgR2FpbihyYXRpbyk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5icG0uY29ubmVjdChyYXRpb1NpZ25hbCk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgcmF0aW9TaWduYWwuY29ubmVjdChzaWduYWwuX3BhcmFtKTtcbiAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscy5wdXNoKHtcbiAgICAgICAgICAgIGluaXRpYWw6IHNpZ25hbC52YWx1ZSxcbiAgICAgICAgICAgIHJhdGlvOiByYXRpb1NpZ25hbCxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgfSk7XG4gICAgICAgIHNpZ25hbC52YWx1ZSA9IDA7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmNzIGEgcHJldmlvdXNseSBzeW5jZWQgc2lnbmFsIGZyb20gdGhlIHRyYW5zcG9ydCdzIGNvbnRyb2wuXG4gICAgICogU2VlIFRyYW5zcG9ydC5zeW5jU2lnbmFsLlxuICAgICAqL1xuICAgIHVuc3luY1NpZ25hbChzaWduYWwpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuX3N5bmNlZFNpZ25hbHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGNvbnN0IHN5bmNlZFNpZ25hbCA9IHRoaXMuX3N5bmNlZFNpZ25hbHNbaV07XG4gICAgICAgICAgICBpZiAoc3luY2VkU2lnbmFsLnNpZ25hbCA9PT0gc2lnbmFsKSB7XG4gICAgICAgICAgICAgICAgc3luY2VkU2lnbmFsLnJhdGlvLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgICAgICBzeW5jZWRTaWduYWwuc2lnbmFsLnZhbHVlID0gc3luY2VkU2lnbmFsLmluaXRpYWw7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3luY2VkU2lnbmFscy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZGlzcG9zZSgpO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBcImJwbVwiKTtcbiAgICAgICAgdGhpcy5fdGltZWxpbmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yZXBlYXRlZEV2ZW50cy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbkVtaXR0ZXIubWl4aW4oVHJhbnNwb3J0KTtcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gXHRJTklUSUFMSVpBVElPTlxuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5vbkNvbnRleHRJbml0KGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQudHJhbnNwb3J0ID0gbmV3IFRyYW5zcG9ydCh7IGNvbnRleHQgfSk7XG59KTtcbm9uQ29udGV4dENsb3NlKGNvbnRleHQgPT4ge1xuICAgIGNvbnRleHQudHJhbnNwb3J0LmRpc3Bvc2UoKTtcbn0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VHJhbnNwb3J0LmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCBcIi4uL2NvcmUvY29udGV4dC9EZXN0aW5hdGlvblwiO1xuaW1wb3J0IFwiLi4vY29yZS9jbG9jay9UcmFuc3BvcnRcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzVW5kZWYgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0LCBhc3NlcnRDb250ZXh0UnVubmluZyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IEdUIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHNvdXJjZXMuXG4gKiBzdGFydC9zdG9wIG9mIHRoaXMuY29udGV4dC50cmFuc3BvcnQuXG4gKlxuICogYGBgXG4gKiAvLyBNdWx0aXBsZSBzdGF0ZSBjaGFuZ2UgZXZlbnRzIGNhbiBiZSBjaGFpbmVkIHRvZ2V0aGVyLFxuICogLy8gYnV0IG11c3QgYmUgc2V0IGluIHRoZSBjb3JyZWN0IG9yZGVyIGFuZCB3aXRoIGFzY2VuZGluZyB0aW1lc1xuICogLy8gT0tcbiAqIHN0YXRlLnN0YXJ0KCkuc3RvcChcIiswLjJcIik7XG4gKiAvLyBPS1xuICogc3RhdGUuc3RhcnQoKS5zdG9wKFwiKzAuMlwiKS5zdGFydChcIiswLjRcIikuc3RvcChcIiswLjdcIilcbiAqIC8vIEJBRFxuICogc3RhdGUuc3RvcChcIiswLjJcIikuc3RhcnQoKTtcbiAqIC8vIEJBRFxuICogc3RhdGUuc3RhcnQoXCIrMC4zXCIpLnN0b3AoXCIrMC4yXCIpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTb3VyY2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICAvKipcbiAgICAgICAgICogU291cmNlcyBoYXZlIG5vIGlucHV0c1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgdGhlIHNjaGVkdWxlZCBzdGF0ZS5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHN5bmNlZCBgc3RhcnRgIGNhbGxiYWNrIGZ1bmN0aW9uIGZyb20gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBLZWVwIHRyYWNrIG9mIGFsbCBvZiB0aGUgc2NoZWR1bGVkIGV2ZW50IGlkc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQbGFjZWhvbGRlciBmdW5jdGlvbnMgZm9yIHN5bmNpbmcvdW5zeW5jaW5nIHRvIHRyYW5zcG9ydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQgPSBub09wO1xuICAgICAgICB0aGlzLl9zeW5jZWRTdG9wID0gbm9PcDtcbiAgICAgICAgdGhpcy5fc3RhdGUubWVtb3J5ID0gMTAwO1xuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG11dGU6IG9wdGlvbnMubXV0ZSxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFwidm9sdW1lXCIpO1xuICAgICAgICB0aGlzLm9uc3RvcCA9IG9wdGlvbnMub25zdG9wO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBvbnN0b3A6IG5vT3AsXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9haG50b25lX2MzLm1wM1wiLCAoKSA9PiB7XG4gICAgICogXHRwbGF5ZXIuc3RhcnQoKTtcbiAgICAgKiBcdGNvbnNvbGUubG9nKHBsYXllci5zdGF0ZSk7XG4gICAgICogfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZSB0aGUgb3V0cHV0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIG9zYy5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRW5zdXJlIHRoYXQgdGhlIHNjaGVkdWxlZCB0aW1lIGlzIG5vdCBiZWZvcmUgdGhlIGN1cnJlbnQgdGltZS5cbiAgICAgKiBTaG91bGQgb25seSBiZSB1c2VkIHdoZW4gc2NoZWR1bGVkIHVuc3luY2VkLlxuICAgICAqL1xuICAgIF9jbGFtcFRvQ3VycmVudFRpbWUodGltZSkge1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGltZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBNYXRoLm1heCh0aW1lLCB0aGlzLmNvbnRleHQuY3VycmVudFRpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBzb3VyY2UgYXQgdGhlIHNwZWNpZmllZCB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLFxuICAgICAqIHN0YXJ0IHRoZSBzb3VyY2Ugbm93LlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBzb3VyY2Ugc2hvdWxkIGJlIHN0YXJ0ZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHNvdXJjZS5zdGFydChcIiswLjVcIik7IC8vIHN0YXJ0cyB0aGUgc291cmNlIDAuNSBzZWNvbmRzIGZyb20gbm93XG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBsZXQgY29tcHV0ZWRUaW1lID0gaXNVbmRlZih0aW1lKSAmJiB0aGlzLl9zeW5jZWQgPyB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMgOiB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29tcHV0ZWRUaW1lID0gdGhpcy5fY2xhbXBUb0N1cnJlbnRUaW1lKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIC8vIGlmIGl0J3Mgc3RhcnRlZCwgc3RvcCBpdCBhbmQgcmVzdGFydCBpdFxuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCAmJiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gdGltZSBzaG91bGQgYmUgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHRoZSBwcmV2aW91cyBzdGFydCB0aW1lXG4gICAgICAgICAgICBhc3NlcnQoR1QoY29tcHV0ZWRUaW1lLCB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKS50aW1lKSwgXCJTdGFydCB0aW1lIG11c3QgYmUgc3RyaWN0bHkgZ3JlYXRlciB0aGFuIHByZXZpb3VzIHN0YXJ0IHRpbWVcIik7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5sb2coXCJyZXN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB0aGlzLnJlc3RhcnQoY29tcHV0ZWRUaW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RhcnRlZFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgICAgIC8vIGFkZCB0aGUgb2Zmc2V0IHRpbWUgdG8gdGhlIGV2ZW50XG4gICAgICAgICAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLl9zdGF0ZS5nZXQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQub2Zmc2V0ID0gdGhpcy50b1NlY29uZHMoZGVmYXVsdEFyZyhvZmZzZXQsIDApKTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZHVyYXRpb24gPSBkdXJhdGlvbiA/IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKHQgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0LCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZC5wdXNoKHNjaGVkKTtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgdHJhbnNwb3J0IGlzIGFscmVhZHkgc3RhcnRlZFxuICAgICAgICAgICAgICAgIC8vIGFuZCB0aGUgdGltZSBpcyBncmVhdGVyIHRoYW4gd2hlcmUgdGhlIHRyYW5zcG9ydCBpc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN0YXRlID09PSBcInN0YXJ0ZWRcIiAmJlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFNlY29uZHNBdFRpbWUodGhpcy5pbW1lZGlhdGUoKSkgPiBjb21wdXRlZFRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQodGhpcy5ub3coKSwgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRDb250ZXh0UnVubmluZyh0aGlzLmNvbnRleHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0KGNvbXB1dGVkVGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHNvdXJjZSBhdCB0aGUgc3BlY2lmaWVkIHRpbWUuIElmIG5vIHRpbWUgaXMgZ2l2ZW4sXG4gICAgICogc3RvcCB0aGUgc291cmNlIG5vdy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgc291cmNlIHNob3VsZCBiZSBzdG9wcGVkLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc291cmNlID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzb3VyY2Uuc3RhcnQoKTtcbiAgICAgKiBzb3VyY2Uuc3RvcChcIiswLjVcIik7IC8vIHN0b3BzIHRoZSBzb3VyY2UgMC41IHNlY29uZHMgZnJvbSBub3dcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgbGV0IGNvbXB1dGVkVGltZSA9IGlzVW5kZWYodGltZSkgJiYgdGhpcy5fc3luY2VkID8gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zZWNvbmRzIDogdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbXB1dGVkVGltZSA9IHRoaXMuX2NsYW1wVG9DdXJyZW50VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIgfHwgaXNEZWZpbmVkKHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0YXJ0ZWRcIiwgY29tcHV0ZWRUaW1lKSkpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKFwic3RvcFwiLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wKGNvbXB1dGVkVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUodGhpcy5fc3RvcC5iaW5kKHRoaXMpLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlZC5wdXNoKHNjaGVkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbChjb21wdXRlZFRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlc3RhcnQgdGhlIHNvdXJjZS5cbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGltZSkgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGltZSk7XG4gICAgICAgICAgICB0aGlzLl9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTeW5jIHRoZSBzb3VyY2UgdG8gdGhlIFRyYW5zcG9ydCBzbyB0aGF0IGFsbCBzdWJzZXF1ZW50XG4gICAgICogY2FsbHMgdG8gYHN0YXJ0YCBhbmQgYHN0b3BgIGFyZSBzeW5jZWQgdG8gdGhlIFRyYW5zcG9ydFRpbWVcbiAgICAgKiBpbnN0ZWFkIG9mIHRoZSBBdWRpb0NvbnRleHQgdGltZS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBzeW5jIHRoZSBzb3VyY2Ugc28gdGhhdCBpdCBwbGF5cyBiZXR3ZWVuIDAgYW5kIDAuMyBvbiB0aGUgVHJhbnNwb3J0J3MgdGltZWxpbmVcbiAgICAgKiBvc2Muc3luYygpLnN0YXJ0KDApLnN0b3AoMC4zKTtcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0LlxuICAgICAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gICAgICogLy8gc2V0IGl0IHRvIGxvb3Agb25jZSBhIHNlY29uZFxuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3AgPSB0cnVlO1xuICAgICAqIFRvbmUuVHJhbnNwb3J0Lmxvb3BFbmQgPSAxO1xuICAgICAqL1xuICAgIHN5bmMoKSB7XG4gICAgICAgIGlmICghdGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkU3RhcnQgPSAodGltZSwgb2Zmc2V0KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG9mZnNldCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gZ2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBhdCB0aGF0IHRpbWVcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhdGVFdmVudCA9IHRoaXMuX3N0YXRlLmdldChvZmZzZXQpO1xuICAgICAgICAgICAgICAgICAgICAvLyBsaXN0ZW4gZm9yIHN0YXJ0IGV2ZW50cyB3aGljaCBtYXkgb2NjdXIgaW4gdGhlIG1pZGRsZSBvZiB0aGUgc3luYydlZCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50ICYmIHN0YXRlRXZlbnQuc3RhdGUgPT09IFwic3RhcnRlZFwiICYmIHN0YXRlRXZlbnQudGltZSAhPT0gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIG9mZnNldFxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRPZmZzZXQgPSBvZmZzZXQgLSB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50LnRpbWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGR1cmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlRXZlbnQuZHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHN0YXRlRXZlbnQuZHVyYXRpb24pIC0gc3RhcnRPZmZzZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9zdGFydCh0aW1lLCB0aGlzLnRvU2Vjb25kcyhzdGF0ZUV2ZW50Lm9mZnNldCkgKyBzdGFydE9mZnNldCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNlZFN0b3AgPSB0aW1lID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWNvbmRzID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5nZXRTZWNvbmRzQXRUaW1lKE1hdGgubWF4KHRpbWUgLSB0aGlzLnNhbXBsZVRpbWUsIDApKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoc2Vjb25kcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRTdGFydCk7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9uKFwibG9vcFN0YXJ0XCIsIHRoaXMuX3N5bmNlZFN0YXJ0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub24oXCJzdG9wXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcImxvb3BFbmRcIiwgdGhpcy5fc3luY2VkU3RvcCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgc291cmNlIHRvIHRoZSBUcmFuc3BvcnQuIFNlZSBTb3VyY2Uuc3luY1xuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdG9wXCIsIHRoaXMuX3N5bmNlZFN0b3ApO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJwYXVzZVwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwibG9vcEVuZFwiLCB0aGlzLl9zeW5jZWRTdG9wKTtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwic3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJsb29wU3RhcnRcIiwgdGhpcy5fc3luY2VkU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICAvLyBjbGVhciBhbGwgb2YgdGhlIHNjaGVkdWxlZCBpZHNcbiAgICAgICAgdGhpcy5fc2NoZWR1bGVkLmZvckVhY2goaWQgPT4gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5jbGVhcihpZCkpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWQgPSBbXTtcbiAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKDApO1xuICAgICAgICAvLyBzdG9wIGl0IGFsc29cbiAgICAgICAgdGhpcy5fc3RvcCgwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vbnN0b3AgPSBub09wO1xuICAgICAgICB0aGlzLnVuc3luYygpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBQYXJhbSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvUGFyYW1cIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyXCI7XG5pbXBvcnQgeyBkZWZhdWx0QXJnLCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IE9uZVNob3RTb3VyY2UgfSBmcm9tIFwiLi4vT25lU2hvdFNvdXJjZVwiO1xuaW1wb3J0IHsgRVEsIEdURSwgTFQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL01hdGhcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBCdWZmZXJTb3VyY2VOb2RlLlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZUJ1ZmZlclNvdXJjZSBleHRlbmRzIE9uZVNob3RTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhUb25lQnVmZmVyU291cmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVG9uZUJ1ZmZlclNvdXJjZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHRoaXMuY29udGV4dC5jcmVhdGVCdWZmZXJTb3VyY2UoKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9zb3VyY2VdO1xuICAgICAgICAvKipcbiAgICAgICAgICogaW5kaWNhdG9ycyBpZiB0aGUgc291cmNlIGhhcyBzdGFydGVkL3N0b3BwZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3NvdXJjZVN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fc291cmNlU3RvcHBlZCA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUJ1ZmZlclNvdXJjZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybFwiLCBcIm9ubG9hZFwiXSk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc291cmNlLCB0aGlzLl9nYWluTm9kZSk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5vbmVuZGVkID0gKCkgPT4gdGhpcy5fc3RvcFNvdXJjZSgpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBsYXliYWNrUmF0ZSBvZiB0aGUgYnVmZmVyXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wbGF5YmFja1JhdGUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzZXQgc29tZSB2YWx1ZXMgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubG9vcCA9IG9wdGlvbnMubG9vcDtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5sb29wRW5kID0gb3B0aW9ucy5sb29wRW5kO1xuICAgICAgICB0aGlzLl9idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKG9wdGlvbnMudXJsLCBvcHRpb25zLm9ubG9hZCwgb3B0aW9ucy5vbmVycm9yKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscy5wdXNoKHRoaXMuX3NvdXJjZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT25lU2hvdFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB1cmw6IG5ldyBUb25lQXVkaW9CdWZmZXIoKSxcbiAgICAgICAgICAgIGxvb3A6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcEVuZDogMCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogMCxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgICAgIG9uZXJyb3I6IG5vT3AsXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKHQpIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgYW1wbGl0dWRlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCBmYWRlT3V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZU91dDtcbiAgICB9XG4gICAgc2V0IGZhZGVPdXQodCkge1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gdDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnZlIGFwcGxpZWQgdG8gdGhlIGZhZGVzLCBlaXRoZXIgXCJsaW5lYXJcIiBvciBcImV4cG9uZW50aWFsXCJcbiAgICAgKi9cbiAgICBnZXQgY3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGN1cnZlKHQpIHtcbiAgICAgICAgdGhpcy5fY3VydmUgPSB0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgYnVmZmVyXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLCBpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICogQHBhcmFtICBnYWluICBUaGUgZ2FpbiB0byBwbGF5IHRoZSBidWZmZXIgYmFjayBhdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uLCBnYWluID0gMSkge1xuICAgICAgICBhc3NlcnQodGhpcy5idWZmZXIubG9hZGVkLCBcImJ1ZmZlciBpcyBlaXRoZXIgbm90IHNldCBvciBub3QgbG9hZGVkXCIpO1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgLy8gYXBwbHkgdGhlIGdhaW4gZW52ZWxvcGVcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSwgZ2Fpbik7XG4gICAgICAgIC8vIGlmIGl0J3MgYSBsb29wIHRoZSBkZWZhdWx0IG9mZnNldCBpcyB0aGUgbG9vcHN0YXJ0IHBvaW50XG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLmxvb3BTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIDBcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIG9mZnNldCBpcyBub3QgbGVzcyB0aGFuIDBcbiAgICAgICAgbGV0IGNvbXB1dGVkT2Zmc2V0ID0gTWF0aC5tYXgodGhpcy50b1NlY29uZHMob2Zmc2V0KSwgMCk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBidWZmZXIgc291cmNlXG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIC8vIG1vZGlmeSB0aGUgb2Zmc2V0IGlmIGl0J3MgZ3JlYXRlciB0aGFuIHRoZSBsb29wIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BFbmQpIHx8IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICAgICAgY29uc3QgbG9vcFN0YXJ0ID0gdGhpcy50b1NlY29uZHModGhpcy5sb29wU3RhcnQpO1xuICAgICAgICAgICAgY29uc3QgbG9vcER1cmF0aW9uID0gbG9vcEVuZCAtIGxvb3BTdGFydDtcbiAgICAgICAgICAgIC8vIG1vdmUgdGhlIG9mZnNldCBiYWNrXG4gICAgICAgICAgICBpZiAoR1RFKGNvbXB1dGVkT2Zmc2V0LCBsb29wRW5kKSkge1xuICAgICAgICAgICAgICAgIGNvbXB1dGVkT2Zmc2V0ID0gKChjb21wdXRlZE9mZnNldCAtIGxvb3BTdGFydCkgJSBsb29wRHVyYXRpb24pICsgbG9vcFN0YXJ0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gd2hlbiB0aGUgb2Zmc2V0IGlzIHZlcnkgY2xvc2UgdG8gdGhlIGR1cmF0aW9uLCBzZXQgaXQgdG8gMFxuICAgICAgICAgICAgaWYgKEVRKGNvbXB1dGVkT2Zmc2V0LCB0aGlzLmJ1ZmZlci5kdXJhdGlvbikpIHtcbiAgICAgICAgICAgICAgICBjb21wdXRlZE9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhpcy5idWZmZXIubG9hZGVkIHdvdWxkIGhhdmUgcmV0dXJuIGZhbHNlIGlmIHRoZSBBdWRpb0J1ZmZlciB3YXMgdW5kZWZpbmVkXG4gICAgICAgIHRoaXMuX3NvdXJjZS5idWZmZXIgPSB0aGlzLmJ1ZmZlci5nZXQoKTtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BFbmQgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmxvb3BFbmQpIHx8IHRoaXMuYnVmZmVyLmR1cmF0aW9uO1xuICAgICAgICBpZiAoTFQoY29tcHV0ZWRPZmZzZXQsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlU3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2Uuc3RhcnQoY29tcHV0ZWRUaW1lLCBjb21wdXRlZE9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgYSBkdXJhdGlvbiBpcyBnaXZlbiwgc2NoZWR1bGUgYSBzdG9wXG4gICAgICAgIGlmIChpc0RlZmluZWQoZHVyYXRpb24pKSB7XG4gICAgICAgICAgICBsZXQgY29tcHV0ZWREdXIgPSB0aGlzLnRvU2Vjb25kcyhkdXJhdGlvbik7XG4gICAgICAgICAgICAvLyBtYWtlIHN1cmUgaXQncyBuZXZlciBuZWdhdGl2ZVxuICAgICAgICAgICAgY29tcHV0ZWREdXIgPSBNYXRoLm1heChjb21wdXRlZER1ciwgMCk7XG4gICAgICAgICAgICB0aGlzLnN0b3AoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfc3RvcFNvdXJjZSh0aW1lKSB7XG4gICAgICAgIGlmICghdGhpcy5fc291cmNlU3RvcHBlZCAmJiB0aGlzLl9zb3VyY2VTdGFydGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuX3NvdXJjZS5zdG9wKHRoaXMudG9TZWNvbmRzKHRpbWUpKTtcbiAgICAgICAgICAgIHRoaXMuX29uZW5kZWQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3BTdGFydCA9IHRoaXMudG9TZWNvbmRzKGxvb3BTdGFydCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZS5sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5sb29wRW5kID0gdGhpcy50b1NlY29uZHMobG9vcEVuZCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgYmVsb25naW5nIHRvIHRoZSBwbGF5ZXIuXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlLmxvb3A7XG4gICAgfVxuICAgIHNldCBsb29wKGxvb3ApIHtcbiAgICAgICAgdGhpcy5fc291cmNlLmxvb3AgPSBsb29wO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlU3RhcnRlZCkge1xuICAgICAgICAgICAgdGhpcy5jYW5jZWxTdG9wKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zb3VyY2Uub25lbmRlZCA9IG51bGw7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUJ1ZmZlclNvdXJjZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG4vKipcbiAqIE5vaXNlIGlzIGEgbm9pc2UgZ2VuZXJhdG9yLiBJdCB1c2VzIGxvb3BlZCBub2lzZSBidWZmZXJzIHRvIHNhdmUgb24gcGVyZm9ybWFuY2UuXG4gKiBOb2lzZSBzdXBwb3J0cyB0aGUgbm9pc2UgdHlwZXM6IFwicGlua1wiLCBcIndoaXRlXCIsIGFuZCBcImJyb3duXCIuIFJlYWQgbW9yZSBhYm91dFxuICogY29sb3JzIG9mIG5vaXNlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvbG9yc19vZl9ub2lzZSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGluaXRpYWxpemUgdGhlIG5vaXNlIGFuZCBzdGFydFxuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZShcInBpbmtcIikuc3RhcnQoKTtcbiAqIC8vIG1ha2UgYW4gYXV0b2ZpbHRlciB0byBzaGFwZSB0aGUgbm9pc2VcbiAqIGNvbnN0IGF1dG9GaWx0ZXIgPSBuZXcgVG9uZS5BdXRvRmlsdGVyKHtcbiAqIFx0ZnJlcXVlbmN5OiBcIjhuXCIsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IDIwMCxcbiAqIFx0b2N0YXZlczogOFxuICogfSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBjb25uZWN0IHRoZSBub2lzZVxuICogbm9pc2UuY29ubmVjdChhdXRvRmlsdGVyKTtcbiAqIC8vIHN0YXJ0IHRoZSBhdXRvZmlsdGVyIExGT1xuICogYXV0b0ZpbHRlci5zdGFydCgpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgTm9pc2UgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOb2lzZVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogUHJpdmF0ZSByZWZlcmVuY2UgdG8gdGhlIHNvdXJjZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiXSk7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IG9wdGlvbnMuZmFkZUluO1xuICAgICAgICB0aGlzLl9mYWRlT3V0ID0gb3B0aW9ucy5mYWRlT3V0O1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgdHlwZTogXCJ3aGl0ZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG5vaXNlLiBDYW4gYmUgXCJ3aGl0ZVwiLCBcImJyb3duXCIsIG9yIFwicGlua1wiLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG5vaXNlLnR5cGUgPSBcImJyb3duXCI7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGFzc2VydCh0eXBlIGluIF9ub2lzZUJ1ZmZlcnMsIFwiTm9pc2U6IGludmFsaWQgdHlwZTogXCIgKyB0eXBlKTtcbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBwbGF5aW5nLCBzdG9wIGFuZCByZXN0YXJ0IGl0XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0b3Aobm93KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGFydChub3cpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub2lzZS4gQWZmZWN0c1xuICAgICAqIHRoZSBcImZyZXF1ZW5jeVwiIG9mIHRoZSBub2lzZS5cbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnBsYXliYWNrUmF0ZS52YWx1ZSA9IHJhdGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogaW50ZXJuYWwgc3RhcnQgbWV0aG9kXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgYnVmZmVyID0gX25vaXNlQnVmZmVyc1t0aGlzLl90eXBlXTtcbiAgICAgICAgdGhpcy5fc291cmNlID0gbmV3IFRvbmVCdWZmZXJTb3VyY2Uoe1xuICAgICAgICAgICAgdXJsOiBidWZmZXIsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmYWRlSW46IHRoaXMuX2ZhZGVJbixcbiAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX2ZhZGVPdXQsXG4gICAgICAgICAgICBsb29wOiB0cnVlLFxuICAgICAgICAgICAgb25lbmRlZDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwbGF5YmFja1JhdGU6IHRoaXMuX3BsYXliYWNrUmF0ZSxcbiAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMuX3NvdXJjZS5zdGFydCh0aGlzLnRvU2Vjb25kcyh0aW1lKSwgTWF0aC5yYW5kb20oKSAqIChidWZmZXIuZHVyYXRpb24gLSAwLjAwMSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBpbnRlcm5hbCBzdG9wIG1ldGhvZFxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLnN0b3AodGhpcy50b1NlY29uZHModGltZSkpO1xuICAgICAgICAgICAgdGhpcy5fc291cmNlID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZUluIHRpbWUgb2YgdGhlIGFtcGxpdHVkZSBlbnZlbG9wZS5cbiAgICAgKi9cbiAgICBnZXQgZmFkZUluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmFkZUluO1xuICAgIH1cbiAgICBzZXQgZmFkZUluKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gdGltZTtcbiAgICAgICAgaWYgKHRoaXMuX3NvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5fc291cmNlLmZhZGVJbiA9IHRoaXMuX2ZhZGVJbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZmFkZU91dCB0aW1lIG9mIHRoZSBhbXBsaXR1ZGUgZW52ZWxvcGUuXG4gICAgICovXG4gICAgZ2V0IGZhZGVPdXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlT3V0O1xuICAgIH1cbiAgICBzZXQgZmFkZU91dCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSB0aW1lO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZmFkZU91dCA9IHRoaXMuX2ZhZGVPdXQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICAvLyBUT0RPIGNvdWxkIGJlIG9wdGltaXplZCBieSBjYW5jZWxsaW5nIHRoZSBidWZmZXIgc291cmNlICdzdG9wJ1xuICAgICAgICB0aGlzLl9zdG9wKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRIRSBOT0lTRSBCVUZGRVJTXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBOb2lzZSBidWZmZXIgc3RhdHNcbmNvbnN0IEJVRkZFUl9MRU5HVEggPSA0NDEwMCAqIDU7XG5jb25zdCBOVU1fQ0hBTk5FTFMgPSAyO1xuLyoqXG4gKiBDYWNoZSB0aGUgbm9pc2UgYnVmZmVyc1xuICovXG5jb25zdCBfbm9pc2VDYWNoZSA9IHtcbiAgICBicm93bjogbnVsbCxcbiAgICBwaW5rOiBudWxsLFxuICAgIHdoaXRlOiBudWxsLFxufTtcbi8qKlxuICogVGhlIG5vaXNlIGFycmF5cy4gR2VuZXJhdGVkIG9uIGluaXRpYWxpemF0aW9uLlxuICogYm9ycm93ZWQgaGVhdmlseSBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS96YWNoYXJ5ZGVudG9uL25vaXNlLmpzXG4gKiAoYykgMjAxMyBaYWNoIERlbnRvbiAoTUlUKVxuICovXG5jb25zdCBfbm9pc2VCdWZmZXJzID0ge1xuICAgIGdldCBicm93bigpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS5icm93bikge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBsZXQgbGFzdE91dCA9IDAuMDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB3aGl0ZSA9IE1hdGgucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSA9IChsYXN0T3V0ICsgKDAuMDIgKiB3aGl0ZSkpIC8gMS4wMjtcbiAgICAgICAgICAgICAgICAgICAgbGFzdE91dCA9IGNoYW5uZWxbaV07XG4gICAgICAgICAgICAgICAgICAgIGNoYW5uZWxbaV0gKj0gMy41OyAvLyAocm91Z2hseSkgY29tcGVuc2F0ZSBmb3IgZ2FpblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLmJyb3duID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS5icm93bjtcbiAgICB9LFxuICAgIGdldCBwaW5rKCkge1xuICAgICAgICBpZiAoIV9ub2lzZUNhY2hlLnBpbmspIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2hhbm5lbE51bSA9IDA7IGNoYW5uZWxOdW0gPCBOVU1fQ0hBTk5FTFM7IGNoYW5uZWxOdW0rKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgRmxvYXQzMkFycmF5KEJVRkZFUl9MRU5HVEgpO1xuICAgICAgICAgICAgICAgIGJ1ZmZlcltjaGFubmVsTnVtXSA9IGNoYW5uZWw7XG4gICAgICAgICAgICAgICAgbGV0IGIwLCBiMSwgYjIsIGIzLCBiNCwgYjUsIGI2O1xuICAgICAgICAgICAgICAgIGIwID0gYjEgPSBiMiA9IGIzID0gYjQgPSBiNSA9IGI2ID0gMC4wO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgQlVGRkVSX0xFTkdUSDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdoaXRlID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgICAgICBiMCA9IDAuOTk4ODYgKiBiMCArIHdoaXRlICogMC4wNTU1MTc5O1xuICAgICAgICAgICAgICAgICAgICBiMSA9IDAuOTkzMzIgKiBiMSArIHdoaXRlICogMC4wNzUwNzU5O1xuICAgICAgICAgICAgICAgICAgICBiMiA9IDAuOTY5MDAgKiBiMiArIHdoaXRlICogMC4xNTM4NTIwO1xuICAgICAgICAgICAgICAgICAgICBiMyA9IDAuODY2NTAgKiBiMyArIHdoaXRlICogMC4zMTA0ODU2O1xuICAgICAgICAgICAgICAgICAgICBiNCA9IDAuNTUwMDAgKiBiNCArIHdoaXRlICogMC41MzI5NTIyO1xuICAgICAgICAgICAgICAgICAgICBiNSA9IC0wLjc2MTYgKiBiNSAtIHdoaXRlICogMC4wMTY4OTgwO1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gYjAgKyBiMSArIGIyICsgYjMgKyBiNCArIGI1ICsgYjYgKyB3aGl0ZSAqIDAuNTM2MjtcbiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbFtpXSAqPSAwLjExOyAvLyAocm91Z2hseSkgY29tcGVuc2F0ZSBmb3IgZ2FpblxuICAgICAgICAgICAgICAgICAgICBiNiA9IHdoaXRlICogMC4xMTU5MjY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgX25vaXNlQ2FjaGUucGluayA9IG5ldyBUb25lQXVkaW9CdWZmZXIoKS5mcm9tQXJyYXkoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gX25vaXNlQ2FjaGUucGluaztcbiAgICB9LFxuICAgIGdldCB3aGl0ZSgpIHtcbiAgICAgICAgaWYgKCFfbm9pc2VDYWNoZS53aGl0ZSkge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjaGFubmVsTnVtID0gMDsgY2hhbm5lbE51bSA8IE5VTV9DSEFOTkVMUzsgY2hhbm5lbE51bSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbCA9IG5ldyBGbG9hdDMyQXJyYXkoQlVGRkVSX0xFTkdUSCk7XG4gICAgICAgICAgICAgICAgYnVmZmVyW2NoYW5uZWxOdW1dID0gY2hhbm5lbDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IEJVRkZFUl9MRU5HVEg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBjaGFubmVsW2ldID0gTWF0aC5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF9ub2lzZUNhY2hlLndoaXRlID0gbmV3IFRvbmVBdWRpb0J1ZmZlcigpLmZyb21BcnJheShidWZmZXIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBfbm9pc2VDYWNoZS53aGl0ZTtcbiAgICB9LFxufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5vaXNlLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgY29ubmVjdCwgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc0RlZmluZWQsIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVXNlck1lZGlhIHVzZXMgTWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSB0byBvcGVuIHVwIGFuZCBleHRlcm5hbCBtaWNyb3Bob25lIG9yIGF1ZGlvIGlucHV0LlxuICogQ2hlY2sgW01lZGlhRGV2aWNlcyBBUEkgU3VwcG9ydF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL01lZGlhRGV2aWNlcy9nZXRVc2VyTWVkaWEpXG4gKiB0byBzZWUgd2hpY2ggYnJvd3NlcnMgYXJlIHN1cHBvcnRlZC4gQWNjZXNzIHRvIGFuIGV4dGVybmFsIGlucHV0XG4gKiBpcyBsaW1pdGVkIHRvIHNlY3VyZSAoSFRUUFMpIGNvbm5lY3Rpb25zLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpLmNvbm5lY3QobWV0ZXIpO1xuICogbWljLm9wZW4oKS50aGVuKCgpID0+IHtcbiAqIFx0Ly8gcHJvbWlzZSByZXNvbHZlcyB3aGVuIGlucHV0IGlzIGF2YWlsYWJsZVxuICogXHRjb25zb2xlLmxvZyhcIm1pYyBvcGVuXCIpO1xuICogXHQvLyBwcmludCB0aGUgaW5jb21pbmcgbWljIGxldmVscyBpbiBkZWNpYmVsc1xuICogXHRzZXRJbnRlcnZhbCgoKSA9PiBjb25zb2xlLmxvZyhtZXRlci5nZXRWYWx1ZSgpKSwgMTAwKTtcbiAqIH0pLmNhdGNoKGUgPT4ge1xuICogXHQvLyBwcm9taXNlIGlzIHJlamVjdGVkIHdoZW4gdGhlIHVzZXIgZG9lc24ndCBoYXZlIG9yIGFsbG93IG1pYyBhY2Nlc3NcbiAqIFx0Y29uc29sZS5sb2coXCJtaWMgbm90IG9wZW5cIik7XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIFVzZXJNZWRpYSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhVc2VyTWVkaWEuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2x1bWVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJVc2VyTWVkaWFcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFVzZXJNZWRpYS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiXSk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5tdXRlID0gb3B0aW9ucy5tdXRlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICB2b2x1bWU6IDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIE9wZW4gdGhlIG1lZGlhIHN0cmVhbS4gSWYgYSBzdHJpbmcgaXMgcGFzc2VkIGluLCBpdCBpcyBhc3N1bWVkXG4gICAgICogdG8gYmUgdGhlIGxhYmVsIG9yIGlkIG9mIHRoZSBzdHJlYW0sIGlmIGEgbnVtYmVyIGlzIHBhc3NlZCBpbixcbiAgICAgKiBpdCBpcyB0aGUgaW5wdXQgbnVtYmVyIG9mIHRoZSBzdHJlYW0uXG4gICAgICogQHBhcmFtICBsYWJlbE9ySWQgVGhlIGxhYmVsIG9yIGlkIG9mIHRoZSBhdWRpbyBpbnB1dCBtZWRpYSBkZXZpY2UuXG4gICAgICogICAgICAgICAgICAgICAgICAgV2l0aCBubyBhcmd1bWVudCwgdGhlIGRlZmF1bHQgc3RyZWFtIGlzIG9wZW5lZC5cbiAgICAgKiBAcmV0dXJuIFRoZSBwcm9taXNlIGlzIHJlc29sdmVkIHdoZW4gdGhlIHN0cmVhbSBpcyBvcGVuLlxuICAgICAqL1xuICAgIG9wZW4obGFiZWxPcklkKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBhc3NlcnQoVXNlck1lZGlhLnN1cHBvcnRlZCwgXCJVc2VyTWVkaWEgaXMgbm90IHN1cHBvcnRlZFwiKTtcbiAgICAgICAgICAgIC8vIGNsb3NlIHRoZSBwcmV2aW91cyBzdHJlYW1cbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRldmljZXMgPSB5aWVsZCBVc2VyTWVkaWEuZW51bWVyYXRlRGV2aWNlcygpO1xuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGxhYmVsT3JJZCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzW2xhYmVsT3JJZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9kZXZpY2UgPSBkZXZpY2VzLmZpbmQoKGRldmljZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGV2aWNlLmxhYmVsID09PSBsYWJlbE9ySWQgfHwgZGV2aWNlLmRldmljZUlkID09PSBsYWJlbE9ySWQ7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gZGlkbid0IGZpbmQgYSBtYXRjaGluZyBkZXZpY2VcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2RldmljZSAmJiBkZXZpY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZGV2aWNlID0gZGV2aWNlc1swXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXNzZXJ0KGlzRGVmaW5lZCh0aGlzLl9kZXZpY2UpLCBgTm8gbWF0Y2hpbmcgZGV2aWNlICR7bGFiZWxPcklkfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZG8gZ2V0VXNlck1lZGlhXG4gICAgICAgICAgICBjb25zdCBjb25zdHJhaW50cyA9IHtcbiAgICAgICAgICAgICAgICBhdWRpbzoge1xuICAgICAgICAgICAgICAgICAgICBlY2hvQ2FuY2VsbGF0aW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUsXG4gICAgICAgICAgICAgICAgICAgIG5vaXNlU3VwcHJlc3Npb246IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtb3pOb2lzZVN1cHByZXNzaW9uOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKHRoaXMuX2RldmljZSkge1xuICAgICAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgICAgICBjb25zdHJhaW50cy5hdWRpby5kZXZpY2VJZCA9IHRoaXMuX2RldmljZS5kZXZpY2VJZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHN0cmVhbSA9IHlpZWxkIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKGNvbnN0cmFpbnRzKTtcbiAgICAgICAgICAgIC8vIHN0YXJ0IGEgbmV3IHNvdXJjZSBvbmx5IGlmIHRoZSBwcmV2aW91cyBvbmUgaXMgY2xvc2VkXG4gICAgICAgICAgICBpZiAoIXRoaXMuX3N0cmVhbSkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0cmVhbSA9IHN0cmVhbTtcbiAgICAgICAgICAgICAgICAvLyBXcmFwIGEgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIGFyb3VuZCB0aGUgbGl2ZSBpbnB1dCBzdHJlYW0uXG4gICAgICAgICAgICAgICAgY29uc3QgbWVkaWFTdHJlYW1Ob2RlID0gdGhpcy5jb250ZXh0LmNyZWF0ZU1lZGlhU3RyZWFtU291cmNlKHN0cmVhbSk7XG4gICAgICAgICAgICAgICAgLy8gQ29ubmVjdCB0aGUgTWVkaWFTdHJlYW1Tb3VyY2VOb2RlIHRvIGEgZ2F0ZSBnYWluIG5vZGVcbiAgICAgICAgICAgICAgICBjb25uZWN0KG1lZGlhU3RyZWFtTm9kZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtID0gbWVkaWFTdHJlYW1Ob2RlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbG9zZSB0aGUgbWVkaWEgc3RyZWFtXG4gICAgICovXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zdHJlYW0gJiYgdGhpcy5fbWVkaWFTdHJlYW0pIHtcbiAgICAgICAgICAgIHRoaXMuX3N0cmVhbS5nZXRBdWRpb1RyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJhY2suc3RvcCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9zdHJlYW0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAvLyByZW1vdmUgdGhlIG9sZCBtZWRpYSBzdHJlYW1cbiAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX21lZGlhU3RyZWFtID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RldmljZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdpdGggdGhlIGxpc3Qgb2YgYXVkaW8gaW5wdXQgZGV2aWNlcyBhdmFpbGFibGUuXG4gICAgICogQHJldHVybiBUaGUgcHJvbWlzZSB0aGF0IGlzIHJlc29sdmVkIHdpdGggdGhlIGRldmljZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIFRvbmUuVXNlck1lZGlhLmVudW1lcmF0ZURldmljZXMoKS50aGVuKChkZXZpY2VzKSA9PiB7XG4gICAgICogXHQvLyBwcmludCB0aGUgZGV2aWNlIGxhYmVsc1xuICAgICAqIFx0Y29uc29sZS5sb2coZGV2aWNlcy5tYXAoZGV2aWNlID0+IGRldmljZS5sYWJlbCkpO1xuICAgICAqIH0pO1xuICAgICAqL1xuICAgIHN0YXRpYyBlbnVtZXJhdGVEZXZpY2VzKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgYWxsRGV2aWNlcyA9IHlpZWxkIG5hdmlnYXRvci5tZWRpYURldmljZXMuZW51bWVyYXRlRGV2aWNlcygpO1xuICAgICAgICAgICAgcmV0dXJuIGFsbERldmljZXMuZmlsdGVyKGRldmljZSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRldmljZS5raW5kID09PSBcImF1ZGlvaW5wdXRcIjtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIHNvdXJjZSwgXCJzdGFydGVkXCIgd2hlbiB0aGUgbWljcm9waG9uZSBpcyBvcGVuXG4gICAgICogYW5kIFwic3RvcHBlZFwiIHdoZW4gdGhlIG1pYyBpcyBjbG9zZWQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc3RyZWFtICYmIHRoaXMuX3N0cmVhbS5hY3RpdmUgPyBcInN0YXJ0ZWRcIiA6IFwic3RvcHBlZFwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGlkZW50aWZpZXIgZm9yIHRoZSByZXByZXNlbnRlZCBkZXZpY2UgdGhhdCBpc1xuICAgICAqIHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMuIEl0IGlzIHVuLWd1ZXNzYWJsZSBieSBvdGhlciBhcHBsaWNhdGlvbnMgYW5kXG4gICAgICogdW5pcXVlIHRvIHRoZSBvcmlnaW4gb2YgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24uIEl0IGlzIHJlc2V0IHdoZW4gdGhlXG4gICAgICogdXNlciBjbGVhcnMgY29va2llcyAoZm9yIFByaXZhdGUgQnJvd3NpbmcsIGEgZGlmZmVyZW50IGlkZW50aWZpZXIgaXNcbiAgICAgKiB1c2VkIHRoYXQgaXMgbm90IHBlcnNpc3RlZCBhY3Jvc3Mgc2Vzc2lvbnMpLiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZVxuICAgICAqIGRldmljZSBpcyBub3Qgb3Blbi5cbiAgICAgKi9cbiAgICBnZXQgZGV2aWNlSWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZGV2aWNlSWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBncm91cCBpZGVudGlmaWVyLiBUd28gZGV2aWNlcyBoYXZlIHRoZVxuICAgICAqIHNhbWUgZ3JvdXAgaWRlbnRpZmllciBpZiB0aGV5IGJlbG9uZyB0byB0aGUgc2FtZSBwaHlzaWNhbCBkZXZpY2UuXG4gICAgICogUmV0dXJucyBudWxsICB3aGVuIHRoZSBkZXZpY2UgaXMgbm90IG9wZW4uXG4gICAgICovXG4gICAgZ2V0IGdyb3VwSWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kZXZpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXZpY2UuZ3JvdXBJZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhIGxhYmVsIGRlc2NyaWJpbmcgdGhpcyBkZXZpY2UgKGZvciBleGFtcGxlIFwiQnVpbHQtaW4gTWljcm9waG9uZVwiKS5cbiAgICAgKiBSZXR1cm5zIHVuZGVmaW5lZCB3aGVuIHRoZSBkZXZpY2UgaXMgbm90IG9wZW4gb3IgbGFiZWwgaXMgbm90IGF2YWlsYWJsZVxuICAgICAqIGJlY2F1c2Ugb2YgcGVybWlzc2lvbnMuXG4gICAgICovXG4gICAgZ2V0IGxhYmVsKCkge1xuICAgICAgICBpZiAodGhpcy5fZGV2aWNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZGV2aWNlLmxhYmVsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAgICAgKiBtaWMub3BlbigpLnRoZW4oKCkgPT4ge1xuICAgICAqIFx0Ly8gcHJvbWlzZSByZXNvbHZlcyB3aGVuIGlucHV0IGlzIGF2YWlsYWJsZVxuICAgICAqIH0pO1xuICAgICAqIC8vIG11dGUgdGhlIG91dHB1dFxuICAgICAqIG1pYy5tdXRlID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgbXV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZvbHVtZS5tdXRlO1xuICAgIH1cbiAgICBzZXQgbXV0ZShtdXRlKSB7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGdldFVzZXJNZWRpYSBpcyBzdXBwb3J0ZWQgYnkgdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgc3RhdGljIGdldCBzdXBwb3J0ZWQoKSB7XG4gICAgICAgIHJldHVybiBpc0RlZmluZWQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcykgJiZcbiAgICAgICAgICAgIGlzRGVmaW5lZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VXNlck1lZGlhLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgT2ZmbGluZUNvbnRleHQgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L09mZmxpbmVDb250ZXh0XCI7XG4vKipcbiAqIFJlbmRlciBhIHNlZ21lbnQgb2YgdGhlIG9zY2lsbGF0b3IgdG8gYW4gb2ZmbGluZSBjb250ZXh0IGFuZCByZXR1cm4gdGhlIHJlc3VsdHMgYXMgYW4gYXJyYXlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlV2F2ZWZvcm0oaW5zdGFuY2UsIGxlbmd0aCkge1xuICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgIGNvbnN0IGR1cmF0aW9uID0gbGVuZ3RoIC8gaW5zdGFuY2UuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgICBjb25zdCBjb250ZXh0ID0gbmV3IE9mZmxpbmVDb250ZXh0KDEsIGR1cmF0aW9uLCBpbnN0YW5jZS5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICBjb25zdCBjbG9uZSA9IG5ldyBpbnN0YW5jZS5jb25zdHJ1Y3RvcihPYmplY3QuYXNzaWduKGluc3RhbmNlLmdldCgpLCB7XG4gICAgICAgICAgICAvLyBzaG91bGQgZG8gMiBpdGVyYXRpb25zXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDIgLyBkdXJhdGlvbixcbiAgICAgICAgICAgIC8vIHplcm8gb3V0IHRoZSBkZXR1bmVcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgfSkpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgICAgY2xvbmUuc3RhcnQoMCk7XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IHlpZWxkIGNvbnRleHQucmVuZGVyKCk7XG4gICAgICAgIHJldHVybiBidWZmZXIuZ2V0Q2hhbm5lbERhdGEoMCk7XG4gICAgfSk7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Pc2NpbGxhdG9ySW50ZXJmYWNlLmpzLm1hcCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVTaG90U291cmNlIH0gZnJvbSBcIi4uL09uZVNob3RTb3VyY2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogV3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBmaXJlLWFuZC1mb3JnZXQgT3NjaWxsYXRvck5vZGUuXG4gKiBBZGRzIHRoZSBhYmlsaXR5IHRvIHJlc2NoZWR1bGUgdGhlIHN0b3AgbWV0aG9kLlxuICogKioqW1tPc2NpbGxhdG9yXV0gaXMgYmV0dGVyIGZvciBtb3N0IHVzZS1jYXNlcyoqKlxuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgVG9uZU9zY2lsbGF0b3JOb2RlIGV4dGVuZHMgT25lU2hvdFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVPc2NpbGxhdG9yTm9kZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJUb25lT3NjaWxsYXRvck5vZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvc2NpbGxhdG9yXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5jb250ZXh0LmNyZWF0ZU9zY2lsbGF0b3IoKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLl9vc2NpbGxhdG9yXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFRvbmVPc2NpbGxhdG9yTm9kZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICBjb25uZWN0KHRoaXMuX29zY2lsbGF0b3IsIHRoaXMuX2dhaW5Ob2RlKTtcbiAgICAgICAgdGhpcy50eXBlID0gb3B0aW9ucy50eXBlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9uZVNob3RTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiA0NDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBvc2NpbGxhdG9yIG5vZGUgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0byBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMubG9nKFwic3RhcnRcIiwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnRHYWluKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9zdG9wU291cmNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIGFuIGFyYml0cmFyeSBjdXN0b20gcGVyaW9kaWMgd2F2ZWZvcm0gZ2l2ZW4gYSBQZXJpb2RpY1dhdmUuXG4gICAgICogQHBhcmFtICBwZXJpb2RpY1dhdmUgUGVyaW9kaWNXYXZlIHNob3VsZCBiZSBjcmVhdGVkIHdpdGggY29udGV4dC5jcmVhdGVQZXJpb2RpY1dhdmVcbiAgICAgKi9cbiAgICBzZXRQZXJpb2RpY1dhdmUocGVyaW9kaWNXYXZlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHBlcmlvZGljV2F2ZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlLiBFaXRoZXIgJ3NpbmUnLCAnc2F3dG9vdGgnLCAnc3F1YXJlJywgb3IgJ3RyaWFuZ2xlJ1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVPc2NpbGxhdG9yTm9kZS5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IGRlZXBFcXVhbHMsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNEZWZpbmVkIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgVG9uZU9zY2lsbGF0b3JOb2RlIH0gZnJvbSBcIi4vVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIE9zY2lsbGF0b3Igc3VwcG9ydHMgYSBudW1iZXIgb2YgZmVhdHVyZXMgaW5jbHVkaW5nXG4gKiBwaGFzZSByb3RhdGlvbiwgbXVsdGlwbGUgb3NjaWxsYXRvciB0eXBlcyAoc2VlIE9zY2lsbGF0b3IudHlwZSksXG4gKiBhbmQgVHJhbnNwb3J0IHN5bmNpbmcgKHNlZSBPc2NpbGxhdG9yLnN5bmNGcmVxdWVuY3kpLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBtYWtlIGFuZCBzdGFydCBhIDQ0MGh6IHNpbmUgdG9uZVxuICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIE9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBtYWluIG9zY2lsbGF0b3JcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBudWxsO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZyZXF1ZW5jeVwiKTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRldHVuZVwiKTtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBvcHRpb25zLnBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBvcHRpb25zLnBhcnRpYWxDb3VudDtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgaWYgKG9wdGlvbnMucGFydGlhbENvdW50ICYmIG9wdGlvbnMudHlwZSAhPT0gXCJjdXN0b21cIikge1xuICAgICAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuYmFzZVR5cGUgKyBvcHRpb25zLnBhcnRpYWxDb3VudC50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNvdXJjZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDQ0MCxcbiAgICAgICAgICAgIHBhcnRpYWxDb3VudDogMCxcbiAgICAgICAgICAgIHBhcnRpYWxzOiBbXSxcbiAgICAgICAgICAgIHBoYXNlOiAwLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyBuZXcgb3NjaWxsYXRvciB3aXRoIHByZXZpb3VzIHZhbHVlc1xuICAgICAgICBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmVPc2NpbGxhdG9yTm9kZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBvbmVuZGVkOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSBvc2NpbGxhdG9yO1xuICAgICAgICBpZiAodGhpcy5fd2F2ZSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGNvbnRyb2wgc2lnbmFsIHRvIHRoZSBvc2NpbGxhdG9yIGZyZXF1ZW5jeSAmIGRldHVuZVxuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX29zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQoY29tcHV0ZWRUaW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXN0YXJ0IHRoZSBvc2NpbGxhdG9yLiBEb2VzIG5vdCBzdG9wIHRoZSBvc2NpbGxhdG9yLCBidXQgaW5zdGVhZFxuICAgICAqIGp1c3QgY2FuY2VscyBhbnkgc2NoZWR1bGVkICdzdG9wJyBmcm9tIGJlaW5nIGludm9rZWQuXG4gICAgICovXG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5sb2coXCJyZXN0YXJ0XCIsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNhbmNlbFN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHNpZ25hbCB0byB0aGUgVHJhbnNwb3J0J3MgYnBtLiBBbnkgY2hhbmdlcyB0byB0aGUgdHJhbnNwb3J0cyBicG0sXG4gICAgICogd2lsbCBhbHNvIGFmZmVjdCB0aGUgb3NjaWxsYXRvcnMgZnJlcXVlbmN5LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG9zYy5mcmVxdWVuY3kudmFsdWUgPSA0NDA7XG4gICAgICogLy8gdGhlIHJhdGlvIGJldHdlZW4gdGhlIGJwbSBhbmQgdGhlIGZyZXF1ZW5jeSB3aWxsIGJlIG1haW50YWluZWRcbiAgICAgKiBvc2Muc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAqIC8vIGRvdWJsZSB0aGUgdGVtcG9cbiAgICAgKiBUb25lLlRyYW5zcG9ydC5icG0udmFsdWUgKj0gMjtcbiAgICAgKiAvLyB0aGUgZnJlcXVlbmN5IG9mIHRoZSBvc2NpbGxhdG9yIGlzIGRvdWJsZWQgdG8gODgwXG4gICAgICovXG4gICAgc3luY0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zeW5jU2lnbmFsKHRoaXMuZnJlcXVlbmN5KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgb3NjaWxsYXRvcidzIGZyZXF1ZW5jeSBmcm9tIHRoZSBUcmFuc3BvcnQuXG4gICAgICogU2VlIE9zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeVxuICAgICAqL1xuICAgIHVuc3luY0ZyZXF1ZW5jeSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC51bnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgY2FjaGVkIHBlcmlvZGljIHdhdmUuIEF2b2lkcyBoYXZpbmcgdG8gcmVjb21wdXRlXG4gICAgICogdGhlIG9zY2lsbGF0b3IgdmFsdWVzIHdoZW4gdGhleSBoYXZlIGFscmVhZHkgYmVlbiBjb21wdXRlZFxuICAgICAqIHdpdGggdGhlIHNhbWUgdmFsdWVzLlxuICAgICAqL1xuICAgIF9nZXRDYWNoZWRQZXJpb2RpY1dhdmUoKSB7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBjb25zdCBvc2NQcm9wcyA9IE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmZpbmQoZGVzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbi5waGFzZSA9PT0gdGhpcy5fcGhhc2UgJiZcbiAgICAgICAgICAgICAgICAgICAgZGVlcEVxdWFscyhkZXNjcmlwdGlvbi5wYXJ0aWFscywgdGhpcy5fcGFydGlhbHMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gb3NjUHJvcHM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBvc2NQcm9wcyA9IE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLmZpbmQoZGVzY3JpcHRpb24gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjcmlwdGlvbi50eXBlID09PSB0aGlzLl90eXBlICYmXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uLnBoYXNlID09PSB0aGlzLl9waGFzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gb3NjUHJvcHMgPyBvc2NQcm9wcy5wYXJ0aWFsQ291bnQgOiB0aGlzLl9wYXJ0aWFsQ291bnQ7XG4gICAgICAgICAgICByZXR1cm4gb3NjUHJvcHM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICBjb25zdCBpc0Jhc2ljVHlwZSA9IFtcInNpbmVcIiwgXCJzcXVhcmVcIiwgXCJzYXd0b290aFwiLCBcInRyaWFuZ2xlXCJdLmluZGV4T2YodHlwZSkgIT09IC0xO1xuICAgICAgICBpZiAodGhpcy5fcGhhc2UgPT09IDAgJiYgaXNCYXNpY1R5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3dhdmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSAwO1xuICAgICAgICAgICAgLy8ganVzdCBnbyB3aXRoIHRoZSBiYXNpYyBhcHByb2FjaFxuICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBhbHJlYWR5IHRlc3RlZCB0aGF0IGl0J3MgYSBiYXNpYyB0eXBlXG4gICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHRoZSB2YWx1ZSBpcyBjYWNoZWRcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlID0gdGhpcy5fZ2V0Q2FjaGVkUGVyaW9kaWNXYXZlKCk7XG4gICAgICAgICAgICBpZiAoaXNEZWZpbmVkKGNhY2hlKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgcGFydGlhbHMsIHdhdmUgfSA9IGNhY2hlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dhdmUgPSB3YXZlO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3IgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zZXRQZXJpb2RpY1dhdmUodGhpcy5fd2F2ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgW3JlYWwsIGltYWddID0gdGhpcy5fZ2V0UmVhbEltYWdpbmFyeSh0eXBlLCB0aGlzLl9waGFzZSk7XG4gICAgICAgICAgICAgICAgY29uc3QgcGVyaW9kaWNXYXZlID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBlcmlvZGljV2F2ZShyZWFsLCBpbWFnKTtcbiAgICAgICAgICAgICAgICB0aGlzLl93YXZlID0gcGVyaW9kaWNXYXZlO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc2V0UGVyaW9kaWNXYXZlKHRoaXMuX3dhdmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBzZXQgdGhlIGNhY2hlXG4gICAgICAgICAgICAgICAgT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGltYWcsXG4gICAgICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudDogdGhpcy5fcGFydGlhbENvdW50LFxuICAgICAgICAgICAgICAgICAgICBwYXJ0aWFsczogdGhpcy5fcGFydGlhbHMsXG4gICAgICAgICAgICAgICAgICAgIHBoYXNlOiB0aGlzLl9waGFzZSxcbiAgICAgICAgICAgICAgICAgICAgcmVhbCxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgICAgICAgICAgd2F2ZTogdGhpcy5fd2F2ZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAoT3NjaWxsYXRvci5fcGVyaW9kaWNXYXZlQ2FjaGUubGVuZ3RoID4gMTAwKSB7XG4gICAgICAgICAgICAgICAgICAgIE9zY2lsbGF0b3IuX3BlcmlvZGljV2F2ZUNhY2hlLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBiYXNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGUucmVwbGFjZSh0aGlzLnBhcnRpYWxDb3VudC50b1N0cmluZygpLCBcIlwiKTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIGlmICh0aGlzLnBhcnRpYWxDb3VudCAmJiB0aGlzLl90eXBlICE9PSBcImN1c3RvbVwiICYmIGJhc2VUeXBlICE9PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZSArIHRoaXMucGFydGlhbENvdW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy50eXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwKSB7XG4gICAgICAgIGFzc2VydFJhbmdlKHAsIDApO1xuICAgICAgICBsZXQgdHlwZSA9IHRoaXMuX3R5cGU7XG4gICAgICAgIGNvbnN0IHBhcnRpYWwgPSAvXihzaW5lfHRyaWFuZ2xlfHNxdWFyZXxzYXd0b290aCkoXFxkKykkLy5leGVjKHRoaXMuX3R5cGUpO1xuICAgICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAgICAgdHlwZSA9IHBhcnRpYWxbMV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX3R5cGUgIT09IFwiY3VzdG9tXCIpIHtcbiAgICAgICAgICAgIGlmIChwID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGUgKyBwLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBleHRlbmQgb3Igc2hvcnRlbiB0aGUgcGFydGlhbHMgYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IGZ1bGxQYXJ0aWFscyA9IG5ldyBGbG9hdDMyQXJyYXkocCk7XG4gICAgICAgICAgICAvLyBjb3B5IG92ZXIgdGhlIHBhcnRpYWxzIGFycmF5XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscy5mb3JFYWNoKCh2LCBpKSA9PiBmdWxsUGFydGlhbHNbaV0gPSB2KTtcbiAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxzID0gQXJyYXkuZnJvbShmdWxsUGFydGlhbHMpO1xuICAgICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5fdHlwZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSByZWFsIGFuZCBpbWFnaW5hcnkgY29tcG9uZW50cyBiYXNlZFxuICAgICAqIG9uIHRoZSBvc2NpbGxhdG9yIHR5cGUuXG4gICAgICogQHJldHVybnMgW3JlYWw6IEZsb2F0MzJBcnJheSwgaW1hZ2luYXJ5OiBGbG9hdDMyQXJyYXldXG4gICAgICovXG4gICAgX2dldFJlYWxJbWFnaW5hcnkodHlwZSwgcGhhc2UpIHtcbiAgICAgICAgY29uc3QgZmZ0U2l6ZSA9IDQwOTY7XG4gICAgICAgIGxldCBwZXJpb2RpY1dhdmVTaXplID0gZmZ0U2l6ZSAvIDI7XG4gICAgICAgIGNvbnN0IHJlYWwgPSBuZXcgRmxvYXQzMkFycmF5KHBlcmlvZGljV2F2ZVNpemUpO1xuICAgICAgICBjb25zdCBpbWFnID0gbmV3IEZsb2F0MzJBcnJheShwZXJpb2RpY1dhdmVTaXplKTtcbiAgICAgICAgbGV0IHBhcnRpYWxDb3VudCA9IDE7XG4gICAgICAgIGlmICh0eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICBwYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGggKyAxO1xuICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIC8vIGlmIHRoZSBwYXJ0aWFsIGNvdW50IGlzIDAsIGRvbid0IGJvdGhlciBkb2luZyBhbnkgY29tcHV0YXRpb25cbiAgICAgICAgICAgIGlmICh0aGlzLl9wYXJ0aWFscy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW3JlYWwsIGltYWddO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFydGlhbCA9IC9eKHNpbmV8dHJpYW5nbGV8c3F1YXJlfHNhd3Rvb3RoKShcXGQrKSQvLmV4ZWModHlwZSk7XG4gICAgICAgICAgICBpZiAocGFydGlhbCkge1xuICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IHBhcnNlSW50KHBhcnRpYWxbMl0sIDEwKSArIDE7XG4gICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gcGFyc2VJbnQocGFydGlhbFsyXSwgMTApO1xuICAgICAgICAgICAgICAgIHR5cGUgPSBwYXJ0aWFsWzFdO1xuICAgICAgICAgICAgICAgIHBhcnRpYWxDb3VudCA9IE1hdGgubWF4KHBhcnRpYWxDb3VudCwgMik7XG4gICAgICAgICAgICAgICAgcGVyaW9kaWNXYXZlU2l6ZSA9IHBhcnRpYWxDb3VudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG4gPSAxOyBuIDwgcGVyaW9kaWNXYXZlU2l6ZTsgKytuKSB7XG4gICAgICAgICAgICBjb25zdCBwaUZhY3RvciA9IDIgLyAobiAqIE1hdGguUEkpO1xuICAgICAgICAgICAgbGV0IGI7XG4gICAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwic2luZVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gKG4gPD0gcGFydGlhbENvdW50KSA/IDEgOiAwO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9wYXJ0aWFsc1tuIC0gMV0gPSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwic3F1YXJlXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSAobiAmIDEpID8gMiAqIHBpRmFjdG9yIDogMDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInNhd3Rvb3RoXCI6XG4gICAgICAgICAgICAgICAgICAgIGIgPSBwaUZhY3RvciAqICgobiAmIDEpID8gMSA6IC0xKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInRyaWFuZ2xlXCI6XG4gICAgICAgICAgICAgICAgICAgIGlmIChuICYgMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYiA9IDIgKiAocGlGYWN0b3IgKiBwaUZhY3RvcikgKiAoKCgobiAtIDEpID4+IDEpICYgMSkgPyAtMSA6IDEpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYiA9IDA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fcGFydGlhbHNbbiAtIDFdID0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcImN1c3RvbVwiOlxuICAgICAgICAgICAgICAgICAgICBiID0gdGhpcy5fcGFydGlhbHNbbiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT3NjaWxsYXRvcjogaW52YWxpZCB0eXBlOiBcIiArIHR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGIgIT09IDApIHtcbiAgICAgICAgICAgICAgICByZWFsW25dID0gLWIgKiBNYXRoLnNpbihwaGFzZSAqIG4pO1xuICAgICAgICAgICAgICAgIGltYWdbbl0gPSBiICogTWF0aC5jb3MocGhhc2UgKiBuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlYWxbbl0gPSAwO1xuICAgICAgICAgICAgICAgIGltYWdbbl0gPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbcmVhbCwgaW1hZ107XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbXB1dGUgdGhlIGludmVyc2UgRkZUIGZvciBhIGdpdmVuIHBoYXNlLlxuICAgICAqL1xuICAgIF9pbnZlcnNlRkZUKHJlYWwsIGltYWcsIHBoYXNlKSB7XG4gICAgICAgIGxldCBzdW0gPSAwO1xuICAgICAgICBjb25zdCBsZW4gPSByZWFsLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgc3VtICs9IHJlYWxbaV0gKiBNYXRoLmNvcyhpICogcGhhc2UpICsgaW1hZ1tpXSAqIE1hdGguc2luKGkgKiBwaGFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1bTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgaW5pdGlhbCB2YWx1ZSBvZiB0aGUgb3NjaWxsYXRvciB3aGVuIHN0b3BwZWQuXG4gICAgICogRS5nLiBhIFwic2luZVwiIG9zY2lsbGF0b3Igd2l0aCBwaGFzZSA9IDkwIHdvdWxkIHJldHVybiBhbiBpbml0aWFsIHZhbHVlIG9mIC0xLlxuICAgICAqL1xuICAgIGdldEluaXRpYWxWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgW3JlYWwsIGltYWddID0gdGhpcy5fZ2V0UmVhbEltYWdpbmFyeSh0aGlzLl90eXBlLCAwKTtcbiAgICAgICAgbGV0IG1heFZhbHVlID0gMDtcbiAgICAgICAgY29uc3QgdHdvUGkgPSBNYXRoLlBJICogMjtcbiAgICAgICAgY29uc3QgdGVzdFBvc2l0aW9ucyA9IDMyO1xuICAgICAgICAvLyBjaGVjayBmb3IgcGVha3MgaW4gMTYgcGxhY2VzXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGVzdFBvc2l0aW9uczsgaSsrKSB7XG4gICAgICAgICAgICBtYXhWYWx1ZSA9IE1hdGgubWF4KHRoaXMuX2ludmVyc2VGRlQocmVhbCwgaW1hZywgKGkgLyB0ZXN0UG9zaXRpb25zKSAqIHR3b1BpKSwgbWF4VmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbGFtcCgtdGhpcy5faW52ZXJzZUZGVChyZWFsLCBpbWFnLCB0aGlzLl9waGFzZSkgLyBtYXhWYWx1ZSwgLTEsIDEpO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0aWFscy5zbGljZSgwLCB0aGlzLnBhcnRpYWxDb3VudCk7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSB0aGlzLl9wYXJ0aWFscy5sZW5ndGg7XG4gICAgICAgIGlmIChwYXJ0aWFscy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiY3VzdG9tXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGhhc2UgKiAoMTgwIC8gTWF0aC5QSSk7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl9waGFzZSA9IHBoYXNlICogTWF0aC5QSSAvIDE4MDtcbiAgICAgICAgLy8gcmVzZXQgdGhlIHR5cGVcbiAgICAgICAgdGhpcy50eXBlID0gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvciAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fd2F2ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8qKlxuICogQ2FjaGUgdGhlIHBlcmlvZGljIHdhdmVzIHRvIGF2b2lkIGhhdmluZyB0byByZWRvIGNvbXB1dGF0aW9uc1xuICovXG5Pc2NpbGxhdG9yLl9wZXJpb2RpY1dhdmVDYWNoZSA9IFtdO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9T3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbi8qKlxuICogQSBzaWduYWwgb3BlcmF0b3IgaGFzIGFuIGlucHV0IGFuZCBvdXRwdXQgYW5kIG1vZGlmaWVzIHRoZSBzaWduYWwuXG4gKi9cbmV4cG9ydCBjbGFzcyBTaWduYWxPcGVyYXRvciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNpZ25hbE9wZXJhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY29udGV4dFwiXSkpKTtcbiAgICB9XG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtID0gMCwgaW5wdXROdW0gPSAwKSB7XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaWduYWxPcGVyYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzRnVuY3Rpb24gfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFdyYXBzIHRoZSBuYXRpdmUgV2ViIEF1ZGlvIEFQSVxuICogW1dhdmVTaGFwZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS13YXZlc2hhcGVybm9kZS1pbnRlcmZhY2UpLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyBtdWx0aXBseSB0aGUgb3V0cHV0IG9mIHRoZSBzaWduYWwgYnkgMiB1c2luZyB0aGUgd2F2ZXNoYXBlcidzIGZ1bmN0aW9uXG4gKiBjb25zdCB0aW1lc1R3byA9IG5ldyBUb25lLldhdmVTaGFwZXIoKHZhbCkgPT4gdmFsICogMiwgMjA0OCkuY29ubmVjdChvc2MuZnJlcXVlbmN5KTtcbiAqIGNvbnN0IHNpZ25hbCA9IG5ldyBUb25lLlNpZ25hbCg0NDApLmNvbm5lY3QodGltZXNUd28pO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgV2F2ZVNoYXBlciBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlU2hhcGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWFwcGluZ1wiLCBcImxlbmd0aFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJXYXZlU2hhcGVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgd2F2ZXNoYXBlciBub2RlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlV2F2ZVNoYXBlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGlucHV0IHRvIHRoZSB3YXZlc2hhcGVyIG5vZGUuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc2hhcGVyO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBmcm9tIHRoZSB3YXZlc2hhcGVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc2hhcGVyO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZVNoYXBlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1hcHBpbmdcIiwgXCJsZW5ndGhcIl0pO1xuICAgICAgICBpZiAoaXNBcnJheShvcHRpb25zLm1hcHBpbmcpIHx8IG9wdGlvbnMubWFwcGluZyBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSkge1xuICAgICAgICAgICAgdGhpcy5jdXJ2ZSA9IEZsb2F0MzJBcnJheS5mcm9tKG9wdGlvbnMubWFwcGluZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNGdW5jdGlvbihvcHRpb25zLm1hcHBpbmcpKSB7XG4gICAgICAgICAgICB0aGlzLnNldE1hcChvcHRpb25zLm1hcHBpbmcsIG9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBsZW5ndGg6IDEwMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVc2VzIGEgbWFwcGluZyBmdW5jdGlvbiB0byBzZXQgdGhlIHZhbHVlIG9mIHRoZSBjdXJ2ZS5cbiAgICAgKiBAcGFyYW0gbWFwcGluZyBUaGUgZnVuY3Rpb24gdXNlZCB0byBkZWZpbmUgdGhlIHZhbHVlcy5cbiAgICAgKiAgICAgICAgICAgICAgICBUaGUgbWFwcGluZyBmdW5jdGlvbiB0YWtlIHR3byBhcmd1bWVudHM6XG4gICAgICogICAgICAgICAgICAgICAgdGhlIGZpcnN0IGlzIHRoZSB2YWx1ZSBhdCB0aGUgY3VycmVudCBwb3NpdGlvblxuICAgICAqICAgICAgICAgICAgICAgIHdoaWNoIGdvZXMgZnJvbSAtMSB0byAxIG92ZXIgdGhlIG51bWJlciBvZiBlbGVtZW50c1xuICAgICAqICAgICAgICAgICAgICAgIGluIHRoZSBjdXJ2ZSBhcnJheS4gVGhlIHNlY29uZCBhcmd1bWVudCBpcyB0aGUgYXJyYXkgcG9zaXRpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzaGFwZXIgPSBuZXcgVG9uZS5XYXZlU2hhcGVyKCk7XG4gICAgICogLy8gbWFwIHRoZSBpbnB1dCBzaWduYWwgZnJvbSBbLTEsIDFdIHRvIFswLCAxMF1cbiAgICAgKiBzaGFwZXIuc2V0TWFwKCh2YWwsIGluZGV4KSA9PiAodmFsICsgMSkgKiA1KTtcbiAgICAgKi9cbiAgICBzZXRNYXAobWFwcGluZywgbGVuZ3RoID0gMTAyNCkge1xuICAgICAgICBjb25zdCBhcnJheSA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBub3JtYWxpemVkID0gKGkgLyAobGVuIC0gMSkpICogMiAtIDE7XG4gICAgICAgICAgICBhcnJheVtpXSA9IG1hcHBpbmcobm9ybWFsaXplZCwgaSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdXJ2ZSA9IGFycmF5O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IHRvIHNldCBhcyB0aGUgd2F2ZXNoYXBlciBjdXJ2ZS4gRm9yIGxpbmVhciBjdXJ2ZXNcbiAgICAgKiBhcnJheSBsZW5ndGggZG9lcyBub3QgbWFrZSBtdWNoIGRpZmZlcmVuY2UsIGJ1dCBmb3IgY29tcGxleCBjdXJ2ZXNcbiAgICAgKiBsb25nZXIgYXJyYXlzIHdpbGwgcHJvdmlkZSBzbW9vdGhlciBpbnRlcnBvbGF0aW9uLlxuICAgICAqL1xuICAgIGdldCBjdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NoYXBlci5jdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGN1cnZlKG1hcHBpbmcpIHtcbiAgICAgICAgdGhpcy5fc2hhcGVyLmN1cnZlID0gbWFwcGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHdoYXQgdHlwZSBvZiBvdmVyc2FtcGxpbmcgKGlmIGFueSkgc2hvdWxkIGJlIHVzZWQgd2hlblxuICAgICAqIGFwcGx5aW5nIHRoZSBzaGFwaW5nIGN1cnZlLiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICBjb25zdCBpc092ZXJTYW1wbGVUeXBlID0gW1wibm9uZVwiLCBcIjJ4XCIsIFwiNHhcIl0uc29tZShzdHIgPT4gc3RyLmluY2x1ZGVzKG92ZXJzYW1wbGluZykpO1xuICAgICAgICBhc3NlcnQoaXNPdmVyU2FtcGxlVHlwZSwgXCJvdmVyc2FtcGxpbmcgbXVzdCBiZSBlaXRoZXIgJ25vbmUnLCAnMngnLCBvciAnNHgnXCIpO1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1XYXZlU2hhcGVyLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIEF1ZGlvVG9HYWluIGNvbnZlcnRzIGFuIGlucHV0IGluIEF1ZGlvUmFuZ2UgWy0xLDFdIHRvIE5vcm1hbFJhbmdlIFswLDFdLlxuICogU2VlIFtbR2FpblRvQXVkaW9dXS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEF1ZGlvVG9HYWluIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1ZGlvVG9HYWluXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ub3JtID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogeCA9PiAoeCArIDEpIC8gMixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBpbnB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fbm9ybTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBHYWluUmFuZ2Ugb3V0cHV0IFswLCAxXVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9ub3JtO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbm9ybS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1ZGlvVG9HYWluLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4vU2lnbmFsXCI7XG4vKipcbiAqIE11bHRpcGx5IHR3byBpbmNvbWluZyBzaWduYWxzLiBPciwgaWYgYSBudW1iZXIgaXMgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yLFxuICogbXVsdGlwbGllcyB0aGUgaW5jb21pbmcgc2lnbmFsIGJ5IHRoYXQgdmFsdWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIG11bHRpcGx5IHR3byBzaWduYWxzXG4gKiBjb25zdCBtdWx0ID0gbmV3IFRvbmUuTXVsdGlwbHkoKTtcbiAqIGNvbnN0IHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMyk7XG4gKiBjb25zdCBzaWdCID0gbmV3IFRvbmUuU2lnbmFsKDQpO1xuICogc2lnQS5jb25uZWN0KG11bHQpO1xuICogc2lnQi5jb25uZWN0KG11bHQuZmFjdG9yKTtcbiAqIC8vIG91dHB1dCBvZiBtdWx0IGlzIDEyLlxuICogQGV4YW1wbGVcbiAqIC8vIG11bHRpcGx5IGEgc2lnbmFsIGFuZCBhIG51bWJlclxuICogY29uc3QgbXVsdCA9IG5ldyBUb25lLk11bHRpcGx5KDEwKTtcbiAqIGNvbnN0IHNpZyA9IG5ldyBUb25lLlNpZ25hbCgyKS5jb25uZWN0KG11bHQpO1xuICogLy8gdGhlIG91dHB1dCBvZiBtdWx0IGlzIDIwLlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgTXVsdGlwbHkgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpcGx5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTXVsdGlwbHlcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluZGljYXRlcyBpZiB0aGUgdmFsdWUgc2hvdWxkIGJlIG92ZXJyaWRkZW4gb24gY29ubmVjdGlvblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdmVycmlkZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTXVsdGlwbHkuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX211bHQgPSB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW5WYWx1ZTogb3B0aW9ucy5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBvcHRpb25zLm1heFZhbHVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mYWN0b3IgPSB0aGlzLl9wYXJhbSA9IHRoaXMuX211bHQuZ2FpbjtcbiAgICAgICAgdGhpcy5mYWN0b3Iuc2V0VmFsdWVBdFRpbWUob3B0aW9ucy52YWx1ZSwgMCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGlwbHkuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEF1ZGlvVG9HYWluIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BdWRpb1RvR2FpblwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbi8qKlxuICogQW4gYW1wbGl0dWRlIG1vZHVsYXRlZCBvc2NpbGxhdG9yIG5vZGUuIEl0IGlzIGltcGxlbWVudGVkIHdpdGhcbiAqIHR3byBvc2NpbGxhdG9ycywgb25lIHdoaWNoIG1vZHVsYXRvcnMgdGhlIG90aGVyJ3MgYW1wbGl0dWRlXG4gKiB0aHJvdWdoIGEgZ2FpbiBub2RlLlxuICogYGBgXG4gKiAgICArLS0tLS0tLS0tLS0tLSsgICAgICAgKy0tLS0tLS0tLS0rXG4gKiAgICB8IENhcnJpZXIgT3NjICs+LS0tLS0tPiBHYWluTm9kZSB8XG4gKiAgICArLS0tLS0tLS0tLS0tLSsgICAgICAgfCAgICAgICAgICArLS0tPk91dHB1dFxuICogICAgICAgICAgICAgICAgICAgICAgKy0tLT4gZ2FpbiAgICAgfFxuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgfCAgICstLS0tLS0tLS0tK1xuICogfCBNb2R1bGF0b3IgT3NjICs+LS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBhbU9zYyA9IG5ldyBUb25lLkFNT3NjaWxsYXRvcigzMCwgXCJzaW5lXCIsIFwic3F1YXJlXCIpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICogfSwgMC4yLCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEFNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJtb2R1bGF0aW9uVHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFNT3NjaWxsYXRvclwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29udmVydCB0aGUgLTEsMSBvdXRwdXQgdG8gMCwxXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUgPSBuZXcgQXVkaW9Ub0dhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhBTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwibW9kdWxhdGlvblR5cGVcIl0pO1xuICAgICAgICB0aGlzLl9jYXJyaWVyID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGV0dW5lOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5LFxuICAgICAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLl9jYXJyaWVyLmRldHVuZTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yID0gbmV3IE9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLm1vZHVsYXRpb25UeXBlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX21vZHVsYXRpb25TY2FsZSwgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiaGFybW9uaWNpdHlcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBjYXJyaWVyIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25TY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUFNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG4vKipcbiAqIEZNT3NjaWxsYXRvciBpbXBsZW1lbnRzIGEgZnJlcXVlbmN5IG1vZHVsYXRpb24gc3ludGhlc2lzXG4gKiBgYGBcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0tLS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLSsgICAgICAgICstLS0tLS0tLS0tLS0tKyAgICAgfCBDYXJyaWVyIE9zYyB8XG4gKiB8IE1vZHVsYXRvciBPc2MgKz4tLS0tLS0tPiBHYWluTm9kZSAgICB8ICAgICB8ICAgICAgICAgICAgICstLS0+T3V0cHV0XG4gKiArLS0tLS0tLS0tLS0tLS0tKyAgICAgICAgfCAgICAgICAgICAgICArPi0tLS0+IGZyZXF1ZW5jeSAgIHxcbiAqICAgICAgICAgICAgICAgICAgICAgICArLS0+IGdhaW4gICAgICAgIHwgICAgICstLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgICAgICAgICAgICAgIHwgICstLS0tLS0tLS0tLS0tK1xuICogKy0tLS0tLS0tLS0tLS0tLS0tKyAgIHxcbiAqIHwgbW9kdWxhdGlvbkluZGV4ICs+LS0rXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGZtT3NjID0gbmV3IFRvbmUuRk1Pc2NpbGxhdG9yKHtcbiAqIFx0XHRmcmVxdWVuY3k6IDIwMCxcbiAqIFx0XHR0eXBlOiBcInNxdWFyZVwiLFxuICogXHRcdG1vZHVsYXRpb25UeXBlOiBcInRyaWFuZ2xlXCIsXG4gKiBcdFx0aGFybW9uaWNpdHk6IDAuMixcbiAqIFx0XHRtb2R1bGF0aW9uSW5kZXg6IDNcbiAqIFx0fSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgRk1Pc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRk1Pc2NpbGxhdG9yXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgbm9kZSB3aGVyZSB0aGUgbW9kdWxhdGlvbiBoYXBwZW5zXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcIm1vZHVsYXRpb25UeXBlXCJdKTtcbiAgICAgICAgdGhpcy5fY2FycmllciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zdG9wKHRoaXMpLFxuICAgICAgICAgICAgcGhhc2U6IG9wdGlvbnMucGhhc2UsXG4gICAgICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX2NhcnJpZXIuZGV0dW5lO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMubW9kdWxhdGlvblR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oYXJtb25pY2l0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tb2R1bGF0aW9uSW5kZXgsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5oYXJtb25pY2l0eSwgdGhpcy5fbW9kdWxhdG9yLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMubW9kdWxhdGlvbkluZGV4LCB0aGlzLl9tb2R1bGF0aW9uTm9kZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jb25uZWN0KHRoaXMuX21vZHVsYXRpb25Ob2RlLmdhaW4pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5jb25uZWN0KHRoaXMuX2NhcnJpZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibW9kdWxhdGlvbkluZGV4XCIsIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCIsIFwiaGFybW9uaWNpdHlcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDEsXG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDIsXG4gICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fY2Fycmllci5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NhcnJpZXIudHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9jYXJyaWVyLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5iYXNlVHlwZSA9IGJhc2VUeXBlO1xuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFsQ291bnQ7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFsQ291bnQocGFydGlhbENvdW50KSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgbW9kdWxhdG9yIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb2R1bGF0b3IudHlwZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnR5cGUgPSB0eXBlO1xuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jYXJyaWVyLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fY2Fycmllci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IucGhhc2UgPSBwaGFzZTtcbiAgICB9XG4gICAgZ2V0IHBhcnRpYWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2Fycmllci5wYXJ0aWFscztcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxzKHBhcnRpYWxzKSB7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIucGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZNT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuLyoqXG4gKiBQdWxzZU9zY2lsbGF0b3IgaXMgYW4gb3NjaWxsYXRvciB3aXRoIGNvbnRyb2wgb3ZlciBwdWxzZSB3aWR0aCxcbiAqIGFsc28ga25vd24gYXMgdGhlIGR1dHkgY3ljbGUuIEF0IDUwJSBkdXR5IGN5Y2xlICh3aWR0aCA9IDApIHRoZSB3YXZlIGlzXG4gKiBhIHNxdWFyZSB3YXZlLlxuICogW1JlYWQgbW9yZV0oaHR0cHM6Ly93aWdnbGV3YXZlLndvcmRwcmVzcy5jb20vMjAxNC8wOC8xNi9wdWxzZS13YXZlZm9ybXMtYW5kLWhhcm1vbmljcy8pLlxuICogYGBgXG4gKiAgICB3aWR0aCA9IC0wLjI1ICAgICAgICB3aWR0aCA9IDAuMCAgICAgICAgICB3aWR0aCA9IDAuMjVcbiAqXG4gKiAgICstLS0tLSsgICAgICAgICAgICArLS0tLS0tLSsgICAgICAgKyAgICArLS0tLS0tLSsgICAgICstK1xuICogICB8ICAgICB8ICAgICAgICAgICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgICAgICB8ICAgICB8XG4gKiAgIHwgICAgIHwgICAgICAgICAgICB8ICAgICAgIHwgICAgICAgfCAgICAgICAgICAgIHwgICAgIHxcbiAqICstKyAgICAgKy0tLS0tLS0rICAgICsgICAgICAgKy0tLS0tLS0rICAgICAgICAgICAgKy0tLS0tK1xuICpcbiAqXG4gKiAgICB3aWR0aCA9IC0wLjUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDAuNVxuICpcbiAqICAgICArLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKyAgICstLS0rXG4gKiAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8XG4gKiAgICAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICB8XG4gKiArLS0tKyAgICstLS0tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0rXG4gKlxuICpcbiAqICAgIHdpZHRoID0gLTAuNzUgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC43NVxuICpcbiAqICAgICAgICstKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKyArLS0tLS0rXG4gKiAgICAgICB8IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgfFxuICogICAgICAgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHxcbiAqICstLS0tLSsgKy0tLS0tLS0rICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgcHVsc2UgPSBuZXcgVG9uZS5QdWxzZU9zY2lsbGF0b3IoNTAsIDAuNCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUHVsc2VPc2NpbGxhdG9yIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwid2lkdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQdWxzZU9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGdhdGUgdGhlIHdpZHRoIGFtb3VudFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaHJlc2hvbGQgdGhlIHNpZ25hbCB0byB0dXJuIGl0IGludG8gYSBzcXVhcmVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3RocmVzaCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHZhbCA9PiB2YWwgPD0gMCA/IC0xIDogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQdWxzZU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImF1ZGlvUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLndpZHRoLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG9uc3RvcDogKCkgPT4gdGhpcy5vbnN0b3AodGhpcyksXG4gICAgICAgICAgICBwaGFzZTogb3B0aW9ucy5waGFzZSxcbiAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fdHJpYW5nbGUuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX3RyaWFuZ2xlLmRldHVuZTtcbiAgICAgICAgLy8gY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUuY2hhaW4odGhpcy5fdGhyZXNoLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIHRoaXMud2lkdGguY2hhaW4odGhpcy5fd2lkdGhHYXRlLCB0aGlzLl90aHJlc2gpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3aWR0aFwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInB1bHNlXCIsXG4gICAgICAgICAgICB3aWR0aDogMC4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAqL1xuICAgIF9zdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5zdG9wKHRpbWUpO1xuICAgICAgICAvLyB0aGUgd2lkdGggaXMgc3RpbGwgY29ubmVjdGVkIHRvIHRoZSBvdXRwdXQuXG4gICAgICAgIC8vIHRoYXQgbmVlZHMgdG8gYmUgc3RvcHBlZCBhbHNvXG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5nYWluLmNhbmNlbFNjaGVkdWxlZFZhbHVlcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uc2V0VmFsdWVBdFRpbWUoMCwgdGltZSk7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUucmVzdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fd2lkdGhHYXRlLmdhaW4uY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl93aWR0aEdhdGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHJpYW5nbGUucGhhc2U7XG4gICAgfVxuICAgIHNldCBwaGFzZShwaGFzZSkge1xuICAgICAgICB0aGlzLl90cmlhbmdsZS5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwdWxzZVwiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gXCJwdWxzZVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZVR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuIEFsd2F5cyByZXR1cm5zIFwicHVsc2VcIi5cbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB1bHNlXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwYXJ0aWFscyBvZiB0aGUgd2F2ZWZvcm0uIENhbm5vdCBzZXQgcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBObyBwYXJ0aWFscyBmb3IgdGhpcyB3YXZlZm9ybSB0eXBlLlxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAqSW50ZXJuYWwgdXNlKiBUaGUgY2FycmllciBvc2NpbGxhdG9yIHR5cGUgaXMgZmVkIHRocm91Z2ggdGhlXG4gICAgICogd2F2ZXNoYXBlciBub2RlIHRvIGNyZWF0ZSB0aGUgcHVsc2UuIFVzaW5nIGRpZmZlcmVudCBjYXJyaWVyIG9zY2lsbGF0b3JzXG4gICAgICogY2hhbmdlcyBvc2NpbGxhdG9yJ3MgYmVoYXZpb3IuXG4gICAgICovXG4gICAgc2V0IGNhcnJpZXJUeXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fdHJpYW5nbGUudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwIG1ldGhvZC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RyaWFuZ2xlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3dpZHRoR2F0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3RocmVzaC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVB1bHNlT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCwgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVdhdmVmb3JtIH0gZnJvbSBcIi4vT3NjaWxsYXRvckludGVyZmFjZVwiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEZhdE9zY2lsbGF0b3IgaXMgYW4gYXJyYXkgb2Ygb3NjaWxsYXRvcnMgd2l0aCBkZXR1bmUgc3ByZWFkIGJldHdlZW4gdGhlIG9zY2lsbGF0b3JzXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZmF0T3NjID0gbmV3IFRvbmUuRmF0T3NjaWxsYXRvcihcIkFiM1wiLCBcInNhd3Rvb3RoXCIsIDQwKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIEZhdE9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGYXRPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInNwcmVhZFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZhdE9zY2lsbGF0b3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhcnJheSBvZiBvc2NpbGxhdG9yc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCIsIFwic3ByZWFkXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgICAgICB0aGlzLl9wYXJ0aWFscyA9IG9wdGlvbnMucGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3BhcnRpYWxDb3VudCA9IG9wdGlvbnMucGFydGlhbENvdW50O1xuICAgICAgICAvLyBzZXQgdGhlIGNvdW50IGluaXRpYWxseVxuICAgICAgICB0aGlzLmNvdW50ID0gb3B0aW9ucy5jb3VudDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNvdW50OiAzLFxuICAgICAgICAgICAgc3ByZWFkOiAyMCxcbiAgICAgICAgICAgIHR5cGU6IFwic2F3dG9vdGhcIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2Muc3RhcnQodGltZSkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdG9wIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5zdG9wKHRpbWUpKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MucmVzdGFydCh0aW1lKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIG9zY2lsbGF0b3JzXG4gICAgICovXG4gICAgX2ZvckVhY2goaXRlcmF0b3IpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9vc2NpbGxhdG9ycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaXRlcmF0b3IodGhpcy5fb3NjaWxsYXRvcnNbaV0sIGkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MudHlwZSA9IHR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycy4gSWYgXCJjb3VudFwiIGlzXG4gICAgICogc2V0IHRvIDMgb3NjaWxsYXRvcnMgYW5kIHRoZSBcInNwcmVhZFwiIGlzIHNldCB0byA0MCxcbiAgICAgKiB0aGUgdGhyZWUgb3NjaWxsYXRvcnMgd291bGQgYmUgZGV0dW5lZCBsaWtlIHRoaXM6IFstMjAsIDAsIDIwXVxuICAgICAqIGZvciBhIHRvdGFsIGRldHVuZSBzcHJlYWQgb2YgNDAgY2VudHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKCkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogZmF0T3NjLnNwcmVhZCA9IDcwO1xuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zcHJlYWQ7XG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX3NwcmVhZCA9IHNwcmVhZDtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gLXNwcmVhZCAvIDI7XG4gICAgICAgICAgICBjb25zdCBzdGVwID0gc3ByZWFkIC8gKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaCgob3NjLCBpKSA9PiBvc2MuZGV0dW5lLnZhbHVlID0gc3RhcnQgKyBzdGVwICogaSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBkZXR1bmVkIG9zY2lsbGF0b3JzLiBNdXN0IGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDEuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmYXRPc2MgPSBuZXcgVG9uZS5GYXRPc2NpbGxhdG9yKFwiQyMzXCIsIFwic2F3dG9vdGhcIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gICAgICogLy8gdXNlIDQgc2F3dG9vdGggb3NjaWxsYXRvcnNcbiAgICAgKiBmYXRPc2MuY291bnQgPSA0O1xuICAgICAqL1xuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aDtcbiAgICB9XG4gICAgc2V0IGNvdW50KGNvdW50KSB7XG4gICAgICAgIGFzc2VydFJhbmdlKGNvdW50LCAxKTtcbiAgICAgICAgaWYgKHRoaXMuX29zY2lsbGF0b3JzLmxlbmd0aCAhPT0gY291bnQpIHtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2UgdGhlIHByZXZpb3VzIG9zY2lsbGF0b3JzXG4gICAgICAgICAgICB0aGlzLl9mb3JFYWNoKG9zYyA9PiBvc2MuZGlzcG9zZSgpKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvc2MgPSBuZXcgT3NjaWxsYXRvcih7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgdm9sdW1lOiAtNiAtIGNvdW50ICogMS4xLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiB0aGlzLl90eXBlLFxuICAgICAgICAgICAgICAgICAgICBwaGFzZTogdGhpcy5fcGhhc2UgKyAoaSAvIGNvdW50KSAqIDM2MCxcbiAgICAgICAgICAgICAgICAgICAgcGFydGlhbENvdW50OiB0aGlzLl9wYXJ0aWFsQ291bnQsXG4gICAgICAgICAgICAgICAgICAgIG9uc3RvcDogaSA9PT0gMCA/ICgpID0+IHRoaXMub25zdG9wKHRoaXMpIDogbm9PcCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy50eXBlID09PSBcImN1c3RvbVwiKSB7XG4gICAgICAgICAgICAgICAgICAgIG9zYy5wYXJ0aWFscyA9IHRoaXMuX3BhcnRpYWxzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KG9zYy5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3Qob3NjLmRldHVuZSk7XG4gICAgICAgICAgICAgICAgb3NjLmRldHVuZS5vdmVycmlkZGVuID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgb3NjLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3JzW2ldID0gb3NjO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gc2V0IHRoZSBzcHJlYWRcbiAgICAgICAgICAgIHRoaXMuc3ByZWFkID0gdGhpcy5fc3ByZWFkO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwaGFzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fcGhhc2UgPSBwaGFzZTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaCgob3NjLCBpKSA9PiBvc2MucGhhc2UgPSB0aGlzLl9waGFzZSArIChpIC8gdGhpcy5jb3VudCkgKiAzNjApO1xuICAgIH1cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yc1swXS5iYXNlVHlwZTtcbiAgICB9XG4gICAgc2V0IGJhc2VUeXBlKGJhc2VUeXBlKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5iYXNlVHlwZSA9IGJhc2VUeXBlKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHRoaXMuX29zY2lsbGF0b3JzWzBdLnR5cGU7XG4gICAgfVxuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLnBhcnRpYWxzO1xuICAgIH1cbiAgICBzZXQgcGFydGlhbHMocGFydGlhbHMpIHtcbiAgICAgICAgdGhpcy5fcGFydGlhbHMgPSBwYXJ0aWFscztcbiAgICAgICAgdGhpcy5fcGFydGlhbENvdW50ID0gdGhpcy5fcGFydGlhbHMubGVuZ3RoO1xuICAgICAgICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLl90eXBlID0gXCJjdXN0b21cIjtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5wYXJ0aWFscyA9IHBhcnRpYWxzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0ucGFydGlhbENvdW50O1xuICAgIH1cbiAgICBzZXQgcGFydGlhbENvdW50KHBhcnRpYWxDb3VudCkge1xuICAgICAgICB0aGlzLl9wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQ7XG4gICAgICAgIHRoaXMuX2ZvckVhY2gob3NjID0+IG9zYy5wYXJ0aWFsQ291bnQgPSBwYXJ0aWFsQ291bnQpO1xuICAgICAgICB0aGlzLl90eXBlID0gdGhpcy5fb3NjaWxsYXRvcnNbMF0udHlwZTtcbiAgICB9XG4gICAgYXNBcnJheShsZW5ndGggPSAxMDI0KSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2VuZXJhdGVXYXZlZm9ybSh0aGlzLCBsZW5ndGgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZhdE9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuL09zY2lsbGF0b3JcIjtcbmltcG9ydCB7IGdlbmVyYXRlV2F2ZWZvcm0gfSBmcm9tIFwiLi9Pc2NpbGxhdG9ySW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBQdWxzZU9zY2lsbGF0b3IgfSBmcm9tIFwiLi9QdWxzZU9zY2lsbGF0b3JcIjtcbi8qKlxuICogUFdNT3NjaWxsYXRvciBtb2R1bGF0ZXMgdGhlIHdpZHRoIG9mIGEgVG9uZS5QdWxzZU9zY2lsbGF0b3JcbiAqIGF0IHRoZSBtb2R1bGF0aW9uRnJlcXVlbmN5LiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGNvbnRpbnVvdXNseVxuICogY2hhbmdpbmcgdGhlIHRpbWJyZSBvZiB0aGUgb3NjaWxsYXRvciBieSBhbHRlcmluZyB0aGUgaGFybW9uaWNzXG4gKiBnZW5lcmF0ZWQuXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IHB3bSA9IG5ldyBUb25lLlBXTU9zY2lsbGF0b3IoNjAsIDAuMykudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUFdNT3NjaWxsYXRvciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtb2R1bGF0aW9uRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUFdNT3NjaWxsYXRvclwiO1xuICAgICAgICB0aGlzLnNvdXJjZVR5cGUgPSBcInB3bVwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogU2NhbGUgdGhlIG9zY2lsbGF0b3Igc28gaXQgZG9lc24ndCBnbyBzaWxlbnRcbiAgICAgICAgICogYXQgdGhlIGV4dHJlbWUgdmFsdWVzLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2NhbGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDIsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUFdNT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm1vZHVsYXRpb25GcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9wdWxzZSA9IG5ldyBQdWxzZU9zY2lsbGF0b3Ioe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLm1vZHVsYXRpb25GcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjaGFuZ2UgdGhlIHB1bHNlIG9zY2lsbGF0b3IgdHlwZVxuICAgICAgICB0aGlzLl9wdWxzZS5jYXJyaWVyVHlwZSA9IFwic2luZVwiO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25GcmVxdWVuY3kgPSB0aGlzLl9wdWxzZS5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvciA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKSxcbiAgICAgICAgICAgIHBoYXNlOiBvcHRpb25zLnBoYXNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRldHVuZSA9IHRoaXMuX21vZHVsYXRvci5kZXR1bmU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5jaGFpbih0aGlzLl9zY2FsZSwgdGhpcy5fcHVsc2Uud2lkdGgpO1xuICAgICAgICB0aGlzLl9wdWxzZS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wibW9kdWxhdGlvbkZyZXF1ZW5jeVwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogNDQwLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkZyZXF1ZW5jeTogMC40LFxuICAgICAgICAgICAgcGhhc2U6IDAsXG4gICAgICAgICAgICB0eXBlOiBcInB3bVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RhcnQodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fcHVsc2Uuc3RhcnQodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0b3AgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnN0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3B1bHNlLnN0b3AodGltZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJlc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfcmVzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5yZXN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9wdWxzZS5yZXN0YXJ0KHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwd21cIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIFwicHdtXCI7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBiYXNlVHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQWx3YXlzIHJldHVybnMgXCJwd21cIi5cbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiBcInB3bVwiO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGFydGlhbHMgb2YgdGhlIHdhdmVmb3JtLiBDYW5ub3Qgc2V0IHBhcnRpYWxzIGZvciB0aGlzIHdhdmVmb3JtIHR5cGVcbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbHMoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTm8gcGFydGlhbHMgZm9yIHRoaXMgd2F2ZWZvcm0gdHlwZS5cbiAgICAgKi9cbiAgICBnZXQgcGFydGlhbENvdW50KCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBoYXNlIG9mIHRoZSBvc2NpbGxhdG9yIGluIGRlZ3JlZXMuXG4gICAgICovXG4gICAgZ2V0IHBoYXNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbW9kdWxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLnBoYXNlID0gcGhhc2U7XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcHVsc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBXTU9zY2lsbGF0b3IuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGlzTnVtYmVyLCBpc1N0cmluZyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgQU1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vQU1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBGYXRPc2NpbGxhdG9yIH0gZnJvbSBcIi4vRmF0T3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgRk1Pc2NpbGxhdG9yIH0gZnJvbSBcIi4vRk1Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBPc2NpbGxhdG9yIH0gZnJvbSBcIi4vT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVXYXZlZm9ybSB9IGZyb20gXCIuL09zY2lsbGF0b3JJbnRlcmZhY2VcIjtcbmltcG9ydCB7IFB1bHNlT3NjaWxsYXRvciB9IGZyb20gXCIuL1B1bHNlT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgUFdNT3NjaWxsYXRvciB9IGZyb20gXCIuL1BXTU9zY2lsbGF0b3JcIjtcbmNvbnN0IE9tbmlPc2NpbGxhdG9yU291cmNlTWFwID0ge1xuICAgIGFtOiBBTU9zY2lsbGF0b3IsXG4gICAgZmF0OiBGYXRPc2NpbGxhdG9yLFxuICAgIGZtOiBGTU9zY2lsbGF0b3IsXG4gICAgb3NjaWxsYXRvcjogT3NjaWxsYXRvcixcbiAgICBwdWxzZTogUHVsc2VPc2NpbGxhdG9yLFxuICAgIHB3bTogUFdNT3NjaWxsYXRvcixcbn07XG4vKipcbiAqIE9tbmlPc2NpbGxhdG9yIGFnZ3JlZ2F0ZXMgYWxsIG9mIHRoZSBvc2NpbGxhdG9yIHR5cGVzIGludG8gb25lLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoXCJDIzRcIiwgXCJwd21cIikudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiB9LCAwLjEsIDEpO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgT21uaU9zY2lsbGF0b3IgZXh0ZW5kcyBTb3VyY2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJPbW5pT3NjaWxsYXRvclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIl0pO1xuICAgICAgICAvLyBzZXQgdGhlIG9wdGlvbnNcbiAgICAgICAgdGhpcy5zZXQob3B0aW9ucyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBGTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgQU1Pc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIEZhdE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgUHVsc2VPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFBXTU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSBvc2NpbGxhdG9yXG4gICAgICovXG4gICAgX3N0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIG9zY2lsbGF0b3JcbiAgICAgKi9cbiAgICBfc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICB9XG4gICAgX3Jlc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnJlc3RhcnQodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gQ2FuIGJlIGFueSBvZiB0aGUgYmFzaWMgdHlwZXM6IHNpbmUsIHNxdWFyZSwgdHJpYW5nbGUsIHNhd3Rvb3RoLiBPclxuICAgICAqIHByZWZpeCB0aGUgYmFzaWMgdHlwZXMgd2l0aCBcImZtXCIsIFwiYW1cIiwgb3IgXCJmYXRcIiB0byB1c2UgdGhlIEZNT3NjaWxsYXRvciwgQU1Pc2NpbGxhdG9yIG9yIEZhdE9zY2lsbGF0b3JcbiAgICAgKiB0eXBlcy4gVGhlIG9zY2lsbGF0b3IgY291bGQgYWxzbyBiZSBzZXQgdG8gXCJwd21cIiBvciBcInB1bHNlXCIuIEFsbCBvZiB0aGUgcGFyYW1ldGVycyBvZiB0aGVcbiAgICAgKiBvc2NpbGxhdG9yJ3MgY2xhc3MgYXJlIGFjY2Vzc2libGUgd2hlbiB0aGUgb3NjaWxsYXRvciBpcyBzZXQgdG8gdGhhdCB0eXBlLCBidXQgdGhyb3dzIGFuIGVycm9yXG4gICAgICogd2hlbiBpdCdzIG5vdC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IG9tbmlPc2MgPSBuZXcgVG9uZS5PbW5pT3NjaWxsYXRvcigpLnRvRGVzdGluYXRpb24oKS5zdGFydCgpO1xuICAgICAqIG9tbmlPc2MudHlwZSA9IFwicHdtXCI7XG4gICAgICogLy8gbW9kdWxhdGlvbkZyZXF1ZW5jeSBpcyBwYXJhbWV0ZXIgd2hpY2ggaXMgYXZhaWxhYmxlXG4gICAgICogLy8gb25seSB3aGVuIHRoZSB0eXBlIGlzIFwicHdtXCIuXG4gICAgICogb21uaU9zYy5tb2R1bGF0aW9uRnJlcXVlbmN5LnZhbHVlID0gMC41O1xuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICBsZXQgcHJlZml4ID0gXCJcIjtcbiAgICAgICAgaWYgKFtcImFtXCIsIFwiZm1cIiwgXCJmYXRcIl0uc29tZShwID0+IHRoaXMuX3NvdXJjZVR5cGUgPT09IHApKSB7XG4gICAgICAgICAgICBwcmVmaXggPSB0aGlzLl9zb3VyY2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcmVmaXggKyB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgaWYgKHR5cGUuc3Vic3RyKDAsIDIpID09PSBcImZtXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX2NyZWF0ZU5ld09zY2lsbGF0b3IoXCJmbVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZS5zdWJzdHIoMCwgMikgPT09IFwiYW1cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImFtXCIpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvciA9IHRoaXMuX29zY2lsbGF0b3I7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnR5cGUgPSB0eXBlLnN1YnN0cigyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlLnN1YnN0cigwLCAzKSA9PT0gXCJmYXRcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcImZhdFwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZS5zdWJzdHIoMyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PT0gXCJwd21cIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcInB3bVwiKTtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IgPSB0aGlzLl9vc2NpbGxhdG9yO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT09IFwicHVsc2VcIikge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcInB1bHNlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fY3JlYXRlTmV3T3NjaWxsYXRvcihcIm9zY2lsbGF0b3JcIik7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IudHlwZSA9IHR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHZhbHVlIGlzIGFuIGVtcHR5IGFycmF5IHdoZW4gdGhlIHR5cGUgaXMgbm90IFwiY3VzdG9tXCIuXG4gICAgICogVGhpcyBpcyBub3QgYXZhaWxhYmxlIG9uIFwicHdtXCIgYW5kIFwicHVsc2VcIiBvc2NpbGxhdG9yIHR5cGVzLlxuICAgICAqIFNlZSBbW09zY2lsbGF0b3IucGFydGlhbHNdXVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICBpZiAoIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSAmJiAhdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcInB3bVwiKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5wYXJ0aWFscyA9IHBhcnRpYWxzO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwYXJ0aWFsQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxDb3VudDtcbiAgICB9XG4gICAgc2V0IHBhcnRpYWxDb3VudChwYXJ0aWFsQ291bnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiYgIXRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbENvdW50ID0gcGFydGlhbENvdW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldChwcm9wcykge1xuICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIHR5cGUgaXMgc2V0IGZpcnN0XG4gICAgICAgIGlmIChSZWZsZWN0Lmhhcyhwcm9wcywgXCJ0eXBlXCIpICYmIHByb3BzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IHByb3BzLnR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlbiBzZXQgdGhlIHJlc3RcbiAgICAgICAgc3VwZXIuc2V0KHByb3BzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3IgdG8gdGhlIGZyZXF1ZW5jeSBhbmQgZGV0dW5lIHNpZ25hbHNcbiAgICAgKi9cbiAgICBfY3JlYXRlTmV3T3NjaWxsYXRvcihvc2NUeXBlKSB7XG4gICAgICAgIGlmIChvc2NUeXBlICE9PSB0aGlzLl9zb3VyY2VUeXBlKSB7XG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VUeXBlID0gb3NjVHlwZTtcbiAgICAgICAgICAgIGNvbnN0IE9zY0NvbnN0cnVjdG9yID0gT21uaU9zY2lsbGF0b3JTb3VyY2VNYXBbb3NjVHlwZV07XG4gICAgICAgICAgICAvLyBzaG9ydCBkZWxheSB0byBhdm9pZCBjbGlja3Mgb24gdGhlIGNoYW5nZVxuICAgICAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vc2NpbGxhdG9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb2xkT3NjID0gdGhpcy5fb3NjaWxsYXRvcjtcbiAgICAgICAgICAgICAgICBvbGRPc2Muc3RvcChub3cpO1xuICAgICAgICAgICAgICAgIC8vIGRpc3Bvc2UgdGhlIG9sZCBvbmVcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQuc2V0VGltZW91dCgoKSA9PiBvbGRPc2MuZGlzcG9zZSgpLCB0aGlzLmJsb2NrVGltZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY0NvbnN0cnVjdG9yKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdCh0aGlzLl9vc2NpbGxhdG9yLmRldHVuZSk7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5vbnN0b3AgPSAoKSA9PiB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RhcnQobm93KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc291cmNlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3IuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoNDQwLCBcImZtc3F1YXJlXCIpO1xuICAgICAqIGNvbnNvbGUubG9nKG9tbmlPc2Muc291cmNlVHlwZSk7IC8vICdmbSdcbiAgICAgKi9cbiAgICBnZXQgc291cmNlVHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvdXJjZVR5cGU7XG4gICAgfVxuICAgIHNldCBzb3VyY2VUeXBlKHNUeXBlKSB7XG4gICAgICAgIC8vIHRoZSBiYXNldHlwZSBkZWZhdWx0cyB0byBzaW5lXG4gICAgICAgIGxldCBiYXNlVHlwZSA9IFwic2luZVwiO1xuICAgICAgICBpZiAodGhpcy5fb3NjaWxsYXRvci50eXBlICE9PSBcInB3bVwiICYmIHRoaXMuX29zY2lsbGF0b3IudHlwZSAhPT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICBiYXNlVHlwZSA9IHRoaXMuX29zY2lsbGF0b3IudHlwZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHR5cGVcbiAgICAgICAgaWYgKHNUeXBlID09PSBcImZtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiZm1cIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcImFtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwiYW1cIiArIGJhc2VUeXBlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNUeXBlID09PSBcImZhdFwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcImZhdFwiICsgYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwib3NjaWxsYXRvclwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBiYXNlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzVHlwZSA9PT0gXCJwdWxzZVwiKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSBcInB1bHNlXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc1R5cGUgPT09IFwicHdtXCIpIHtcbiAgICAgICAgICAgIHRoaXMudHlwZSA9IFwicHdtXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2dldE9zY1R5cGUob3NjLCBzb3VyY2VUeXBlKSB7XG4gICAgICAgIHJldHVybiBvc2MgaW5zdGFuY2VvZiBPbW5pT3NjaWxsYXRvclNvdXJjZU1hcFtzb3VyY2VUeXBlXTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGJhc2UgdHlwZSBvZiB0aGUgb3NjaWxsYXRvci4gU2VlIFtbT3NjaWxsYXRvci5iYXNlVHlwZV1dXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBvbW5pT3NjID0gbmV3IFRvbmUuT21uaU9zY2lsbGF0b3IoNDQwLCBcImZtc3F1YXJlNFwiKTtcbiAgICAgKiBjb25zb2xlLmxvZyhvbW5pT3NjLnNvdXJjZVR5cGUsIG9tbmlPc2MuYmFzZVR5cGUsIG9tbmlPc2MucGFydGlhbENvdW50KTtcbiAgICAgKi9cbiAgICBnZXQgYmFzZVR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmJhc2VUeXBlO1xuICAgIH1cbiAgICBzZXQgYmFzZVR5cGUoYmFzZVR5cGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHVsc2VcIikgJiZcbiAgICAgICAgICAgICF0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwicHdtXCIpICYmXG4gICAgICAgICAgICBiYXNlVHlwZSAhPT0gXCJwdWxzZVwiICYmIGJhc2VUeXBlICE9PSBcInB3bVwiKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmJhc2VUeXBlID0gYmFzZVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHdpZHRoIG9mIHRoZSBvc2NpbGxhdG9yIHdoZW4gc291cmNlVHlwZSA9PT0gXCJwdWxzZVwiLlxuICAgICAqIFNlZSBbW1BXTU9zY2lsbGF0b3Iud2lkdGhdXVxuICAgICAqL1xuICAgIGdldCB3aWR0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwdWxzZVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3Iud2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgZGV0dW5lZCBvc2NpbGxhdG9ycyB3aGVuIHNvdXJjZVR5cGUgPT09IFwiZmF0XCIuXG4gICAgICogU2VlIFtbRmF0T3NjaWxsYXRvci5jb3VudF1dXG4gICAgICovXG4gICAgZ2V0IGNvdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IuY291bnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBjb3VudChjb3VudCkge1xuICAgICAgICBpZiAodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZhdFwiKSAmJiBpc051bWJlcihjb3VudCkpIHtcbiAgICAgICAgICAgIHRoaXMuX29zY2lsbGF0b3IuY291bnQgPSBjb3VudDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGV0dW5lIHNwcmVhZCBiZXR3ZWVuIHRoZSBvc2NpbGxhdG9ycyB3aGVuIHNvdXJjZVR5cGUgPT09IFwiZmF0XCIuXG4gICAgICogU2VlIFtbRmF0T3NjaWxsYXRvci5jb3VudF1dXG4gICAgICovXG4gICAgZ2V0IHNwcmVhZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnNwcmVhZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmYXRcIikgJiYgaXNOdW1iZXIoc3ByZWFkKSkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zcHJlYWQgPSBzcHJlYWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG1vZHVsYXRvciBvc2NpbGxhdG9yLiBPbmx5IGlmIHRoZSBvc2NpbGxhdG9yIGlzIHNldCB0byBcImFtXCIgb3IgXCJmbVwiIHR5cGVzLlxuICAgICAqIFNlZSBbW0FNT3NjaWxsYXRvcl1dIG9yIFtbRk1Pc2NpbGxhdG9yXV1cbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvblR5cGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiZm1cIikgfHwgdGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImFtXCIpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5tb2R1bGF0aW9uVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25UeXBlKG1UeXBlKSB7XG4gICAgICAgIGlmICgodGhpcy5fZ2V0T3NjVHlwZSh0aGlzLl9vc2NpbGxhdG9yLCBcImZtXCIpIHx8IHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJhbVwiKSkgJiYgaXNTdHJpbmcobVR5cGUpKSB7XG4gICAgICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25UeXBlID0gbVR5cGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb24gaW5kZXggd2hlbiB0aGUgc291cmNlVHlwZSA9PT0gXCJmbVwiXG4gICAgICogU2VlIFtbRk1Pc2NpbGxhdG9yXV0uXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25JbmRleCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IubW9kdWxhdGlvbkluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBIYXJtb25pY2l0eSBpcyB0aGUgZnJlcXVlbmN5IHJhdGlvIGJldHdlZW4gdGhlIGNhcnJpZXIgYW5kIHRoZSBtb2R1bGF0b3Igb3NjaWxsYXRvcnMuXG4gICAgICogU2VlIFtbQU1Pc2NpbGxhdG9yXV0gb3IgW1tGTU9zY2lsbGF0b3JdXVxuICAgICAqL1xuICAgIGdldCBoYXJtb25pY2l0eSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJmbVwiKSB8fCB0aGlzLl9nZXRPc2NUeXBlKHRoaXMuX29zY2lsbGF0b3IsIFwiYW1cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLmhhcm1vbmljaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbW9kdWxhdGlvbkZyZXF1ZW5jeSBTaWduYWwgb2YgdGhlIG9zY2lsbGF0b3Igd2hlbiBzb3VyY2VUeXBlID09PSBcInB3bVwiXG4gICAgICogc2VlIFtbUFdNT3NjaWxsYXRvcl1dXG4gICAgICogQG1pbiAwLjFcbiAgICAgKiBAbWF4IDVcbiAgICAgKi9cbiAgICBnZXQgbW9kdWxhdGlvbkZyZXF1ZW5jeSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2dldE9zY1R5cGUodGhpcy5fb3NjaWxsYXRvciwgXCJwd21cIikpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLm1vZHVsYXRpb25GcmVxdWVuY3k7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgcmV0dXJuIGdlbmVyYXRlV2F2ZWZvcm0odGhpcywgbGVuZ3RoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbW5pT3NjaWxsYXRvci5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuL1NpZ25hbFwiO1xuLyoqXG4gKiBBZGQgYSBzaWduYWwgYW5kIGEgbnVtYmVyIG9yIHR3byBzaWduYWxzLiBXaGVuIG5vIHZhbHVlIGlzXG4gKiBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIFRvbmUuQWRkIHdpbGwgc3VtIGlucHV0IGFuZCBgYWRkZW5kYFxuICogSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW50byB0aGUgY29uc3RydWN0b3IsIHRoZSBpdCB3aWxsIGJlIGFkZGVkIHRvIHRoZSBpbnB1dC5cbiAqXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGFkZCA9IG5ldyBUb25lLkFkZCgyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdGFkZC5hZGRlbmQuc2V0VmFsdWVBdFRpbWUoMSwgMC4yKTtcbiAqIFx0Y29uc3Qgc2lnbmFsID0gbmV3IFRvbmUuU2lnbmFsKDIpO1xuICogXHQvLyBhZGQgYSBzaWduYWwgYW5kIGEgc2NhbGFyXG4gKiBcdHNpZ25hbC5jb25uZWN0KGFkZCk7XG4gKiBcdHNpZ25hbC5zZXRWYWx1ZUF0VGltZSgxLCAwLjEpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEFkZCBleHRlbmRzIFNpZ25hbCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoQWRkLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pKSk7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJBZGRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzdW1taW5nIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N1bSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB3aGljaCBpcyBhZGRlZCB0byB0aGUgaW5wdXQgc2lnbmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmFkZGVuZCA9IHRoaXMuX3BhcmFtO1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuX2NvbnN0YW50U291cmNlLCB0aGlzLl9zdW0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWRkLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4vQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFBlcmZvcm1zIGEgbGluZWFyIHNjYWxpbmcgb24gYW4gaW5wdXQgc2lnbmFsLlxuICogU2NhbGVzIGEgTm9ybWFsUmFuZ2UgaW5wdXQgdG8gYmV0d2VlblxuICogb3V0cHV0TWluIGFuZCBvdXRwdXRNYXguXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNjYWxlID0gbmV3IFRvbmUuU2NhbGUoNTAsIDEwMCk7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlKTtcbiAqIC8vIHRoZSBvdXRwdXQgb2Ygc2NhbGUgZXF1YWxzIDc1XG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBTY2FsZSBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTY2FsZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm1pblwiLCBcIm1heFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTY2FsZVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2NhbGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJtaW5cIiwgXCJtYXhcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0ID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5tYXggLSBvcHRpb25zLm1pbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2FkZCA9IHRoaXMub3V0cHV0ID0gbmV3IEFkZCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5taW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taW4gPSBvcHRpb25zLm1pbjtcbiAgICAgICAgdGhpcy5fbWF4ID0gb3B0aW9ucy5tYXg7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gb3V0cHV0IHZhbHVlLiBUaGlzIG51bWJlciBpcyBvdXRwdXQgd2hlbiB0aGUgdmFsdWUgaW5wdXQgdmFsdWUgaXMgMC5cbiAgICAgKi9cbiAgICBnZXQgbWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWluO1xuICAgIH1cbiAgICBzZXQgbWluKG1pbikge1xuICAgICAgICB0aGlzLl9taW4gPSBtaW47XG4gICAgICAgIHRoaXMuX3NldFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIG91dHB1dCB2YWx1ZS4gVGhpcyBudW1iZXIgaXMgb3V0cHV0IHdoZW4gdGhlIHZhbHVlIGlucHV0IHZhbHVlIGlzIDEuXG4gICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heDtcbiAgICB9XG4gICAgc2V0IG1heChtYXgpIHtcbiAgICAgICAgdGhpcy5fbWF4ID0gbWF4O1xuICAgICAgICB0aGlzLl9zZXRSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXQgdGhlIHZhbHVlc1xuICAgICAqL1xuICAgIF9zZXRSYW5nZSgpIHtcbiAgICAgICAgdGhpcy5fYWRkLnZhbHVlID0gdGhpcy5fbWluO1xuICAgICAgICB0aGlzLl9tdWx0LnZhbHVlID0gdGhpcy5fbWF4IC0gdGhpcy5fbWluO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX211bHQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TY2FsZS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBkaXNjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbi8qKlxuICogVG9uZS5aZXJvIG91dHB1dHMgMCdzIGF0IGF1ZGlvLXJhdGUuIFRoZSByZWFzb24gdGhpcyBoYXMgdG8gYmVcbiAqIGl0J3Mgb3duIGNsYXNzIGlzIHRoYXQgbWFueSBicm93c2VycyBvcHRpbWl6ZSBvdXQgVG9uZS5TaWduYWxcbiAqIHdpdGggYSB2YWx1ZSBvZiAwIGFuZCB3aWxsIG5vdCBwcm9jZXNzIG5vZGVzIGZ1cnRoZXIgZG93biB0aGUgZ3JhcGguXG4gKiBAY2F0ZWdvcnkgU2lnbmFsXG4gKi9cbmV4cG9ydCBjbGFzcyBaZXJvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFplcm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlplcm9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBnYWluIG5vZGUgd2hpY2ggY29ubmVjdHMgdGhlIGNvbnN0YW50IHNvdXJjZSB0byB0aGUgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nYWluID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPbmx5IG91dHB1dHMgMFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluO1xuICAgICAgICAvKipcbiAgICAgICAgICogbm8gaW5wdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMCksIHRoaXMuX2dhaW4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgZGlzY29ubmVjdCh0aGlzLmNvbnRleHQuZ2V0Q29uc3RhbnQoMCksIHRoaXMuX2dhaW4pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1aZXJvLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi8uLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgY29ubmVjdFNpZ25hbCwgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IFplcm8gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1plcm9cIjtcbmltcG9ydCB7IE9zY2lsbGF0b3IgfSBmcm9tIFwiLi9Pc2NpbGxhdG9yXCI7XG4vKipcbiAqIExGTyBzdGFuZHMgZm9yIGxvdyBmcmVxdWVuY3kgb3NjaWxsYXRvci4gTEZPIHByb2R1Y2VzIGFuIG91dHB1dCBzaWduYWxcbiAqIHdoaWNoIGNhbiBiZSBhdHRhY2hlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsXG4gKiBpbiBvcmRlciB0byBtb2R1bGF0ZSB0aGF0IHBhcmFtZXRlciB3aXRoIGFuIG9zY2lsbGF0b3IuIFRoZSBMRk8gY2FuXG4gKiBhbHNvIGJlIHN5bmNlZCB0byB0aGUgdHJhbnNwb3J0IHRvIHN0YXJ0L3N0b3AgYW5kIGNoYW5nZSB3aGVuIHRoZSB0ZW1wbyBjaGFuZ2VzLlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBsZm8gPSBuZXcgVG9uZS5MRk8oXCI0blwiLCA0MDAsIDQwMDApLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICogfSwgMC41LCAxKTtcbiAqIEBjYXRlZ29yeSBTb3VyY2VcbiAqL1xuZXhwb3J0IGNsYXNzIExGTyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhMRk8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtaW5cIiwgXCJtYXhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMRk9cIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB0aGF0IHRoZSBMRk8gb3V0cHV0cyB3aGVuIGl0J3Mgc3RvcHBlZFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgcHJpdmF0ZSBwbGFjZWhvbGRlciBmb3IgdGhlIHVuaXRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl91bml0cyA9IFwibnVtYmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgaW5wdXQgdmFsdWUgaXMgY29udmVydGVkIHVzaW5nIHRoZSBbW3VuaXRzXV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuY29udmVydCA9IHRydWU7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcml2YXRlIG1ldGhvZHMgYm9ycm93ZWQgZnJvbSBQYXJhbVxuICAgICAgICAgKi9cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9mcm9tVHlwZSA9IFBhcmFtLnByb3RvdHlwZS5fZnJvbVR5cGU7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fdG9UeXBlID0gUGFyYW0ucHJvdG90eXBlLl90b1R5cGU7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5faXMgPSBQYXJhbS5wcm90b3R5cGUuX2lzO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX2NsYW1wVmFsdWUgPSBQYXJhbS5wcm90b3R5cGUuX2NsYW1wVmFsdWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMRk8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJtaW5cIiwgXCJtYXhcIl0pO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yID0gbmV3IE9zY2lsbGF0b3Iob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fb3NjaWxsYXRvci5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZUdhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmFtcGxpdHVkZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmFtcGxpdHVkZSA9IHRoaXMuX2FtcGxpdHVkZUdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbCA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiYXVkaW9SYW5nZVwiLFxuICAgICAgICAgICAgdmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl96ZXJvcyA9IG5ldyBaZXJvKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hMmcgPSBuZXcgQXVkaW9Ub0dhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3NjYWxlciA9IHRoaXMub3V0cHV0ID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heDogb3B0aW9ucy5tYXgsXG4gICAgICAgICAgICBtaW46IG9wdGlvbnMubWluLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51bml0cyA9IG9wdGlvbnMudW5pdHM7XG4gICAgICAgIHRoaXMubWluID0gb3B0aW9ucy5taW47XG4gICAgICAgIHRoaXMubWF4ID0gb3B0aW9ucy5tYXg7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5jaGFpbih0aGlzLl9hbXBsaXR1ZGVHYWluLCB0aGlzLl9hMmcsIHRoaXMuX3NjYWxlcik7XG4gICAgICAgIHRoaXMuX3plcm9zLmNvbm5lY3QodGhpcy5fYTJnKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5jb25uZWN0KHRoaXMuX2EyZyk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImFtcGxpdHVkZVwiLCBcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMucGhhc2UgPSBvcHRpb25zLnBoYXNlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYW1wbGl0dWRlOiAxLFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBcIjRuXCIsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIHVuaXRzOiBcIm51bWJlclwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIExGTy5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0aGUgTEZPIHdpbGwgc3RhcnRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5zZXRWYWx1ZUF0VGltZSgwLCB0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIExGTy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgdGhlIExGTyB3aWxsIHN0b3BcbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zdG9wcGVkU2lnbmFsLnNldFZhbHVlQXRUaW1lKHRoaXMuX3N0b3BwZWRWYWx1ZSwgdGltZSk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIHN0YXJ0L3N0b3AvcGF1c2UgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAqIGFuZCB0aGUgZnJlcXVlbmN5IHRvIHRoZSBicG0gb2YgdGhlIHRyYW5zcG9ydFxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgbGZvID0gbmV3IFRvbmUuTEZPKFwiOG5cIik7XG4gICAgICogbGZvLnN5bmMoKS5zdGFydCgwKTtcbiAgICAgKiAvLyB0aGUgcmF0ZSBvZiB0aGUgTEZPIHdpbGwgYWx3YXlzIGJlIGFuIGVpZ2h0aCBub3RlLCBldmVuIGFzIHRoZSB0ZW1wbyBjaGFuZ2VzXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5zeW5jKCk7XG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3Iuc3luY0ZyZXF1ZW5jeSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogdW5zeW5jIHRoZSBMRk8gZnJvbSB0cmFuc3BvcnQgY29udHJvbFxuICAgICAqL1xuICAgIHVuc3luYygpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmMoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci51bnN5bmNGcmVxdWVuY3koKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFmdGVyIHRoZSBvc2NpbGxhdG9yIHdhdmVmb3JtIGlzIHVwZGF0ZWQsIHJlc2V0IHRoZSBgX3N0b3BwZWRTaWduYWxgIHZhbHVlIHRvIG1hdGNoIHRoZSB1cGRhdGVkIHdhdmVmb3JtXG4gICAgICovXG4gICAgX3NldFN0b3BwZWRWYWx1ZSgpIHtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFZhbHVlID0gdGhpcy5fb3NjaWxsYXRvci5nZXRJbml0aWFsVmFsdWUoKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC52YWx1ZSA9IHRoaXMuX3N0b3BwZWRWYWx1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1pbmltdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IG1pbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9zY2FsZXIubWluKTtcbiAgICB9XG4gICAgc2V0IG1pbihtaW4pIHtcbiAgICAgICAgbWluID0gdGhpcy5fZnJvbVR5cGUobWluKTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLm1pbiA9IG1pbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1heGltdW0gb3V0cHV0IG9mIHRoZSBMRk8uXG4gICAgICovXG4gICAgZ2V0IG1heCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RvVHlwZSh0aGlzLl9zY2FsZXIubWF4KTtcbiAgICB9XG4gICAgc2V0IG1heChtYXgpIHtcbiAgICAgICAgbWF4ID0gdGhpcy5fZnJvbVR5cGUobWF4KTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLm1heCA9IG1heDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIG9zY2lsbGF0b3I6IFNlZSBbW09zY2lsbGF0b3IudHlwZV1dXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnR5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fc2V0U3RvcHBlZFZhbHVlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvc2NpbGxhdG9yJ3MgcGFydGlhbHMgYXJyYXk6IFNlZSBbW09zY2lsbGF0b3IucGFydGlhbHNdXVxuICAgICAqL1xuICAgIGdldCBwYXJ0aWFscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3IucGFydGlhbHM7XG4gICAgfVxuICAgIHNldCBwYXJ0aWFscyhwYXJ0aWFscykge1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLnBhcnRpYWxzID0gcGFydGlhbHM7XG4gICAgICAgIHRoaXMuX3NldFN0b3BwZWRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGhhc2Ugb2YgdGhlIExGTy5cbiAgICAgKi9cbiAgICBnZXQgcGhhc2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vc2NpbGxhdG9yLnBoYXNlO1xuICAgIH1cbiAgICBzZXQgcGhhc2UocGhhc2UpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvci5waGFzZSA9IHBoYXNlO1xuICAgICAgICB0aGlzLl9zZXRTdG9wcGVkVmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG91dHB1dCB1bml0cyBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCB1bml0cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3VuaXRzO1xuICAgIH1cbiAgICBzZXQgdW5pdHModmFsKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRNaW4gPSB0aGlzLm1pbjtcbiAgICAgICAgY29uc3QgY3VycmVudE1heCA9IHRoaXMubWF4O1xuICAgICAgICAvLyBjb252ZXJ0IHRoZSBtaW4gYW5kIHRoZSBtYXhcbiAgICAgICAgdGhpcy5fdW5pdHMgPSB2YWw7XG4gICAgICAgIHRoaXMubWluID0gY3VycmVudE1pbjtcbiAgICAgICAgdGhpcy5tYXggPSBjdXJyZW50TWF4O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgc291cmNlLCBlaXRoZXIgXCJzdGFydGVkXCIgb3IgXCJzdG9wcGVkXCIuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvci5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtIG5vZGUgdGhlIGRlc3RpbmF0aW9uIHRvIGNvbm5lY3QgdG9cbiAgICAgKiBAcGFyYW0gb3V0cHV0TnVtIHRoZSBvcHRpb25hbCBvdXRwdXQgbnVtYmVyXG4gICAgICogQHBhcmFtIGlucHV0TnVtIHRoZSBpbnB1dCBudW1iZXJcbiAgICAgKi9cbiAgICBjb25uZWN0KG5vZGUsIG91dHB1dE51bSwgaW5wdXROdW0pIHtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBQYXJhbSB8fCBub2RlIGluc3RhbmNlb2YgU2lnbmFsKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnZlcnQgPSBub2RlLmNvbnZlcnQ7XG4gICAgICAgICAgICB0aGlzLnVuaXRzID0gbm9kZS51bml0cztcbiAgICAgICAgfVxuICAgICAgICBjb25uZWN0U2lnbmFsKHRoaXMsIG5vZGUsIG91dHB1dE51bSwgaW5wdXROdW0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9vc2NpbGxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3RvcHBlZFNpZ25hbC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3plcm9zLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYTJnLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYW1wbGl0dWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TEZPLmpzLm1hcCIsImltcG9ydCB7IGFzc2VydFJhbmdlIH0gZnJvbSBcIi4vRGVidWdcIjtcbi8qKlxuICogQXNzZXJ0IHRoYXQgdGhlIG51bWJlciBpcyBpbiB0aGUgZ2l2ZW4gcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5nZShtaW4sIG1heCA9IEluZmluaXR5KSB7XG4gICAgY29uc3QgdmFsdWVNYXAgPSBuZXcgV2Vha01hcCgpO1xuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgICAgICBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIHtcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWVNYXAuZ2V0KHRoaXMpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKG5ld1ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgYXNzZXJ0UmFuZ2UobmV3VmFsdWUsIG1pbiwgbWF4KTtcbiAgICAgICAgICAgICAgICB2YWx1ZU1hcC5zZXQodGhpcywgbmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuLyoqXG4gKiBDb252ZXJ0IHRoZSB0aW1lIHRvIHNlY29uZHMgYW5kIGFzc2VydCB0aGF0IHRoZSB0aW1lIGlzIGluIGJldHdlZW4gdGhlIHR3b1xuICogdmFsdWVzIHdoZW4gYmVpbmcgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGltZVJhbmdlKG1pbiwgbWF4ID0gSW5maW5pdHkpIHtcbiAgICBjb25zdCB2YWx1ZU1hcCA9IG5ldyBXZWFrTWFwKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIHByb3BlcnR5S2V5KSB7XG4gICAgICAgIFJlZmxlY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwge1xuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZU1hcC5nZXQodGhpcyk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAobmV3VmFsdWUpIHtcbiAgICAgICAgICAgICAgICBhc3NlcnRSYW5nZSh0aGlzLnRvU2Vjb25kcyhuZXdWYWx1ZSksIG1pbiwgbWF4KTtcbiAgICAgICAgICAgICAgICB2YWx1ZU1hcC5zZXQodGhpcywgbmV3VmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RGVjb3JhdG9yLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciwgX19kZWNvcmF0ZSB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVyIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc1VuZGVmIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9Tb3VyY2VcIjtcbmltcG9ydCB7IFRvbmVCdWZmZXJTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQnVmZmVyU291cmNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIFBsYXllciBpcyBhbiBhdWRpbyBmaWxlIHBsYXllciB3aXRoIHN0YXJ0LCBsb29wLCBhbmQgc3RvcCBmdW5jdGlvbnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvZ29uZ18xLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBwbGF5IGFzIHNvb24gYXMgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAqIHBsYXllci5hdXRvc3RhcnQgPSB0cnVlO1xuICogQGNhdGVnb3J5IFNvdXJjZVxuICovXG5leHBvcnQgY2xhc3MgUGxheWVyIGV4dGVuZHMgU291cmNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGxheWVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGFjdGl2ZSBidWZmZXIgc291cmNlIG5vZGVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzID0gbmV3IFNldCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcih7XG4gICAgICAgICAgICBvbmxvYWQ6IHRoaXMuX29ubG9hZC5iaW5kKHRoaXMsIG9wdGlvbnMub25sb2FkKSxcbiAgICAgICAgICAgIG9uZXJyb3I6IG9wdGlvbnMub25lcnJvcixcbiAgICAgICAgICAgIHJldmVyc2U6IG9wdGlvbnMucmV2ZXJzZSxcbiAgICAgICAgICAgIHVybDogb3B0aW9ucy51cmwsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF1dG9zdGFydCA9IG9wdGlvbnMuYXV0b3N0YXJ0O1xuICAgICAgICB0aGlzLl9sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBvcHRpb25zLmxvb3BTdGFydDtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuZmFkZU91dCA9IG9wdGlvbnMuZmFkZU91dDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXV0b3N0YXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIGZhZGVJbjogMCxcbiAgICAgICAgICAgIGZhZGVPdXQ6IDAsXG4gICAgICAgICAgICBsb29wOiBmYWxzZSxcbiAgICAgICAgICAgIGxvb3BFbmQ6IDAsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2UsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMb2FkIHRoZSBhdWRpbyBmaWxlIGFzIGFuIGF1ZGlvIGJ1ZmZlci5cbiAgICAgKiBEZWNvZGVzIHRoZSBhdWRpbyBhc3luY2hyb25vdXNseSBhbmQgaW52b2tlc1xuICAgICAqIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBhdWRpbyBidWZmZXIgbG9hZHMuXG4gICAgICogTm90ZTogdGhpcyBkb2VzIG5vdCBuZWVkIHRvIGJlIGNhbGxlZCBpZiBhIHVybFxuICAgICAqIHdhcyBwYXNzZWQgaW4gdG8gdGhlIGNvbnN0cnVjdG9yLiBPbmx5IHVzZSB0aGlzXG4gICAgICogaWYgeW91IHdhbnQgdG8gbWFudWFsbHkgbG9hZCBhIG5ldyB1cmwuXG4gICAgICogQHBhcmFtIHVybCBUaGUgdXJsIG9mIHRoZSBidWZmZXIgdG8gbG9hZC4gRmlsZXR5cGUgc3VwcG9ydCBkZXBlbmRzIG9uIHRoZSBicm93c2VyLlxuICAgICAqL1xuICAgIGxvYWQodXJsKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICB5aWVsZCB0aGlzLl9idWZmZXIubG9hZCh1cmwpO1xuICAgICAgICAgICAgdGhpcy5fb25sb2FkKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGNhbGxiYWNrIHdoZW4gdGhlIGJ1ZmZlciBpcyBsb2FkZWQuXG4gICAgICovXG4gICAgX29ubG9hZChjYWxsYmFjayA9IG5vT3ApIHtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICAgICAgaWYgKHRoaXMuYXV0b3N0YXJ0KSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgY2FsbGJhY2sgd2hlbiB0aGUgYnVmZmVyIGlzIGRvbmUgcGxheWluZy5cbiAgICAgKi9cbiAgICBfb25Tb3VyY2VFbmQoc291cmNlKSB7XG4gICAgICAgIC8vIGludm9rZSB0aGUgb25zdG9wIGZ1bmN0aW9uXG4gICAgICAgIHRoaXMub25zdG9wKHRoaXMpO1xuICAgICAgICAvLyBkZWxldGUgdGhlIHNvdXJjZSBmcm9tIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmRlbGV0ZShzb3VyY2UpO1xuICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcy5zaXplID09PSAwICYmICF0aGlzLl9zeW5jZWQgJiZcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRoaXMubm93KCkpID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSAnaW1wbGljaXRFbmQnIGV2ZW50IGFuZCByZXBsYWNlIHdpdGggYW4gZXhwbGljaXQgZW5kXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5jYW5jZWwodGhpcy5ub3coKSk7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgdGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogUGxheSB0aGUgYnVmZmVyIGF0IHRoZSBnaXZlbiBzdGFydFRpbWUuIE9wdGlvbmFsbHkgYWRkIGFuIG9mZnNldFxuICAgICAqIGFuZC9vciBkdXJhdGlvbiB3aGljaCB3aWxsIHBsYXkgdGhlIGJ1ZmZlciBmcm9tIGEgcG9zaXRpb25cbiAgICAgKiB3aXRoaW4gdGhlIGJ1ZmZlciBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLCBpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbikge1xuICAgICAgICBzdXBlci5zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydChzdGFydFRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgLy8gaWYgaXQncyBhIGxvb3AgdGhlIGRlZmF1bHQgb2Zmc2V0IGlzIHRoZSBsb29wU3RhcnQgcG9pbnRcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCB0aGlzLl9sb29wU3RhcnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG9mZnNldCBpcyAwXG4gICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY29tcHV0ZSB0aGUgdmFsdWVzIGluIHNlY29uZHNcbiAgICAgICAgY29uc3QgY29tcHV0ZWRPZmZzZXQgPSB0aGlzLnRvU2Vjb25kcyhvZmZzZXQpO1xuICAgICAgICAvLyBjb21wdXRlIHRoZSBkdXJhdGlvbiB3aGljaCBpcyBlaXRoZXIgdGhlIHBhc3NlZCBpbiBkdXJhdGlvbiBvZiB0aGUgYnVmZmVyLmR1cmF0aW9uIC0gb2Zmc2V0XG4gICAgICAgIGNvbnN0IG9yaWdEdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgICAgICBkdXJhdGlvbiA9IGRlZmF1bHRBcmcoZHVyYXRpb24sIE1hdGgubWF4KHRoaXMuX2J1ZmZlci5kdXJhdGlvbiAtIGNvbXB1dGVkT2Zmc2V0LCAwKSk7XG4gICAgICAgIGxldCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAvLyBzY2FsZSBpdCBieSB0aGUgcGxheWJhY2sgcmF0ZVxuICAgICAgICBjb21wdXRlZER1cmF0aW9uID0gY29tcHV0ZWREdXJhdGlvbiAvIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICAgICAgLy8gZ2V0IHRoZSBzdGFydCB0aW1lXG4gICAgICAgIHN0YXJ0VGltZSA9IHRoaXMudG9TZWNvbmRzKHN0YXJ0VGltZSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIHNvdXJjZVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICB1cmw6IHRoaXMuX2J1ZmZlcixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZhZGVJbjogdGhpcy5mYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLmZhZGVPdXQsXG4gICAgICAgICAgICBsb29wOiB0aGlzLl9sb29wLFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5fbG9vcEVuZCxcbiAgICAgICAgICAgIGxvb3BTdGFydDogdGhpcy5fbG9vcFN0YXJ0LFxuICAgICAgICAgICAgb25lbmRlZDogdGhpcy5fb25Tb3VyY2VFbmQuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5fcGxheWJhY2tSYXRlLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgLy8gc2V0IHRoZSBsb29waW5nIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKCF0aGlzLl9sb29wICYmICF0aGlzLl9zeW5jZWQpIHtcbiAgICAgICAgICAgIC8vIGNhbmNlbCB0aGUgcHJldmlvdXMgc3RvcFxuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0YXJ0VGltZSArIGNvbXB1dGVkRHVyYXRpb24pO1xuICAgICAgICAgICAgLy8gaWYgaXQncyBub3QgbG9vcGluZywgc2V0IHRoZSBzdGF0ZSBjaGFuZ2UgYXQgdGhlIGVuZCBvZiB0aGUgc2FtcGxlXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZS5zZXRTdGF0ZUF0VGltZShcInN0b3BwZWRcIiwgc3RhcnRUaW1lICsgY29tcHV0ZWREdXJhdGlvbiwge1xuICAgICAgICAgICAgICAgIGltcGxpY2l0RW5kOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhcnJheSBvZiBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmFkZChzb3VyY2UpO1xuICAgICAgICAvLyBzdGFydCBpdFxuICAgICAgICBpZiAodGhpcy5fbG9vcCAmJiBpc1VuZGVmKG9yaWdEdXJhdGlvbikpIHtcbiAgICAgICAgICAgIHNvdXJjZS5zdGFydChzdGFydFRpbWUsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHN1YnRyYWN0IHRoZSBmYWRlIG91dCB0aW1lXG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQoc3RhcnRUaW1lLCBjb21wdXRlZE9mZnNldCwgY29tcHV0ZWREdXJhdGlvbiAtIHRoaXMudG9TZWNvbmRzKHRoaXMuZmFkZU91dCkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgcGxheWJhY2suXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5mb3JFYWNoKHNvdXJjZSA9PiBzb3VyY2Uuc3RvcChjb21wdXRlZFRpbWUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbmQgdGhlbiByZXN0YXJ0IHRoZSBwbGF5ZXIgZnJvbSB0aGUgYmVnaW5uaW5nIChvciBvZmZzZXQpXG4gICAgICogQHBhcmFtICB0aW1lIFdoZW4gdGhlIHBsYXllciBzaG91bGQgc3RhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgVGhlIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHNhbXBsZSB0byBzdGFydCBhdC5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIEhvdyBsb25nIHRoZSBzYW1wbGUgc2hvdWxkIHBsYXkuIElmIG5vIGR1cmF0aW9uIGlzIGdpdmVuLFxuICAgICAqIFx0XHRcdFx0XHRpdCB3aWxsIGRlZmF1bHQgdG8gdGhlIGZ1bGwgbGVuZ3RoIG9mIHRoZSBzYW1wbGUgKG1pbnVzIGFueSBvZmZzZXQpXG4gICAgICovXG4gICAgcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHN1cGVyLnJlc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBfcmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3N0b3AodGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWVrIHRvIGEgc3BlY2lmaWMgdGltZSBpbiB0aGUgcGxheWVyJ3MgYnVmZmVyLiBJZiB0aGVcbiAgICAgKiBzb3VyY2UgaXMgbm8gbG9uZ2VyIHBsYXlpbmcgYXQgdGhhdCB0aW1lLCBpdCB3aWxsIHN0b3AuXG4gICAgICogQHBhcmFtIG9mZnNldCBUaGUgdGltZSB0byBzZWVrIHRvLlxuICAgICAqIEBwYXJhbSB3aGVuIFRoZSB0aW1lIGZvciB0aGUgc2VlayBldmVudCB0byBvY2N1ci5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBsYXllciA9IG5ldyBUb25lLlBsYXllcihcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9iZXJrbGVlL2d1cmdsaW5nX3RoZXJlbWluXzEubXAzXCIsICgpID0+IHtcbiAgICAgKiBcdHBsYXllci5zdGFydCgpO1xuICAgICAqIFx0Ly8gc2VlayB0byB0aGUgb2Zmc2V0IGluIDEgc2Vjb25kIGZyb20gbm93XG4gICAgICogXHRwbGF5ZXIuc2VlaygwLjQsIFwiKzFcIik7XG4gICAgICogfSkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqL1xuICAgIHNlZWsob2Zmc2V0LCB3aGVuKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHdoZW4pO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUoY29tcHV0ZWRUaW1lKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkT2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgICAgIC8vIGlmIGl0J3MgY3VycmVudGx5IHBsYXlpbmcsIHN0b3AgaXRcbiAgICAgICAgICAgIHRoaXMuX3N0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIC8vIHJlc3RhcnQgaXQgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgICAgICAgIHRoaXMuX3N0YXJ0KGNvbXB1dGVkVGltZSwgY29tcHV0ZWRPZmZzZXQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGxvb3Agc3RhcnQgYW5kIGVuZC4gV2lsbCBvbmx5IGxvb3AgaWYgbG9vcCBpcyBzZXQgdG8gdHJ1ZS5cbiAgICAgKiBAcGFyYW0gbG9vcFN0YXJ0IFRoZSBsb29wIHN0YXJ0IHRpbWVcbiAgICAgKiBAcGFyYW0gbG9vcEVuZCBUaGUgbG9vcCBlbmQgdGltZVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2JlcmtsZWUvbWFsZXZvaWNlc19hYTJfRjMubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyBsb29wIGJldHdlZW4gdGhlIGdpdmVuIHBvaW50c1xuICAgICAqIHBsYXllci5zZXRMb29wUG9pbnRzKDAuMiwgMC4zKTtcbiAgICAgKiBwbGF5ZXIubG9vcCA9IHRydWU7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgc2V0TG9vcFBvaW50cyhsb29wU3RhcnQsIGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBsb29wIGlzIHRydWUsIHRoZSBsb29wIHdpbGwgc3RhcnQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KGxvb3BTdGFydCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBsb29wU3RhcnQ7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKGxvb3BTdGFydCksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZXQgdGhlIGN1cnJlbnQgc291cmNlXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3BTdGFydCA9IGxvb3BTdGFydDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGxvb3AgaXMgdHJ1ZSwgdGhlIGxvb3Agd2lsbCBlbmQgYXQgdGhpcyBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BFbmQ7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGxvb3BFbmQ7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKGxvb3BFbmQpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2V0IHRoZSBjdXJyZW50IHNvdXJjZVxuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5sb29wRW5kID0gbG9vcEVuZDtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdWRpbyBidWZmZXIgYmVsb25naW5nIHRvIHRoZSBwbGF5ZXIuXG4gICAgICovXG4gICAgZ2V0IGJ1ZmZlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICB9XG4gICAgc2V0IGJ1ZmZlcihidWZmZXIpIHtcbiAgICAgICAgdGhpcy5fYnVmZmVyLnNldChidWZmZXIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVyIHNob3VsZCBsb29wIG9uY2UgaXQncyBvdmVyLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGxheWVyID0gbmV3IFRvbmUuUGxheWVyKFwiaHR0cHM6Ly90b25lanMuZ2l0aHViLmlvL2F1ZGlvL2RydW0tc2FtcGxlcy9icmVha2JlYXQubXAzXCIpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBwbGF5ZXIubG9vcCA9IHRydWU7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIC8vIGlmIG5vIGNoYW5nZSwgZG8gbm90aGluZ1xuICAgICAgICBpZiAodGhpcy5fbG9vcCA9PT0gbG9vcCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICAvLyBzZXQgdGhlIGxvb3Agb2YgYWxsIG9mIHRoZSBzb3VyY2VzXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4ge1xuICAgICAgICAgICAgc291cmNlLmxvb3AgPSBsb29wO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGxvb3ApIHtcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgbmV4dCBzdG9wRXZlbnRcbiAgICAgICAgICAgIGNvbnN0IHN0b3BFdmVudCA9IHRoaXMuX3N0YXRlLmdldE5leHRTdGF0ZShcInN0b3BwZWRcIiwgdGhpcy5ub3coKSk7XG4gICAgICAgICAgICBpZiAoc3RvcEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBOb3JtYWwgc3BlZWQgaXMgMS4gVGhlIHBpdGNoIHdpbGwgY2hhbmdlIHdpdGggdGhlIHBsYXliYWNrIHJhdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9mZW1hbGV2b2ljZXNfYWEyX0E1Lm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gcGxheSBhdCAxLzQgc3BlZWRcbiAgICAgKiBwbGF5ZXIucGxheWJhY2tSYXRlID0gMC4yNTtcbiAgICAgKiAvLyBwbGF5IGFzIHNvb24gYXMgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKiBwbGF5ZXIuYXV0b3N0YXJ0ID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5ub3coKTtcbiAgICAgICAgLy8gY2FuY2VsIHRoZSBzdG9wIGV2ZW50IHNpbmNlIGl0J3MgYXQgYSBkaWZmZXJlbnQgdGltZSBub3dcbiAgICAgICAgY29uc3Qgc3RvcEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0TmV4dFN0YXRlKFwic3RvcHBlZFwiLCBub3cpO1xuICAgICAgICBpZiAoc3RvcEV2ZW50ICYmIHN0b3BFdmVudC5pbXBsaWNpdEVuZCkge1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuY2FuY2VsKHN0b3BFdmVudC50aW1lKTtcbiAgICAgICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMuZm9yRWFjaChzb3VyY2UgPT4gc291cmNlLmNhbmNlbFN0b3AoKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gc2V0IGFsbCB0aGUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgIHNvdXJjZS5wbGF5YmFja1JhdGUuc2V0VmFsdWVBdFRpbWUocmF0ZSwgbm93KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBidWZmZXIgc2hvdWxkIGJlIHJldmVyc2VkXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoXCJodHRwczovL3RvbmVqcy5naXRodWIuaW8vYXVkaW8vYmVya2xlZS9jaGltZV8xLm1wM1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcGxheWVyLmF1dG9zdGFydCA9IHRydWU7XG4gICAgICogcGxheWVyLnJldmVyc2UgPSB0cnVlO1xuICAgICAqL1xuICAgIGdldCByZXZlcnNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLnJldmVyc2U7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICB0aGlzLl9idWZmZXIucmV2ZXJzZSA9IHJldjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSWYgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyLmxvYWRlZDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICAvLyBkaXNjb25uZWN0IGFsbCBvZiB0aGUgcGxheWVyc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgUGxheWVyLnByb3RvdHlwZSwgXCJmYWRlSW5cIiwgdm9pZCAwKTtcbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgUGxheWVyLnByb3RvdHlwZSwgXCJmYWRlT3V0XCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QbGF5ZXIuanMubWFwIiwiaW1wb3J0IHsgVm9sdW1lIH0gZnJvbSBcIi4uLy4uL2NvbXBvbmVudC9jaGFubmVsL1ZvbHVtZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvQnVmZmVyc1wiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBub09wLCByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vU291cmNlXCI7XG5pbXBvcnQgeyBQbGF5ZXIgfSBmcm9tIFwiLi9QbGF5ZXJcIjtcbi8qKlxuICogUGxheWVycyBjb21iaW5lcyBtdWx0aXBsZSBbW1BsYXllcl1dIG9iamVjdHMuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBQbGF5ZXJzIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsYXllcnMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxzXCIsIFwib25sb2FkXCJdLCBcInVybHNcIikpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsYXllcnNcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBsYXllcnMgaGFzIG5vIGlucHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb250YWluZXIgb2YgYWxsIG9mIHRoZSBwbGF5ZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wbGF5ZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGxheWVycy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvdXRwdXQgdm9sdW1lIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBUb25lQXVkaW9CdWZmZXJzKHtcbiAgICAgICAgICAgIHVybHM6IG9wdGlvbnMudXJscyxcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3JcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG11dGUgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5fZmFkZUluID0gb3B0aW9ucy5mYWRlSW47XG4gICAgICAgIHRoaXMuX2ZhZGVPdXQgPSBvcHRpb25zLmZhZGVPdXQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU291cmNlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGJhc2VVcmw6IFwiXCIsXG4gICAgICAgICAgICBmYWRlSW46IDAsXG4gICAgICAgICAgICBmYWRlT3V0OiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgICAgICB2b2x1bWU6IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlIHRoZSBvdXRwdXQuXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92b2x1bWUubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl92b2x1bWUubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmYWRlSW4gdGltZSBvZiB0aGUgZW52ZWxvcGUgYXBwbGllZCB0byB0aGUgc291cmNlLlxuICAgICAqL1xuICAgIGdldCBmYWRlSW4oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9mYWRlSW47XG4gICAgfVxuICAgIHNldCBmYWRlSW4oZmFkZUluKSB7XG4gICAgICAgIHRoaXMuX2ZhZGVJbiA9IGZhZGVJbjtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiB7XG4gICAgICAgICAgICBwbGF5ZXIuZmFkZUluID0gZmFkZUluO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGZhZGVPdXQgdGltZSBvZiB0aGUgZWFjaCBvZiB0aGUgc291cmNlcy5cbiAgICAgKi9cbiAgICBnZXQgZmFkZU91dCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZhZGVPdXQ7XG4gICAgfVxuICAgIHNldCBmYWRlT3V0KGZhZGVPdXQpIHtcbiAgICAgICAgdGhpcy5fZmFkZU91dCA9IGZhZGVPdXQ7XG4gICAgICAgIHRoaXMuX3BsYXllcnMuZm9yRWFjaChwbGF5ZXIgPT4ge1xuICAgICAgICAgICAgcGxheWVyLmZhZGVPdXQgPSBmYWRlT3V0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXRlIG9mIHRoZSBwbGF5ZXJzIG9iamVjdC4gUmV0dXJucyBcInN0YXJ0ZWRcIiBpZiBhbnkgb2YgdGhlIHBsYXllcnMgYXJlIHBsYXlpbmcuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICBjb25zdCBwbGF5aW5nID0gQXJyYXkuZnJvbSh0aGlzLl9wbGF5ZXJzKS5zb21lKChbXywgcGxheWVyXSkgPT4gcGxheWVyLnN0YXRlID09PSBcInN0YXJ0ZWRcIik7XG4gICAgICAgIHJldHVybiBwbGF5aW5nID8gXCJzdGFydGVkXCIgOiBcInN0b3BwZWRcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJ1ZSBpZiB0aGUgYnVmZmVycyBvYmplY3QgaGFzIGEgYnVmZmVyIGJ5IHRoYXQgbmFtZS5cbiAgICAgKiBAcGFyYW0gbmFtZSAgVGhlIGtleSBvciBpbmRleCBvZiB0aGUgYnVmZmVyLlxuICAgICAqL1xuICAgIGhhcyhuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmhhcyhuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGEgcGxheWVyIGJ5IG5hbWUuXG4gICAgICogQHBhcmFtICBuYW1lICBUaGUgcGxheWVycyBuYW1lIGFzIGRlZmluZWQgaW4gdGhlIGNvbnN0cnVjdG9yIG9iamVjdCBvciBgYWRkYCBtZXRob2QuXG4gICAgICovXG4gICAgcGxheWVyKG5hbWUpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuaGFzKG5hbWUpLCBgTm8gUGxheWVyIHdpdGggdGhlIG5hbWUgJHtuYW1lfSBleGlzdHMgb24gdGhpcyBvYmplY3RgKTtcbiAgICAgICAgaWYgKCF0aGlzLl9wbGF5ZXJzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgY29uc3QgcGxheWVyID0gbmV3IFBsYXllcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGZhZGVJbjogdGhpcy5fZmFkZUluLFxuICAgICAgICAgICAgICAgIGZhZGVPdXQ6IHRoaXMuX2ZhZGVPdXQsXG4gICAgICAgICAgICAgICAgdXJsOiB0aGlzLl9idWZmZXJzLmdldChuYW1lKSxcbiAgICAgICAgICAgIH0pLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fcGxheWVycy5zZXQobmFtZSwgcGxheWVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWVycy5nZXQobmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGFsbCB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmxvYWRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQWRkIGEgcGxheWVyIGJ5IG5hbWUgYW5kIHVybCB0byB0aGUgUGxheWVyc1xuICAgICAqIEBwYXJhbSAgbmFtZSBBIHVuaXF1ZSBuYW1lIHRvIGdpdmUgdGhlIHBsYXllclxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZXIgb3IgYSBidWZmZXIgd2hpY2ggd2lsbCBiZSBhZGRlZCB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICAgICAqIEBwYXJhbSBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGFkZChuYW1lLCB1cmwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5fYnVmZmVycy5oYXMobmFtZSksIFwiQSBidWZmZXIgd2l0aCB0aGF0IG5hbWUgYWxyZWFkeSBleGlzdHMgb24gdGhpcyBvYmplY3RcIik7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5hbWUsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCBhbGwgb2YgdGhlIHBsYXllcnMgYXQgdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSB0byBzdG9wIGFsbCBvZiB0aGUgcGxheWVycy5cbiAgICAgKi9cbiAgICBzdG9wQWxsKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiBwbGF5ZXIuc3RvcCh0aW1lKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGxheWVycy5mb3JFYWNoKHBsYXllciA9PiBwbGF5ZXIuZGlzcG9zZSgpKTtcbiAgICAgICAgdGhpcy5fYnVmZmVycy5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsYXllcnMuanMubWFwIiwiaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL1NvdXJjZVwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBDbG9jayB9IGZyb20gXCIuLi8uLi9jb3JlL2Nsb2NrL0Nsb2NrXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vVG9uZUJ1ZmZlclNvdXJjZVwiO1xuaW1wb3J0IHsgaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIEdyYWluUGxheWVyIGltcGxlbWVudHMgW2dyYW51bGFyIHN5bnRoZXNpc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvR3JhbnVsYXJfc3ludGhlc2lzKS5cbiAqIEdyYW51bGFyIFN5bnRoZXNpcyBlbmFibGVzIHlvdSB0byBhZGp1c3QgcGl0Y2ggYW5kIHBsYXliYWNrIHJhdGUgaW5kZXBlbmRlbnRseS4gVGhlIGdyYWluU2l6ZSBpcyB0aGVcbiAqIGFtb3VudCBvZiB0aW1lIGVhY2ggc21hbGwgY2h1bmsgb2YgYXVkaW8gaXMgcGxheWVkIGZvciBhbmQgdGhlIG92ZXJsYXAgaXMgdGhlXG4gKiBhbW91bnQgb2YgY3Jvc3NmYWRpbmcgdHJhbnNpdGlvbiB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG4gKiBAY2F0ZWdvcnkgU291cmNlXG4gKi9cbmV4cG9ydCBjbGFzcyBHcmFpblBsYXllciBleHRlbmRzIFNvdXJjZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyYWluUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiR3JhaW5QbGF5ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEludGVybmFsIGxvb3BTdGFydCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gMDtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEludGVybmFsIGxvb3BTdGFydCB2YWx1ZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IDA7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGN1cnJlbnRseSBwbGF5aW5nIEJ1ZmZlclNvdXJjZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyYWluUGxheWVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5idWZmZXIgPSBuZXcgVG9uZUF1ZGlvQnVmZmVyKHtcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgICAgICByZXZlcnNlOiBvcHRpb25zLnJldmVyc2UsXG4gICAgICAgICAgICB1cmw6IG9wdGlvbnMudXJsLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xvY2sgPSBuZXcgQ2xvY2soe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMSAvIG9wdGlvbnMuZ3JhaW5TaXplXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fZ3JhaW5TaXplID0gb3B0aW9ucy5ncmFpblNpemU7XG4gICAgICAgIHRoaXMuX292ZXJsYXAgPSBvcHRpb25zLm92ZXJsYXA7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gb3B0aW9ucy5kZXR1bmU7XG4gICAgICAgIC8vIHNldHVwXG4gICAgICAgIHRoaXMub3ZlcmxhcCA9IG9wdGlvbnMub3ZlcmxhcDtcbiAgICAgICAgdGhpcy5sb29wID0gb3B0aW9ucy5sb29wO1xuICAgICAgICB0aGlzLnBsYXliYWNrUmF0ZSA9IG9wdGlvbnMucGxheWJhY2tSYXRlO1xuICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IG9wdGlvbnMuZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLmxvb3BTdGFydCA9IG9wdGlvbnMubG9vcFN0YXJ0O1xuICAgICAgICB0aGlzLmxvb3BFbmQgPSBvcHRpb25zLmxvb3BFbmQ7XG4gICAgICAgIHRoaXMucmV2ZXJzZSA9IG9wdGlvbnMucmV2ZXJzZTtcbiAgICAgICAgdGhpcy5fY2xvY2sub24oXCJzdG9wXCIsIHRoaXMuX29uc3RvcC5iaW5kKHRoaXMpKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTb3VyY2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgb25sb2FkOiBub09wLFxuICAgICAgICAgICAgb25lcnJvcjogbm9PcCxcbiAgICAgICAgICAgIG92ZXJsYXA6IDAuMSxcbiAgICAgICAgICAgIGdyYWluU2l6ZTogMC4yLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgZGV0dW5lOiAwLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgcmV2ZXJzZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0YXJ0IG1ldGhvZFxuICAgICAqL1xuICAgIF9zdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKSB7XG4gICAgICAgIG9mZnNldCA9IGRlZmF1bHRBcmcob2Zmc2V0LCAwKTtcbiAgICAgICAgb2Zmc2V0ID0gdGhpcy50b1NlY29uZHMob2Zmc2V0KTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBncmFpblNpemUgPSAxIC8gdGhpcy5fY2xvY2suZnJlcXVlbmN5LmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLl9jbG9jay5zdGFydCh0aW1lLCBvZmZzZXQgLyBncmFpblNpemUpO1xuICAgICAgICBpZiAoZHVyYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIGFuZCB0aGVuIHJlc3RhcnQgdGhlIHBsYXllciBmcm9tIHRoZSBiZWdpbm5pbmcgKG9yIG9mZnNldClcbiAgICAgKiBAcGFyYW0gIHRpbWUgV2hlbiB0aGUgcGxheWVyIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIG9mZnNldCBUaGUgb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc2FtcGxlIHRvIHN0YXJ0IGF0LlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIHNhbXBsZSBzaG91bGQgcGxheS4gSWYgbm8gZHVyYXRpb24gaXMgZ2l2ZW4sXG4gICAgICogXHRcdFx0XHRcdGl0IHdpbGwgZGVmYXVsdCB0byB0aGUgZnVsbCBsZW5ndGggb2YgdGhlIHNhbXBsZSAobWludXMgYW55IG9mZnNldClcbiAgICAgKi9cbiAgICByZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgc3VwZXIucmVzdGFydCh0aW1lLCBvZmZzZXQsIGR1cmF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIF9yZXN0YXJ0KHRpbWUsIG9mZnNldCwgZHVyYXRpb24pIHtcbiAgICAgICAgdGhpcy5fc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fc3RhcnQodGltZSwgb2Zmc2V0LCBkdXJhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHN0b3AgbWV0aG9kXG4gICAgICovXG4gICAgX3N0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9jbG9jay5zdG9wKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gdGhlIGNsb2NrIGlzIHN0b3BwZWRcbiAgICAgKi9cbiAgICBfb25zdG9wKHRpbWUpIHtcbiAgICAgICAgLy8gc3RvcCB0aGUgcGxheWVyc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4ge1xuICAgICAgICAgICAgc291cmNlLmZhZGVPdXQgPSAwO1xuICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uc3RvcCh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW52b2tlZCBvbiBlYWNoIGNsb2NrIHRpY2suIHNjaGVkdWxlZCBhIG5ldyBncmFpbiBhdCB0aGlzIHRpbWUuXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICAvLyBjaGVjayBpZiBpdCBzaG91bGQgc3RvcCBsb29waW5nXG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy5fY2xvY2suZ2V0VGlja3NBdFRpbWUodGltZSk7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IHRpY2tzICogdGhpcy5fZ3JhaW5TaXplO1xuICAgICAgICB0aGlzLmxvZyhcIm9mZnNldFwiLCBvZmZzZXQpO1xuICAgICAgICBpZiAoIXRoaXMubG9vcCAmJiBvZmZzZXQgPiB0aGlzLmJ1ZmZlci5kdXJhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5zdG9wKHRpbWUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGZpbGUsIHRoZSBmYWRlIGluIHNob3VsZCBiZSAwXG4gICAgICAgIGNvbnN0IGZhZGVJbiA9IG9mZnNldCA8IHRoaXMuX292ZXJsYXAgPyAwIDogdGhpcy5fb3ZlcmxhcDtcbiAgICAgICAgLy8gY3JlYXRlIGEgYnVmZmVyIHNvdXJjZVxuICAgICAgICBjb25zdCBzb3VyY2UgPSBuZXcgVG9uZUJ1ZmZlclNvdXJjZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1cmw6IHRoaXMuYnVmZmVyLFxuICAgICAgICAgICAgZmFkZUluOiBmYWRlSW4sXG4gICAgICAgICAgICBmYWRlT3V0OiB0aGlzLl9vdmVybGFwLFxuICAgICAgICAgICAgbG9vcDogdGhpcy5sb29wLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLl9sb29wU3RhcnQsXG4gICAgICAgICAgICBsb29wRW5kOiB0aGlzLl9sb29wRW5kLFxuICAgICAgICAgICAgLy8gY29tcHV0ZSB0aGUgcGxheWJhY2tSYXRlIGJhc2VkIG9uIHRoZSBkZXR1bmVcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKHRoaXMuZGV0dW5lIC8gMTAwKVxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgc291cmNlLnN0YXJ0KHRpbWUsIHRoaXMuX2dyYWluU2l6ZSAqIHRpY2tzKTtcbiAgICAgICAgc291cmNlLnN0b3AodGltZSArIHRoaXMuX2dyYWluU2l6ZSAvIHRoaXMucGxheWJhY2tSYXRlKTtcbiAgICAgICAgLy8gYWRkIGl0IHRvIHRoZSBhY3RpdmUgc291cmNlc1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnB1c2goc291cmNlKTtcbiAgICAgICAgLy8gcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG4gICAgICAgIHNvdXJjZS5vbmVuZGVkID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLl9hY3RpdmVTb3VyY2VzLmluZGV4T2Yoc291cmNlKTtcbiAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBzYW1wbGVcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgYXNzZXJ0UmFuZ2UocmF0ZSwgMC4wMDEpO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSByYXRlO1xuICAgICAgICB0aGlzLmdyYWluU2l6ZSA9IHRoaXMuX2dyYWluU2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3Agc3RhcnQgdGltZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcFN0YXJ0O1xuICAgIH1cbiAgICBzZXQgbG9vcFN0YXJ0KHRpbWUpIHtcbiAgICAgICAgaWYgKHRoaXMuYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgYXNzZXJ0UmFuZ2UodGhpcy50b1NlY29uZHModGltZSksIDAsIHRoaXMuYnVmZmVyLmR1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3AgZW5kIHRpbWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZCh0aW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlci5sb2FkZWQpIHtcbiAgICAgICAgICAgIGFzc2VydFJhbmdlKHRoaXMudG9TZWNvbmRzKHRpbWUpLCAwLCB0aGlzLmJ1ZmZlci5kdXJhdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGlyZWN0aW9uIHRoZSBidWZmZXIgc2hvdWxkIHBsYXkgaW5cbiAgICAgKi9cbiAgICBnZXQgcmV2ZXJzZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVmZmVyLnJldmVyc2U7XG4gICAgfVxuICAgIHNldCByZXZlcnNlKHJldikge1xuICAgICAgICB0aGlzLmJ1ZmZlci5yZXZlcnNlID0gcmV2O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc2l6ZSBvZiBlYWNoIGNodW5rIG9mIGF1ZGlvIHRoYXQgdGhlXG4gICAgICogYnVmZmVyIGlzIGNob3BwZWQgaW50byBhbmQgcGxheWVkIGJhY2sgYXQuXG4gICAgICovXG4gICAgZ2V0IGdyYWluU2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dyYWluU2l6ZTtcbiAgICB9XG4gICAgc2V0IGdyYWluU2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2dyYWluU2l6ZSA9IHRoaXMudG9TZWNvbmRzKHNpemUpO1xuICAgICAgICB0aGlzLl9jbG9jay5mcmVxdWVuY3kuc2V0VmFsdWVBdFRpbWUodGhpcy5fcGxheWJhY2tSYXRlIC8gdGhpcy5fZ3JhaW5TaXplLCB0aGlzLm5vdygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGR1cmF0aW9uIG9mIHRoZSBjcm9zcy1mYWRlIGJldHdlZW4gc3VjY2Vzc2l2ZSBncmFpbnMuXG4gICAgICovXG4gICAgZ2V0IG92ZXJsYXAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vdmVybGFwO1xuICAgIH1cbiAgICBzZXQgb3ZlcmxhcCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZShjb21wdXRlZFRpbWUsIDApO1xuICAgICAgICB0aGlzLl9vdmVybGFwID0gY29tcHV0ZWRUaW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBhbGwgdGhlIGJ1ZmZlciBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBnZXQgbG9hZGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5idWZmZXIubG9hZGVkO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuYnVmZmVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY2xvY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goKHNvdXJjZSkgPT4gc291cmNlLmRpc3Bvc2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUdyYWluUGxheWVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL05vaXNlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Vc2VyTWVkaWFcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9BTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvRk1Pc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1B1bHNlT3NjaWxsYXRvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vb3NjaWxsYXRvci9GYXRPc2NpbGxhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL1BXTU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvT21uaU9zY2lsbGF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vc2NpbGxhdG9yL0xGT1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9QbGF5ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2J1ZmZlci9QbGF5ZXJzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9idWZmZXIvR3JhaW5QbGF5ZXJcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIFJldHVybiB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgYW4gaW5jb21pbmcgc2lnbmFsLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYWJzID0gbmV3IFRvbmUuQWJzKCkudG9EZXN0aW5hdGlvbigpO1xuICogXHRjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMSk7XG4gKiBcdHNpZ25hbC5yYW1wVG8oLTEsIDAuNSk7XG4gKiBcdHNpZ25hbC5jb25uZWN0KGFicyk7XG4gKiB9LCAwLjUsIDEpO1xuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgQWJzIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFic1wiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5vZGUgd2hpY2ggY29udmVydHMgdGhlIGF1ZGlvIHJhbmdlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWJzID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogdmFsID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoTWF0aC5hYnModmFsKSA8IDAuMDAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1hdGguYWJzKHZhbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgQXVkaW9SYW5nZSBpbnB1dCBbLTEsIDFdXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fYWJzO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCByYW5nZSBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fYWJzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWJzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QWJzLmpzLm1hcCIsImltcG9ydCB7IFNpZ25hbE9wZXJhdG9yIH0gZnJvbSBcIi4vU2lnbmFsT3BlcmF0b3JcIjtcbmltcG9ydCB7IFdhdmVTaGFwZXIgfSBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG4vKipcbiAqIEdhaW5Ub0F1ZGlvIGNvbnZlcnRzIGFuIGlucHV0IGluIE5vcm1hbFJhbmdlIFswLDFdIHRvIEF1ZGlvUmFuZ2UgWy0xLDFdLlxuICogU2VlIFtbQXVkaW9Ub0dhaW5dXS5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdhaW5Ub0F1ZGlvIGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdhaW5Ub0F1ZGlvXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbm9kZSB3aGljaCBjb252ZXJ0cyB0aGUgYXVkaW8gcmFuZ2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ub3JtID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWFwcGluZzogeCA9PiBNYXRoLmFicyh4KSAqIDIgLSAxLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBOb3JtYWxSYW5nZSBpbnB1dCBbMCwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9ub3JtO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIEF1ZGlvUmFuZ2Ugb3V0cHV0IFstMSwgMV1cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fbm9ybTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vcm0uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HYWluVG9BdWRpby5qcy5tYXAiLCJpbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuL011bHRpcGx5XCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIE5lZ2F0ZSB0aGUgaW5jb21pbmcgc2lnbmFsLiBpLmUuIGFuIGlucHV0IHNpZ25hbCBvZiAxMCB3aWxsIG91dHB1dCAtMTBcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbmVnID0gbmV3IFRvbmUuTmVnYXRlKCk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoLTIpLmNvbm5lY3QobmVnKTtcbiAqIC8vIG91dHB1dCBvZiBuZWcgaXMgcG9zaXRpdmUgMi5cbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIE5lZ2F0ZSBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJOZWdhdGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIG5lZ2F0aW9uIGlzIGRvbmUgYnkgbXVsdGlwbHlpbmcgYnkgLTFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX211bHRpcGx5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAtMSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgYW5kIG91dHB1dCBhcmUgZXF1YWwgdG8gdGhlIG11bHRpcGx5IG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9tdWx0aXBseTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9tdWx0aXBseTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKiBAcmV0dXJucyB7TmVnYXRlfSB0aGlzXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU5lZ2F0ZS5qcy5tYXAiLCJpbXBvcnQgeyBjb25uZWN0U2VyaWVzIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE5lZ2F0ZSB9IGZyb20gXCIuLi9zaWduYWwvTmVnYXRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuLyoqXG4gKiBTdWJ0cmFjdCB0aGUgc2lnbmFsIGNvbm5lY3RlZCB0byB0aGUgaW5wdXQgaXMgc3VidHJhY3RlZCBmcm9tIHRoZSBzaWduYWwgY29ubmVjdGVkXG4gKiBUaGUgc3VidHJhaGVuZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gc3VidHJhY3QgYSBzY2FsYXIgZnJvbSBhIHNpZ25hbFxuICogY29uc3Qgc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoMSk7XG4gKiBjb25zdCBzaWcgPSBuZXcgVG9uZS5TaWduYWwoNCkuY29ubmVjdChzdWIpO1xuICogLy8gdGhlIG91dHB1dCBvZiBzdWIgaXMgMy5cbiAqIEBleGFtcGxlXG4gKiAvLyBzdWJ0cmFjdCB0d28gc2lnbmFsc1xuICogY29uc3Qgc3ViID0gbmV3IFRvbmUuU3VidHJhY3QoKTtcbiAqIGNvbnN0IHNpZ0EgPSBuZXcgVG9uZS5TaWduYWwoMTApO1xuICogY29uc3Qgc2lnQiA9IG5ldyBUb25lLlNpZ25hbCgyLjUpO1xuICogc2lnQS5jb25uZWN0KHN1Yik7XG4gKiBzaWdCLmNvbm5lY3Qoc3ViLnN1YnRyYWhlbmQpO1xuICogLy8gb3V0cHV0IG9mIHN1YiBpcyA3LjVcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFN1YnRyYWN0IGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhTdWJ0cmFjdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3VidHJhY3RcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzdW1taW5nIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N1bSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fc3VtO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX3N1bTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE5lZ2F0ZSB0aGUgaW5wdXQgb2YgdGhlIHNlY29uZCBpbnB1dCBiZWZvcmUgY29ubmVjdGluZyBpdCB0byB0aGUgc3VtbWluZyBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fbmVnID0gbmV3IE5lZ2F0ZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2YWx1ZSB3aGljaCBpcyBzdWJ0cmFjdGVkIGZyb20gdGhlIG1haW4gc2lnbmFsXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnN1YnRyYWhlbmQgPSB0aGlzLl9wYXJhbTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLl9jb25zdGFudFNvdXJjZSwgdGhpcy5fbmVnLCB0aGlzLl9zdW0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbmVnLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VtLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3VidHJhY3QuanMubWFwIiwiaW1wb3J0IHsgU2lnbmFsT3BlcmF0b3IgfSBmcm9tIFwiLi9TaWduYWxPcGVyYXRvclwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi9NdWx0aXBseVwiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuL1dhdmVTaGFwZXJcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBHcmVhdGVyVGhhblplcm8gb3V0cHV0cyAxIHdoZW4gdGhlIGlucHV0IGlzIHN0cmljdGx5IGdyZWF0ZXIgdGhhbiB6ZXJvXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGd0MCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuWmVybygpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChndDApO1xuICogXHRzaWcuc2V0VmFsdWVBdFRpbWUoLTEsIDAuMDUpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuWmVybyBleHRlbmRzIFNpZ25hbE9wZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhblplcm8uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyZWF0ZXJUaGFuWmVyb1wiO1xuICAgICAgICB0aGlzLl90aHJlc2ggPSB0aGlzLm91dHB1dCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGxlbmd0aDogMTI3LFxuICAgICAgICAgICAgbWFwcGluZzogKHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWwgPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMuaW5wdXQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IDEwMDAwXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9zY2FsZS5jb25uZWN0KHRoaXMuX3RocmVzaCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90aHJlc2guZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmVhdGVyVGhhblplcm8uanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTdWJ0cmFjdCB9IGZyb20gXCIuL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IEdyZWF0ZXJUaGFuWmVybyB9IGZyb20gXCIuL0dyZWF0ZXJUaGFuWmVyb1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBPdXRwdXQgMSBpZiB0aGUgc2lnbmFsIGlzIGdyZWF0ZXIgdGhhbiB0aGUgdmFsdWUsIG90aGVyd2lzZSBvdXRwdXRzIDAuXG4gKiBjYW4gY29tcGFyZSB0d28gc2lnbmFscyBvciBhIHNpZ25hbCBhbmQgYSBudW1iZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIHJldHVybiBUb25lLk9mZmxpbmUoKCkgPT4ge1xuICogXHRjb25zdCBndCA9IG5ldyBUb25lLkdyZWF0ZXJUaGFuKDIpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0Y29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDQpLmNvbm5lY3QoZ3QpO1xuICogfSwgMC4xLCAxKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIEdyZWF0ZXJUaGFuIGV4dGVuZHMgU2lnbmFsIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhHcmVhdGVyVGhhbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkdyZWF0ZXJUaGFuXCI7XG4gICAgICAgIHRoaXMub3ZlcnJpZGUgPSBmYWxzZTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEdyZWF0ZXJUaGFuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9zdWJ0cmFjdCA9IHRoaXMuaW5wdXQgPSBuZXcgU3VidHJhY3Qoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMudmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2d0eiA9IHRoaXMub3V0cHV0ID0gbmV3IEdyZWF0ZXJUaGFuWmVybyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5jb21wYXJhdG9yID0gdGhpcy5fcGFyYW0gPSB0aGlzLl9zdWJ0cmFjdC5zdWJ0cmFoZW5kO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImNvbXBhcmF0b3JcIik7XG4gICAgICAgIC8vIGNvbm5lY3RcbiAgICAgICAgdGhpcy5fc3VidHJhY3QuY29ubmVjdCh0aGlzLl9ndHopO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNpZ25hbC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ3R6LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3VidHJhY3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNvbXBhcmF0b3IuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1HcmVhdGVyVGhhbi5qcy5tYXAiLCJpbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4vV2F2ZVNoYXBlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTaWduYWxPcGVyYXRvciB9IGZyb20gXCIuL1NpZ25hbE9wZXJhdG9yXCI7XG4vKipcbiAqIFBvdyBhcHBsaWVzIGFuIGV4cG9uZW50IHRvIHRoZSBpbmNvbWluZyBzaWduYWwuIFRoZSBpbmNvbWluZyBzaWduYWwgbXVzdCBiZSBBdWRpb1JhbmdlIFstMSwgMV1cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcG93ID0gbmV3IFRvbmUuUG93KDIpO1xuICogY29uc3Qgc2lnID0gbmV3IFRvbmUuU2lnbmFsKDAuNSkuY29ubmVjdChwb3cpO1xuICogLy8gb3V0cHV0IG9mIHBvdyBpcyAwLjI1LlxuICogQGNhdGVnb3J5IFNpZ25hbFxuICovXG5leHBvcnQgY2xhc3MgUG93IGV4dGVuZHMgU2lnbmFsT3BlcmF0b3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvdy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZhbHVlXCJdKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBvd1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUG93LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widmFsdWVcIl0pO1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBXYXZlU2hhcGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1hcHBpbmc6IHRoaXMuX2V4cEZ1bmMob3B0aW9ucy52YWx1ZSksXG4gICAgICAgICAgICBsZW5ndGg6IDgxOTIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IG9wdGlvbnMudmFsdWU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU2lnbmFsT3BlcmF0b3IuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgdmFsdWU6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB0aGUgZnVuY3Rpb24gd2hpY2ggbWFwcyB0aGUgd2F2ZXNoYXBlclxuICAgICAqIEBwYXJhbSBleHBvbmVudCBleHBvbmVudCB2YWx1ZVxuICAgICAqL1xuICAgIF9leHBGdW5jKGV4cG9uZW50KSB7XG4gICAgICAgIHJldHVybiAodmFsKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gTWF0aC5wb3coTWF0aC5hYnModmFsKSwgZXhwb25lbnQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgb2YgdGhlIGV4cG9uZW50LlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V4cG9uZW50O1xuICAgIH1cbiAgICBzZXQgdmFsdWUoZXhwb25lbnQpIHtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQgPSBleHBvbmVudDtcbiAgICAgICAgdGhpcy5fZXhwb25lbnRTY2FsZXIuc2V0TWFwKHRoaXMuX2V4cEZ1bmModGhpcy5fZXhwb25lbnQpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHBvbmVudFNjYWxlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBvdy5qcy5tYXAiLCJpbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuL1NjYWxlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFBvdyB9IGZyb20gXCIuL1Bvd1wiO1xuLyoqXG4gKiBQZXJmb3JtcyBhbiBleHBvbmVudGlhbCBzY2FsaW5nIG9uIGFuIGlucHV0IHNpZ25hbC5cbiAqIFNjYWxlcyBhIE5vcm1hbFJhbmdlIHZhbHVlIFswLDFdIGV4cG9uZW50aWFsbHlcbiAqIHRvIHRoZSBvdXRwdXQgcmFuZ2Ugb2Ygb3V0cHV0TWluIHRvIG91dHB1dE1heC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzY2FsZUV4cCA9IG5ldyBUb25lLlNjYWxlRXhwKDAsIDEwMCwgMik7XG4gKiBjb25zdCBzaWduYWwgPSBuZXcgVG9uZS5TaWduYWwoMC41KS5jb25uZWN0KHNjYWxlRXhwKTtcbiAqIEBjYXRlZ29yeSBTaWduYWxcbiAqL1xuZXhwb3J0IGNsYXNzIFNjYWxlRXhwIGV4dGVuZHMgU2NhbGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlRXhwLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCIsIFwiZXhwb25lbnRcIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU2NhbGVFeHBcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNjYWxlRXhwLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibWluXCIsIFwibWF4XCIsIFwiZXhwb25lbnRcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5fZXhwID0gbmV3IFBvdyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5leHBvbmVudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V4cC5jb25uZWN0KHRoaXMuX211bHQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFNjYWxlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGV4cG9uZW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSW5zdGVhZCBvZiBpbnRlcnBvbGF0aW5nIGxpbmVhcmx5IGJldHdlZW4gdGhlIFtbbWluXV0gYW5kXG4gICAgICogW1ttYXhdXSB2YWx1ZXMsIHNldHRpbmcgdGhlIGV4cG9uZW50IHdpbGwgaW50ZXJwb2xhdGUgYmV0d2VlblxuICAgICAqIHRoZSB0d28gdmFsdWVzIHdpdGggYW4gZXhwb25lbnRpYWwgY3VydmUuXG4gICAgICovXG4gICAgZ2V0IGV4cG9uZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwLnZhbHVlO1xuICAgIH1cbiAgICBzZXQgZXhwb25lbnQoZXhwKSB7XG4gICAgICAgIHRoaXMuX2V4cC52YWx1ZSA9IGV4cDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9leHAuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TY2FsZUV4cC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgVHJhbnNwb3J0VGltZUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UcmFuc3BvcnRUaW1lXCI7XG5pbXBvcnQgeyBUb25lQ29uc3RhbnRTb3VyY2UgfSBmcm9tIFwiLi9Ub25lQ29uc3RhbnRTb3VyY2VcIjtcbi8qKlxuICogQWRkcyB0aGUgYWJpbGl0eSB0byBzeW5jaHJvbml6ZSB0aGUgc2lnbmFsIHRvIHRoZSBbW1RyYW5zcG9ydF1dXG4gKi9cbmV4cG9ydCBjbGFzcyBTeW5jZWRTaWduYWwgZXh0ZW5kcyBTaWduYWwge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3luY2VkU2lnbmFsXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEb24ndCBvdmVycmlkZSB3aGVuIHNvbWV0aGluZyBpcyBjb25uZWN0ZWQgdG8gdGhlIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm92ZXJyaWRlID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTaWduYWwuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2YWx1ZVwiLCBcInVuaXRzXCJdKTtcbiAgICAgICAgdGhpcy5fbGFzdFZhbCA9IG9wdGlvbnMudmFsdWU7XG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGVSZXBlYXQodGhpcy5fb25UaWNrLmJpbmQodGhpcyksIFwiMWlcIik7XG4gICAgICAgIHRoaXMuX3N5bmNlZENhbGxiYWNrID0gdGhpcy5fYW5jaG9yVmFsdWUuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0YXJ0XCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInBhdXNlXCIsIHRoaXMuX3N5bmNlZENhbGxiYWNrKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vbihcInN0b3BcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICAvLyBkaXNjb25uZWN0IHRoZSBjb25zdGFudCBzb3VyY2UgZnJvbSB0aGUgb3V0cHV0IGFuZCByZXBsYWNlIGl0IHdpdGggYW5vdGhlciBvbmVcbiAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2UuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5zdG9wKDApO1xuICAgICAgICAvLyBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlID0gdGhpcy5vdXRwdXQgPSBuZXcgVG9uZUNvbnN0YW50U291cmNlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG9mZnNldDogb3B0aW9ucy52YWx1ZSxcbiAgICAgICAgICAgIHVuaXRzOiBvcHRpb25zLnVuaXRzLFxuICAgICAgICB9KS5zdGFydCgwKTtcbiAgICAgICAgdGhpcy5zZXRWYWx1ZUF0VGltZShvcHRpb25zLnZhbHVlLCAwKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCBldmVyeSB0aWNrLlxuICAgICAqL1xuICAgIF9vblRpY2sodGltZSkge1xuICAgICAgICBjb25zdCB2YWwgPSBzdXBlci5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNlY29uZHMpO1xuICAgICAgICAvLyBhcHByb3hpbWF0ZSByYW1wIGN1cnZlcyB3aXRoIGxpbmVhciByYW1wc1xuICAgICAgICBpZiAodGhpcy5fbGFzdFZhbCAhPT0gdmFsKSB7XG4gICAgICAgICAgICB0aGlzLl9sYXN0VmFsID0gdmFsO1xuICAgICAgICAgICAgdGhpcy5fY29uc3RhbnRTb3VyY2Uub2Zmc2V0LnNldFZhbHVlQXRUaW1lKHZhbCwgdGltZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogQW5jaG9yIHRoZSB2YWx1ZSBhdCB0aGUgc3RhcnQgYW5kIHN0b3Agb2YgdGhlIFRyYW5zcG9ydFxuICAgICAqL1xuICAgIF9hbmNob3JWYWx1ZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHN1cGVyLmdldFZhbHVlQXRUaW1lKHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2Vjb25kcyk7XG4gICAgICAgIHRoaXMuX2xhc3RWYWwgPSB2YWw7XG4gICAgICAgIHRoaXMuX2NvbnN0YW50U291cmNlLm9mZnNldC5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5vZmZzZXQuc2V0VmFsdWVBdFRpbWUodmFsLCB0aW1lKTtcbiAgICB9XG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHJldHVybiBzdXBlci5nZXRWYWx1ZUF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgIH1cbiAgICBzZXRWYWx1ZUF0VGltZSh2YWx1ZSwgdGltZSkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnNldFZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgbGluZWFyUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5saW5lYXJSYW1wVG9WYWx1ZUF0VGltZSh2YWx1ZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvVmFsdWVBdFRpbWUodmFsdWUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBzdGFydFRpbWUsIHRpbWVDb25zdGFudCkge1xuICAgICAgICBjb25zdCBjb21wdXRlZFRpbWUgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuc2V0VGFyZ2V0QXRUaW1lKHZhbHVlLCBjb21wdXRlZFRpbWUsIHRpbWVDb25zdGFudCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBjYW5jZWxTY2hlZHVsZWRWYWx1ZXMoc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5jYW5jZWxTY2hlZHVsZWRWYWx1ZXMoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHNldFZhbHVlQ3VydmVBdFRpbWUodmFsdWVzLCBzdGFydFRpbWUsIGR1cmF0aW9uLCBzY2FsaW5nKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBkdXJhdGlvbiA9IHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKTtcbiAgICAgICAgc3VwZXIuc2V0VmFsdWVDdXJ2ZUF0VGltZSh2YWx1ZXMsIGNvbXB1dGVkVGltZSwgZHVyYXRpb24sIHNjYWxpbmcpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCB0aW1lKS50b1NlY29uZHMoKTtcbiAgICAgICAgc3VwZXIuY2FuY2VsQW5kSG9sZEF0VGltZShjb21wdXRlZFRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc2V0UmFtcFBvaW50KHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5zZXRSYW1wUG9pbnQoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGV4cG9uZW50aWFsUmFtcFRvKHZhbHVlLCByYW1wVGltZSwgc3RhcnRUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IG5ldyBUcmFuc3BvcnRUaW1lQ2xhc3ModGhpcy5jb250ZXh0LCBzdGFydFRpbWUpLnRvU2Vjb25kcygpO1xuICAgICAgICBzdXBlci5leHBvbmVudGlhbFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBsaW5lYXJSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLmxpbmVhclJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICB0YXJnZXRSYW1wVG8odmFsdWUsIHJhbXBUaW1lLCBzdGFydFRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gbmV3IFRyYW5zcG9ydFRpbWVDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGltZSkudG9TZWNvbmRzKCk7XG4gICAgICAgIHN1cGVyLnRhcmdldFJhbXBUbyh2YWx1ZSwgcmFtcFRpbWUsIGNvbXB1dGVkVGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIodGhpcy5fc3luY2VkKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5vZmYoXCJzdGFydFwiLCB0aGlzLl9zeW5jZWRDYWxsYmFjayk7XG4gICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQub2ZmKFwicGF1c2VcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0Lm9mZihcInN0b3BcIiwgdGhpcy5fc3luY2VkQ2FsbGJhY2spO1xuICAgICAgICB0aGlzLl9jb25zdGFudFNvdXJjZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN5bmNlZFNpZ25hbC5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9BZGRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0Fic1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vQXVkaW9Ub0dhaW5cIjtcbmV4cG9ydCAqIGZyb20gXCIuL0dhaW5Ub0F1ZGlvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9HcmVhdGVyVGhhblwiO1xuZXhwb3J0ICogZnJvbSBcIi4vR3JlYXRlclRoYW5aZXJvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NdWx0aXBseVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vTmVnYXRlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Qb3dcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NpZ25hbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2NhbGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1NjYWxlRXhwXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TdWJ0cmFjdFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3luY2VkU2lnbmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9XYXZlU2hhcGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9aZXJvXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIsIF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNPYmplY3QsIGlzU3RyaW5nIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IGNvbm5lY3RTaWduYWwsIFNpZ25hbCB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBPZmZsaW5lQ29udGV4dCB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvT2ZmbGluZUNvbnRleHRcIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHJhbmdlLCB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBFbnZlbG9wZSBpcyBhbiBbQURTUl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvU3ludGhlc2l6ZXIjQURTUl9lbnZlbG9wZSlcbiAqIGVudmVsb3BlIGdlbmVyYXRvci4gRW52ZWxvcGUgb3V0cHV0cyBhIHNpZ25hbCB3aGljaFxuICogY2FuIGJlIGNvbm5lY3RlZCB0byBhbiBBdWRpb1BhcmFtIG9yIFRvbmUuU2lnbmFsLlxuICogYGBgXG4gKiAgICAgICAgICAgL1xcXG4gKiAgICAgICAgICAvICBcXFxuICogICAgICAgICAvICAgIFxcXG4gKiAgICAgICAgLyAgICAgIFxcXG4gKiAgICAgICAvICAgICAgICBcXF9fX19fX19fX19fXG4gKiAgICAgIC8gICAgICAgICAgICAgICAgICAgICBcXFxuICogICAgIC8gICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgICAvICAgICAgICAgICAgICAgICAgICAgICAgIFxcXG4gKiAgIC8gICAgICAgICAgICAgICAgICAgICAgICAgICBcXFxuICogYGBgXG4gKiBAZXhhbXBsZVxuICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAqIFx0XHRhdHRhY2s6IDAuMSxcbiAqIFx0XHRkZWNheTogMC4yLFxuICogXHRcdHN1c3RhaW46IDAuNSxcbiAqIFx0XHRyZWxlYXNlOiAwLjgsXG4gKiBcdH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0ZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuNSk7XG4gKiB9LCAxLjUsIDEpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRW52ZWxvcGUgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRW52ZWxvcGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBzaWduYWwgd2hpY2ggaXMgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc2lnID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb3V0cHV0IHNpZ25hbCBvZiB0aGUgZW52ZWxvcGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fc2lnO1xuICAgICAgICAvKipcbiAgICAgICAgICogRW52ZWxvcGUgaGFzIG5vIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJhdHRhY2tcIiwgXCJkZWNheVwiLCBcInN1c3RhaW5cIiwgXCJyZWxlYXNlXCJdKTtcbiAgICAgICAgdGhpcy5hdHRhY2sgPSBvcHRpb25zLmF0dGFjaztcbiAgICAgICAgdGhpcy5kZWNheSA9IG9wdGlvbnMuZGVjYXk7XG4gICAgICAgIHRoaXMuc3VzdGFpbiA9IG9wdGlvbnMuc3VzdGFpbjtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLmF0dGFja0N1cnZlID0gb3B0aW9ucy5hdHRhY2tDdXJ2ZTtcbiAgICAgICAgdGhpcy5yZWxlYXNlQ3VydmUgPSBvcHRpb25zLnJlbGVhc2VDdXJ2ZTtcbiAgICAgICAgdGhpcy5kZWNheUN1cnZlID0gb3B0aW9ucy5kZWNheUN1cnZlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwibGluZWFyXCIsXG4gICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgZGVjYXlDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgICAgIHJlbGVhc2VDdXJ2ZTogXCJleHBvbmVudGlhbFwiLFxuICAgICAgICAgICAgc3VzdGFpbjogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVhZCB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZW52ZWxvcGUuIFVzZWZ1bCBmb3JcbiAgICAgKiBzeW5jaHJvbml6aW5nIHZpc3VhbCBvdXRwdXQgdG8gdGhlIGVudmVsb3BlLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmFsdWVBdFRpbWUodGhpcy5ub3coKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgY3VydmVcbiAgICAgKiBAcGFyYW0gIGN1cnZlXG4gICAgICogQHBhcmFtICBkaXJlY3Rpb24gIEluL091dFxuICAgICAqIEByZXR1cm4gVGhlIGN1cnZlIG5hbWVcbiAgICAgKi9cbiAgICBfZ2V0Q3VydmUoY3VydmUsIGRpcmVjdGlvbikge1xuICAgICAgICBpZiAoaXNTdHJpbmcoY3VydmUpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3VydmU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBjdXJ2ZXMgYXJyYXlcbiAgICAgICAgICAgIGxldCBjdXJ2ZU5hbWU7XG4gICAgICAgICAgICBmb3IgKGN1cnZlTmFtZSBpbiBFbnZlbG9wZUN1cnZlcykge1xuICAgICAgICAgICAgICAgIGlmIChFbnZlbG9wZUN1cnZlc1tjdXJ2ZU5hbWVdW2RpcmVjdGlvbl0gPT09IGN1cnZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjdXJ2ZU5hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gcmV0dXJuIHRoZSBjdXN0b20gY3VydmVcbiAgICAgICAgICAgIHJldHVybiBjdXJ2ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBBc3NpZ24gYSB0aGUgY3VydmUgdG8gdGhlIGdpdmVuIG5hbWUgdXNpbmcgdGhlIGRpcmVjdGlvblxuICAgICAqIEBwYXJhbSAgbmFtZVxuICAgICAqIEBwYXJhbSAgZGlyZWN0aW9uIEluL091dFxuICAgICAqIEBwYXJhbSAgY3VydmVcbiAgICAgKi9cbiAgICBfc2V0Q3VydmUobmFtZSwgZGlyZWN0aW9uLCBjdXJ2ZSkge1xuICAgICAgICAvLyBjaGVjayBpZiBpdCdzIGEgdmFsaWQgdHlwZVxuICAgICAgICBpZiAoaXNTdHJpbmcoY3VydmUpICYmIFJlZmxlY3QuaGFzKEVudmVsb3BlQ3VydmVzLCBjdXJ2ZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnZlRGVmID0gRW52ZWxvcGVDdXJ2ZXNbY3VydmVdO1xuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGN1cnZlRGVmKSkge1xuICAgICAgICAgICAgICAgIGlmIChuYW1lICE9PSBcIl9kZWNheUN1cnZlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlRGVmW2RpcmVjdGlvbl07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlRGVmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQXJyYXkoY3VydmUpICYmIG5hbWUgIT09IFwiX2RlY2F5Q3VydmVcIikge1xuICAgICAgICAgICAgdGhpc1tuYW1lXSA9IGN1cnZlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRW52ZWxvcGU6IGludmFsaWQgY3VydmU6IFwiICsgY3VydmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgYXR0YWNrLlxuICAgICAqIENhbiBiZSBhbnkgb2YgdGhlc2Ugc3RyaW5nczpcbiAgICAgKiAqIFwibGluZWFyXCJcbiAgICAgKiAqIFwiZXhwb25lbnRpYWxcIlxuICAgICAqICogXCJzaW5lXCJcbiAgICAgKiAqIFwiY29zaW5lXCJcbiAgICAgKiAqIFwiYm91bmNlXCJcbiAgICAgKiAqIFwicmlwcGxlXCJcbiAgICAgKiAqIFwic3RlcFwiXG4gICAgICpcbiAgICAgKiBDYW4gYWxzbyBiZSBhbiBhcnJheSB3aGljaCBkZXNjcmliZXMgdGhlIGN1cnZlLiBWYWx1ZXNcbiAgICAgKiBpbiB0aGUgYXJyYXkgYXJlIGV2ZW5seSBzdWJkaXZpZGVkIGFuZCBsaW5lYXJseVxuICAgICAqIGludGVycG9sYXRlZCBvdmVyIHRoZSBkdXJhdGlvbiBvZiB0aGUgYXR0YWNrLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogcmV0dXJuIFRvbmUuT2ZmbGluZSgoKSA9PiB7XG4gICAgICogXHRjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSgwLjQpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBcdGVudi5hdHRhY2tDdXJ2ZSA9IFwibGluZWFyXCI7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCBhdHRhY2tDdXJ2ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldEN1cnZlKHRoaXMuX2F0dGFja0N1cnZlLCBcIkluXCIpO1xuICAgIH1cbiAgICBzZXQgYXR0YWNrQ3VydmUoY3VydmUpIHtcbiAgICAgICAgdGhpcy5fc2V0Q3VydmUoXCJfYXR0YWNrQ3VydmVcIiwgXCJJblwiLCBjdXJ2ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgcmVsZWFzZS4gU2VlIHRoZSBhdHRhY2sgY3VydmUgdHlwZXMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAgICAgKiBcdFx0cmVsZWFzZTogMC44XG4gICAgICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIFx0Ly8gcmVsZWFzZSBjdXJ2ZSBjb3VsZCBhbHNvIGJlIGRlZmluZWQgYnkgYW4gYXJyYXlcbiAgICAgKiBcdGVudi5yZWxlYXNlQ3VydmUgPSBbMSwgMC4zLCAwLjQsIDAuMiwgMC43LCAwXTtcbiAgICAgKiBcdGVudi50cmlnZ2VyUmVsZWFzZSgwLjIpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCByZWxlYXNlQ3VydmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRDdXJ2ZSh0aGlzLl9yZWxlYXNlQ3VydmUsIFwiT3V0XCIpO1xuICAgIH1cbiAgICBzZXQgcmVsZWFzZUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHRoaXMuX3NldEN1cnZlKFwiX3JlbGVhc2VDdXJ2ZVwiLCBcIk91dFwiLCBjdXJ2ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzaGFwZSBvZiB0aGUgZGVjYXkgZWl0aGVyIFwibGluZWFyXCIgb3IgXCJleHBvbmVudGlhbFwiXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAgICAgKiBcdGNvbnN0IGVudiA9IG5ldyBUb25lLkVudmVsb3BlKHtcbiAgICAgKiBcdFx0c3VzdGFpbjogMC4xLFxuICAgICAqIFx0XHRkZWNheTogMC41XG4gICAgICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogXHRlbnYuZGVjYXlDdXJ2ZSA9IFwibGluZWFyXCI7XG4gICAgICogXHRlbnYudHJpZ2dlckF0dGFjaygpO1xuICAgICAqIH0sIDEsIDEpO1xuICAgICAqL1xuICAgIGdldCBkZWNheUN1cnZlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjYXlDdXJ2ZTtcbiAgICB9XG4gICAgc2V0IGRlY2F5Q3VydmUoY3VydmUpIHtcbiAgICAgICAgYXNzZXJ0KFtcImxpbmVhclwiLCBcImV4cG9uZW50aWFsXCJdLnNvbWUoYyA9PiBjID09PSBjdXJ2ZSksIGBJbnZhbGlkIGVudmVsb3BlIGN1cnZlOiAke2N1cnZlfWApO1xuICAgICAgICB0aGlzLl9kZWNheUN1cnZlID0gY3VydmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjay9kZWNheSBwb3J0aW9uIG9mIHRoZSBBRFNSIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0LlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIGVudmVsb3BlIHNjYWxlcyB0aGUgdmFsZXMuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bWJlciBiZXR3ZWVuIDAtMVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgZW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogY29uc3Qgb3NjID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QoZW52KS5zdGFydCgpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIGF0dGFjayAwLjUgc2Vjb25kcyBmcm9tIG5vdyB3aXRoIGEgdmVsb2NpdHkgb2YgMC4yXG4gICAgICogZW52LnRyaWdnZXJBdHRhY2soXCIrMC41XCIsIDAuMik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyQXR0YWNrXCIsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBvcmlnaW5hbEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKTtcbiAgICAgICAgbGV0IGF0dGFjayA9IG9yaWdpbmFsQXR0YWNrO1xuICAgICAgICBjb25zdCBkZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpO1xuICAgICAgICAvLyBjaGVjayBpZiBpdCdzIG5vdCBhIGNvbXBsZXRlIGF0dGFja1xuICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSB0aGlzLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoY3VycmVudFZhbHVlID4gMCkge1xuICAgICAgICAgICAgLy8gc3VidHJhY3QgdGhlIGN1cnJlbnQgdmFsdWUgZnJvbSB0aGUgYXR0YWNrIHRpbWVcbiAgICAgICAgICAgIGNvbnN0IGF0dGFja1JhdGUgPSAxIC8gYXR0YWNrO1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nRGlzdGFuY2UgPSAxIC0gY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgLy8gdGhlIGF0dGFjayBpcyBub3cgdGhlIHJlbWFpbmluZyB0aW1lXG4gICAgICAgICAgICBhdHRhY2sgPSByZW1haW5pbmdEaXN0YW5jZSAvIGF0dGFja1JhdGU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYXR0YWNrXG4gICAgICAgIGlmIChhdHRhY2sgPCB0aGlzLnNhbXBsZVRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxTY2hlZHVsZWRWYWx1ZXModGltZSk7XG4gICAgICAgICAgICAvLyBjYXNlIHdoZXJlIHRoZSBhdHRhY2sgdGltZSBpcyAwIHNob3VsZCBzZXQgaW5zdGFudGx5XG4gICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVBdFRpbWUodmVsb2NpdHksIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcubGluZWFyUmFtcFRvKHZlbG9jaXR5LCBhdHRhY2ssIHRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuX2F0dGFja0N1cnZlID09PSBcImV4cG9uZW50aWFsXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZy50YXJnZXRSYW1wVG8odmVsb2NpdHksIGF0dGFjaywgdGltZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9zaWcuY2FuY2VsQW5kSG9sZEF0VGltZSh0aW1lKTtcbiAgICAgICAgICAgIGxldCBjdXJ2ZSA9IHRoaXMuX2F0dGFja0N1cnZlO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnRpbmcgcG9zaXRpb24gaW4gdGhlIGN1cnZlXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGN1cnZlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gdGhlIHN0YXJ0aW5nIGluZGV4IGlzIGJldHdlZW4gdGhlIHR3byB2YWx1ZXNcbiAgICAgICAgICAgICAgICBpZiAoY3VydmVbaSAtIDFdIDw9IGN1cnJlbnRWYWx1ZSAmJiBjdXJyZW50VmFsdWUgPD0gY3VydmVbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgY3VydmUgPSB0aGlzLl9hdHRhY2tDdXJ2ZS5zbGljZShpKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlIGZpcnN0IGluZGV4IGlzIHRoZSBjdXJyZW50IHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIGN1cnZlWzBdID0gY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9zaWcuc2V0VmFsdWVDdXJ2ZUF0VGltZShjdXJ2ZSwgdGltZSwgYXR0YWNrLCB2ZWxvY2l0eSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZGVjYXlcbiAgICAgICAgaWYgKGRlY2F5ICYmIHRoaXMuc3VzdGFpbiA8IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlY2F5VmFsdWUgPSB2ZWxvY2l0eSAqIHRoaXMuc3VzdGFpbjtcbiAgICAgICAgICAgIGNvbnN0IGRlY2F5U3RhcnQgPSB0aW1lICsgYXR0YWNrO1xuICAgICAgICAgICAgdGhpcy5sb2coXCJkZWNheVwiLCBkZWNheVN0YXJ0KTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9kZWNheUN1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUb1ZhbHVlQXRUaW1lKGRlY2F5VmFsdWUsIGRlY2F5ICsgZGVjYXlTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zaWcuZXhwb25lbnRpYWxBcHByb2FjaFZhbHVlQXRUaW1lKGRlY2F5VmFsdWUsIGRlY2F5U3RhcnQsIGRlY2F5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlcnMgdGhlIHJlbGVhc2Ugb2YgdGhlIGVudmVsb3BlLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlIHNob3VsZCBzdGFydC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3Ioe1xuICAgICAqIFx0dHlwZTogXCJzYXd0b290aFwiXG4gICAgICogfSkuY29ubmVjdChlbnYpLnN0YXJ0KCk7XG4gICAgICogZW52LnRyaWdnZXJBdHRhY2soKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIGhhbGYgYSBzZWNvbmQgYWZ0ZXIgdGhlIGF0dGFja1xuICAgICAqIGVudi50cmlnZ2VyUmVsZWFzZShcIiswLjVcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIHRpbWUpO1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMuZ2V0VmFsdWVBdFRpbWUodGltZSk7XG4gICAgICAgIGlmIChjdXJyZW50VmFsdWUgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCByZWxlYXNlID0gdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKTtcbiAgICAgICAgICAgIGlmIChyZWxlYXNlIDwgdGhpcy5zYW1wbGVUaW1lKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnNldFZhbHVlQXRUaW1lKDAsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fcmVsZWFzZUN1cnZlID09PSBcImxpbmVhclwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLmxpbmVhclJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMuX3JlbGVhc2VDdXJ2ZSA9PT0gXCJleHBvbmVudGlhbFwiKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc2lnLnRhcmdldFJhbXBUbygwLCByZWxlYXNlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGFzc2VydChpc0FycmF5KHRoaXMuX3JlbGVhc2VDdXJ2ZSksIFwicmVsZWFzZUN1cnZlIG11c3QgYmUgZWl0aGVyICdsaW5lYXInLCAnZXhwb25lbnRpYWwnIG9yIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5jYW5jZWxBbmRIb2xkQXRUaW1lKHRpbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3NpZy5zZXRWYWx1ZUN1cnZlQXRUaW1lKHRoaXMuX3JlbGVhc2VDdXJ2ZSwgdGltZSwgcmVsZWFzZSwgY3VycmVudFZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzY2hlZHVsZWQgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuIFRoaXMgd2lsbFxuICAgICAqIHJldHVybiB0aGUgdW5jb252ZXJ0ZWQgKHJhdykgdmFsdWUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBlbnYgPSBuZXcgVG9uZS5FbnZlbG9wZSgwLjUsIDEsIDAuNCwgMik7XG4gICAgICogZW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKDIpO1xuICAgICAqIHNldEludGVydmFsKCgpID0+IGNvbnNvbGUubG9nKGVudi5nZXRWYWx1ZUF0VGltZShUb25lLm5vdygpKSksIDEwMCk7XG4gICAgICovXG4gICAgZ2V0VmFsdWVBdFRpbWUodGltZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2lnLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiB0cmlnZ2VyQXR0YWNrUmVsZWFzZSBpcyBzaG9ydGhhbmQgZm9yIHRyaWdnZXJBdHRhY2ssIHRoZW4gd2FpdGluZ1xuICAgICAqIHNvbWUgZHVyYXRpb24sIHRoZW4gdHJpZ2dlclJlbGVhc2UuXG4gICAgICogQHBhcmFtIGR1cmF0aW9uIFRoZSBkdXJhdGlvbiBvZiB0aGUgc3VzdGFpbi5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IG9mIHRoZSBlbnZlbG9wZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IGVudiA9IG5ldyBUb25lLkFtcGxpdHVkZUVudmVsb3BlKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGVudikuc3RhcnQoKTtcbiAgICAgKiAvLyB0cmlnZ2VyIHRoZSByZWxlYXNlIDAuNSBzZWNvbmRzIGFmdGVyIHRoZSBhdHRhY2tcbiAgICAgKiBlbnYudHJpZ2dlckF0dGFja1JlbGVhc2UoMC41KTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZSh0aW1lICsgdGhpcy50b1NlY29uZHMoZHVyYXRpb24pKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbHMgYWxsIHNjaGVkdWxlZCBlbnZlbG9wZSBjaGFuZ2VzIGFmdGVyIHRoZSBnaXZlbiB0aW1lLlxuICAgICAqL1xuICAgIGNhbmNlbChhZnRlcikge1xuICAgICAgICB0aGlzLl9zaWcuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRoaXMudG9TZWNvbmRzKGFmdGVyKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBlbnZlbG9wZSB0byBhIGRlc3RpbmF0aW9uIG5vZGUuXG4gICAgICovXG4gICAgY29ubmVjdChkZXN0aW5hdGlvbiwgb3V0cHV0TnVtYmVyID0gMCwgaW5wdXROdW1iZXIgPSAwKSB7XG4gICAgICAgIGNvbm5lY3RTaWduYWwodGhpcywgZGVzdGluYXRpb24sIG91dHB1dE51bWJlciwgaW5wdXROdW1iZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVuZGVyIHRoZSBlbnZlbG9wZSBjdXJ2ZSB0byBhbiBhcnJheSBvZiB0aGUgZ2l2ZW4gbGVuZ3RoLlxuICAgICAqIEdvb2QgZm9yIHZpc3VhbGl6aW5nIHRoZSBlbnZlbG9wZSBjdXJ2ZS4gUmVzY2FsZXMgdGhlIGR1cmF0aW9uIG9mIHRoZVxuICAgICAqIGVudmVsb3BlIHRvIGZpdCB0aGUgbGVuZ3RoLlxuICAgICAqL1xuICAgIGFzQXJyYXkobGVuZ3RoID0gMTAyNCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb24gPSBsZW5ndGggLyB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZTtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMSwgZHVyYXRpb24sIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKTtcbiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSB0aGUgQURTUiBmb3IgdGhlIGdpdmVuIGR1cmF0aW9uIHdpdGggMjAlIHN1c3RhaW4gdGltZVxuICAgICAgICAgICAgY29uc3QgYXR0YWNrUG9ydGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZGVjYXkpO1xuICAgICAgICAgICAgY29uc3QgZW52ZWxvcGVEdXJhdGlvbiA9IGF0dGFja1BvcnRpb24gKyB0aGlzLnRvU2Vjb25kcyh0aGlzLnJlbGVhc2UpO1xuICAgICAgICAgICAgY29uc3Qgc3VzdGFpblRpbWUgPSBlbnZlbG9wZUR1cmF0aW9uICogMC4xO1xuICAgICAgICAgICAgY29uc3QgdG90YWxEdXJhdGlvbiA9IGVudmVsb3BlRHVyYXRpb24gKyBzdXN0YWluVGltZTtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGNsb25lID0gbmV3IHRoaXMuY29uc3RydWN0b3IoT2JqZWN0LmFzc2lnbih0aGlzLmdldCgpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiBkdXJhdGlvbiAqIHRoaXMudG9TZWNvbmRzKHRoaXMuYXR0YWNrKSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgZGVjYXk6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5kZWNheSkgLyB0b3RhbER1cmF0aW9uLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IGR1cmF0aW9uICogdGhpcy50b1NlY29uZHModGhpcy5yZWxlYXNlKSAvIHRvdGFsRHVyYXRpb24sXG4gICAgICAgICAgICAgICAgY29udGV4dFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgY2xvbmUuX3NpZy50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAgICBjbG9uZS50cmlnZ2VyQXR0YWNrUmVsZWFzZShkdXJhdGlvbiAqIChhdHRhY2tQb3J0aW9uICsgc3VzdGFpblRpbWUpIC8gdG90YWxEdXJhdGlvbiwgMCk7XG4gICAgICAgICAgICBjb25zdCBidWZmZXIgPSB5aWVsZCBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlci5nZXRDaGFubmVsRGF0YSgwKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lnLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBFbnZlbG9wZS5wcm90b3R5cGUsIFwiYXR0YWNrXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJkZWNheVwiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgcmFuZ2UoMCwgMSlcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJzdXN0YWluXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIEVudmVsb3BlLnByb3RvdHlwZSwgXCJyZWxlYXNlXCIsIHZvaWQgMCk7XG4vKipcbiAqIEdlbmVyYXRlIHNvbWUgY29tcGxleCBlbnZlbG9wZSBjdXJ2ZXMuXG4gKi9cbmNvbnN0IEVudmVsb3BlQ3VydmVzID0gKCgpID0+IHtcbiAgICBjb25zdCBjdXJ2ZUxlbiA9IDEyODtcbiAgICBsZXQgaTtcbiAgICBsZXQgaztcbiAgICAvLyBjb3NpbmUgY3VydmVcbiAgICBjb25zdCBjb3NpbmVDdXJ2ZSA9IFtdO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjdXJ2ZUxlbjsgaSsrKSB7XG4gICAgICAgIGNvc2luZUN1cnZlW2ldID0gTWF0aC5zaW4oKGkgLyAoY3VydmVMZW4gLSAxKSkgKiAoTWF0aC5QSSAvIDIpKTtcbiAgICB9XG4gICAgLy8gcmlwcGxlIGN1cnZlXG4gICAgY29uc3QgcmlwcGxlQ3VydmUgPSBbXTtcbiAgICBjb25zdCByaXBwbGVDdXJ2ZUZyZXEgPSA2LjQ7XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuIC0gMTsgaSsrKSB7XG4gICAgICAgIGsgPSAoaSAvIChjdXJ2ZUxlbiAtIDEpKTtcbiAgICAgICAgY29uc3Qgc2luZVdhdmUgPSBNYXRoLnNpbihrICogKE1hdGguUEkgKiAyKSAqIHJpcHBsZUN1cnZlRnJlcSAtIE1hdGguUEkgLyAyKSArIDE7XG4gICAgICAgIHJpcHBsZUN1cnZlW2ldID0gc2luZVdhdmUgLyAxMCArIGsgKiAwLjgzO1xuICAgIH1cbiAgICByaXBwbGVDdXJ2ZVtjdXJ2ZUxlbiAtIDFdID0gMTtcbiAgICAvLyBzdGFpcnMgY3VydmVcbiAgICBjb25zdCBzdGFpcnNDdXJ2ZSA9IFtdO1xuICAgIGNvbnN0IHN0ZXBzID0gNTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY3VydmVMZW47IGkrKykge1xuICAgICAgICBzdGFpcnNDdXJ2ZVtpXSA9IE1hdGguY2VpbCgoaSAvIChjdXJ2ZUxlbiAtIDEpKSAqIHN0ZXBzKSAvIHN0ZXBzO1xuICAgIH1cbiAgICAvLyBpbi1vdXQgZWFzaW5nIGN1cnZlXG4gICAgY29uc3Qgc2luZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgayA9IGkgLyAoY3VydmVMZW4gLSAxKTtcbiAgICAgICAgc2luZUN1cnZlW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcyhNYXRoLlBJICogaykpO1xuICAgIH1cbiAgICAvLyBhIGJvdW5jZSBjdXJ2ZVxuICAgIGNvbnN0IGJvdW5jZUN1cnZlID0gW107XG4gICAgZm9yIChpID0gMDsgaSA8IGN1cnZlTGVuOyBpKyspIHtcbiAgICAgICAgayA9IGkgLyAoY3VydmVMZW4gLSAxKTtcbiAgICAgICAgY29uc3QgZnJlcSA9IE1hdGgucG93KGssIDMpICogNCArIDAuMjtcbiAgICAgICAgY29uc3QgdmFsID0gTWF0aC5jb3MoZnJlcSAqIE1hdGguUEkgKiAyICogayk7XG4gICAgICAgIGJvdW5jZUN1cnZlW2ldID0gTWF0aC5hYnModmFsICogKDEgLSBrKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludmVydCBhIHZhbHVlIGN1cnZlIHRvIG1ha2UgaXQgd29yayBmb3IgdGhlIHJlbGVhc2VcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBpbnZlcnRDdXJ2ZShjdXJ2ZSkge1xuICAgICAgICBjb25zdCBvdXQgPSBuZXcgQXJyYXkoY3VydmUubGVuZ3RoKTtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjdXJ2ZS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgb3V0W2pdID0gMSAtIGN1cnZlW2pdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHJldmVyc2UgdGhlIGN1cnZlXG4gICAgICovXG4gICAgZnVuY3Rpb24gcmV2ZXJzZUN1cnZlKGN1cnZlKSB7XG4gICAgICAgIHJldHVybiBjdXJ2ZS5zbGljZSgwKS5yZXZlcnNlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIGF0dGFjayBhbmQgcmVsZWFzZSBjdXJ2ZSBhcnJheXNcbiAgICAgKi9cbiAgICByZXR1cm4ge1xuICAgICAgICBib3VuY2U6IHtcbiAgICAgICAgICAgIEluOiBpbnZlcnRDdXJ2ZShib3VuY2VDdXJ2ZSksXG4gICAgICAgICAgICBPdXQ6IGJvdW5jZUN1cnZlLFxuICAgICAgICB9LFxuICAgICAgICBjb3NpbmU6IHtcbiAgICAgICAgICAgIEluOiBjb3NpbmVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogcmV2ZXJzZUN1cnZlKGNvc2luZUN1cnZlKSxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwb25lbnRpYWw6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgbGluZWFyOiBcImxpbmVhclwiLFxuICAgICAgICByaXBwbGU6IHtcbiAgICAgICAgICAgIEluOiByaXBwbGVDdXJ2ZSxcbiAgICAgICAgICAgIE91dDogaW52ZXJ0Q3VydmUocmlwcGxlQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBzaW5lOiB7XG4gICAgICAgICAgICBJbjogc2luZUN1cnZlLFxuICAgICAgICAgICAgT3V0OiBpbnZlcnRDdXJ2ZShzaW5lQ3VydmUpLFxuICAgICAgICB9LFxuICAgICAgICBzdGVwOiB7XG4gICAgICAgICAgICBJbjogc3RhaXJzQ3VydmUsXG4gICAgICAgICAgICBPdXQ6IGludmVydEN1cnZlKHN0YWlyc0N1cnZlKSxcbiAgICAgICAgfSxcbiAgICB9O1xufSkoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IFZvbHVtZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Wb2x1bWVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBCYXNlLWNsYXNzIGZvciBhbGwgaW5zdHJ1bWVudHNcbiAqL1xuZXhwb3J0IGNsYXNzIEluc3RydW1lbnQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEtlZXAgdHJhY2sgb2YgYWxsIGV2ZW50cyBzY2hlZHVsZWQgdG8gdGhlIHRyYW5zcG9ydFxuICAgICAgICAgKiB3aGVuIHRoZSBpbnN0cnVtZW50IGlzICdzeW5jZWQnXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIElmIHRoZSBpbnN0cnVtZW50IGlzIGN1cnJlbnRseSBzeW5jZWRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyQXR0YWNrID0gdGhpcy50cmlnZ2VyQXR0YWNrO1xuICAgICAgICB0aGlzLl9vcmlnaW5hbF90cmlnZ2VyUmVsZWFzZSA9IHRoaXMudHJpZ2dlclJlbGVhc2U7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhJbnN0cnVtZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX3ZvbHVtZSA9IHRoaXMub3V0cHV0ID0gbmV3IFZvbHVtZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy52b2x1bWUgPSB0aGlzLl92b2x1bWUudm9sdW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcInZvbHVtZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHZvbHVtZTogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGluc3RydW1lbnQgdG8gdGhlIFRyYW5zcG9ydC4gQWxsIHN1YnNlcXVlbnQgY2FsbHMgb2ZcbiAgICAgKiBbW3RyaWdnZXJBdHRhY2tdXSBhbmQgW1t0cmlnZ2VyUmVsZWFzZV1dIHdpbGwgYmUgc2NoZWR1bGVkIGFsb25nIHRoZSB0cmFuc3BvcnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmbVN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBmbVN5bnRoLnZvbHVtZS52YWx1ZSA9IC02O1xuICAgICAqIGZtU3ludGguc3luYygpO1xuICAgICAqIC8vIHNjaGVkdWxlIDMgbm90ZXMgd2hlbiB0aGUgdHJhbnNwb3J0IGZpcnN0IHN0YXJ0c1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIsIDApO1xuICAgICAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJFNFwiLCBcIjhuXCIsIFwiOG5cIik7XG4gICAgICogZm1TeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkc0XCIsIFwiOG5cIiwgXCI0blwiKTtcbiAgICAgKiAvLyBzdGFydCB0aGUgdHJhbnNwb3J0IHRvIGhlYXIgdGhlIG5vdGVzXG4gICAgICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzZXQgX3N5bmNcbiAgICAgKi9cbiAgICBfc3luY1N0YXRlKCkge1xuICAgICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuX3N5bmNlZCkge1xuICAgICAgICAgICAgdGhpcy5fc3luY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGFuZ2VkO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXcmFwIHRoZSBnaXZlbiBtZXRob2Qgc28gdGhhdCBpdCBjYW4gYmUgc3luY2hyb25pemVkXG4gICAgICogQHBhcmFtIG1ldGhvZCBXaGljaCBtZXRob2QgdG8gd3JhcCBhbmQgc3luY1xuICAgICAqIEBwYXJhbSAgdGltZVBvc2l0aW9uIFdoYXQgcG9zaXRpb24gdGhlIHRpbWUgYXJndW1lbnQgYXBwZWFycyBpblxuICAgICAqL1xuICAgIF9zeW5jTWV0aG9kKG1ldGhvZCwgdGltZVBvc2l0aW9uKSB7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsTWV0aG9kID0gdGhpc1tcIl9vcmlnaW5hbF9cIiArIG1ldGhvZF0gPSB0aGlzW21ldGhvZF07XG4gICAgICAgIHRoaXNbbWV0aG9kXSA9ICguLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0aW1lID0gYXJnc1t0aW1lUG9zaXRpb25dO1xuICAgICAgICAgICAgY29uc3QgaWQgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnNjaGVkdWxlKCh0KSA9PiB7XG4gICAgICAgICAgICAgICAgYXJnc1t0aW1lUG9zaXRpb25dID0gdDtcbiAgICAgICAgICAgICAgICBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH0sIHRpbWUpO1xuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVkRXZlbnRzLnB1c2goaWQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGluc3RydW1lbnQgZnJvbSB0aGUgVHJhbnNwb3J0XG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMuZm9yRWFjaChpZCA9PiB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGlkKSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlZEV2ZW50cyA9IFtdO1xuICAgICAgICBpZiAodGhpcy5fc3luY2VkKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayA9IHRoaXMuX29yaWdpbmFsX3RyaWdnZXJBdHRhY2s7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlID0gdGhpcy5fb3JpZ2luYWxfdHJpZ2dlclJlbGVhc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgdGhlbiB0aGUgcmVsZWFzZSBhZnRlciB0aGUgZHVyYXRpb24uXG4gICAgICogQHBhcmFtICBub3RlICAgICBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gSG93IGxvbmcgdGhlIG5vdGUgc2hvdWxkIGJlIGhlbGQgZm9yIGJlZm9yZVxuICAgICAqICAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJpbmcgdGhlIHJlbGVhc2UuIFRoaXMgdmFsdWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gMC5cbiAgICAgKiBAcGFyYW0gdGltZSAgV2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRoZSBub3RlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgXCJDNFwiIGZvciB0aGUgZHVyYXRpb24gb2YgYW4gOHRoIG5vdGVcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZER1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sobm90ZSwgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2UoY29tcHV0ZWRUaW1lICsgY29tcHV0ZWREdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjbGVhbiB1cFxuICAgICAqIEByZXR1cm5zIHtJbnN0cnVtZW50fSB0aGlzXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZWRFdmVudHMgPSBbXTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SW5zdHJ1bWVudC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgSW5zdHJ1bWVudCB9IGZyb20gXCIuLi9pbnN0cnVtZW50L0luc3RydW1lbnRcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG4vKipcbiAqIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIG90aGVyIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMgdG8gZXh0ZW5kLlxuICovXG5leHBvcnQgY2xhc3MgTW9ub3Bob25pYyBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnBvcnRhbWVudG8gPSBvcHRpb25zLnBvcnRhbWVudG87XG4gICAgICAgIHRoaXMub25zaWxlbmNlID0gb3B0aW9ucy5vbnNpbGVuY2U7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZXR1bmU6IDAsXG4gICAgICAgICAgICBvbnNpbGVuY2U6IG5vT3AsXG4gICAgICAgICAgICBwb3J0YW1lbnRvOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIG9mIHRoZSBub3RlIG9wdGlvbmFsbHkgd2l0aCBhIGdpdmVuIHZlbG9jaXR5LlxuICAgICAqIEBwYXJhbSAgbm90ZSBUaGUgbm90ZSB0byB0cmlnZ2VyLlxuICAgICAqIEBwYXJhbSAgdGltZSBXaGVuIHRoZSBub3RlIHNob3VsZCBzdGFydC5cbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBzY2FsZXIgZGV0ZXJtaW5lcyBob3cgXCJsb3VkXCIgdGhlIG5vdGUgd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIG5vdGUgYSBoYWxmIHNlY29uZCBmcm9tIG5vdyBhdCBoYWxmIHZlbG9jaXR5XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIsIFwiKzAuNVwiLCAwLjUpO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZSwgdGltZSwgdmVsb2NpdHkgPSAxKSB7XG4gICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHNlY29uZHMsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5zZXROb3RlKG5vdGUsIHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSAgdGltZSBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgcmVsZWFzZSBoYXBwZW5zIGltbWVkaWF0bHlcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogc3ludGgudHJpZ2dlckF0dGFjayhcIkM0XCIpO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2UgYSBzZWNvbmQgZnJvbSBub3dcbiAgICAgKiBzeW50aC50cmlnZ2VyUmVsZWFzZShcIisxXCIpO1xuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5sb2coXCJ0cmlnZ2VyUmVsZWFzZVwiLCB0aW1lKTtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHNlY29uZHMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBub3RlIGF0IHRoZSBnaXZlbiB0aW1lLiBJZiBubyB0aW1lIGlzIGdpdmVuLCB0aGUgbm90ZVxuICAgICAqIHdpbGwgc2V0IGltbWVkaWF0ZWx5LlxuICAgICAqIEBwYXJhbSBub3RlIFRoZSBub3RlIHRvIGNoYW5nZSB0by5cbiAgICAgKiBAcGFyYW0gIHRpbWUgVGhlIHRpbWUgd2hlbiB0aGUgbm90ZSBzaG91bGQgYmUgc2V0LlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBzeW50aC50cmlnZ2VyQXR0YWNrKFwiQzRcIik7XG4gICAgICogLy8gY2hhbmdlIHRvIEYjNiBpbiBvbmUgcXVhcnRlciBub3RlIGZyb20gbm93LlxuICAgICAqIHN5bnRoLnNldE5vdGUoXCJGIzZcIiwgXCIrNG5cIik7XG4gICAgICovXG4gICAgc2V0Tm90ZShub3RlLCB0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBjb21wdXRlZEZyZXF1ZW5jeSA9IG5vdGUgaW5zdGFuY2VvZiBGcmVxdWVuY3lDbGFzcyA/IG5vdGUudG9GcmVxdWVuY3koKSA6IG5vdGU7XG4gICAgICAgIGlmICh0aGlzLnBvcnRhbWVudG8gPiAwICYmIHRoaXMuZ2V0TGV2ZWxBdFRpbWUoY29tcHV0ZWRUaW1lKSA+IDAuMDUpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvcnRUaW1lID0gdGhpcy50b1NlY29uZHModGhpcy5wb3J0YW1lbnRvKTtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmV4cG9uZW50aWFsUmFtcFRvKGNvbXB1dGVkRnJlcXVlbmN5LCBwb3J0VGltZSwgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LnNldFZhbHVlQXRUaW1lKGNvbXB1dGVkRnJlcXVlbmN5LCBjb21wdXRlZFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHRpbWVSYW5nZSgwKVxuXSwgTW9ub3Bob25pYy5wcm90b3R5cGUsIFwicG9ydGFtZW50b1wiLCB2b2lkIDApO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9ub3Bob25pYy5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEVudmVsb3BlIH0gZnJvbSBcIi4vRW52ZWxvcGVcIjtcbi8qKlxuICogQW1wbGl0dWRlRW52ZWxvcGUgaXMgYSBUb25lLkVudmVsb3BlIGNvbm5lY3RlZCB0byBhIGdhaW4gbm9kZS5cbiAqIFVubGlrZSBUb25lLkVudmVsb3BlLCB3aGljaCBvdXRwdXRzIHRoZSBlbnZlbG9wZSdzIHZhbHVlLCBBbXBsaXR1ZGVFbnZlbG9wZSBhY2NlcHRzXG4gKiBhbiBhdWRpbyBzaWduYWwgYXMgdGhlIGlucHV0IGFuZCB3aWxsIGFwcGx5IHRoZSBlbnZlbG9wZSB0byB0aGUgYW1wbGl0dWRlXG4gKiBvZiB0aGUgc2lnbmFsLlxuICogUmVhZCBtb3JlIGFib3V0IEFEU1IgRW52ZWxvcGVzIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bnRoZXNpemVyI0FEU1JfZW52ZWxvcGUpLlxuICpcbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIFx0Y29uc3QgYW1wRW52ID0gbmV3IFRvbmUuQW1wbGl0dWRlRW52ZWxvcGUoe1xuICogXHRcdGF0dGFjazogMC4xLFxuICogXHRcdGRlY2F5OiAwLjIsXG4gKiBcdFx0c3VzdGFpbjogMS4wLFxuICogXHRcdHJlbGVhc2U6IDAuOFxuICogXHR9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBcdC8vIGNyZWF0ZSBhbiBvc2NpbGxhdG9yIGFuZCBjb25uZWN0IGl0XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGFtcEVudikuc3RhcnQoKTtcbiAqIFx0Ly8gdHJpZ2dlciB0aGUgZW52ZWxvcGVzIGF0dGFjayBhbmQgcmVsZWFzZSBcIjh0XCIgYXBhcnRcbiAqIFx0YW1wRW52LnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiOHRcIik7XG4gKiB9LCAxLjUsIDEpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQW1wbGl0dWRlRW52ZWxvcGUgZXh0ZW5kcyBFbnZlbG9wZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEFtcGxpdHVkZUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFtcGxpdHVkZUVudmVsb3BlXCI7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICAgICAgdGhpcy5fc2lnLmNvbm5lY3QodGhpcy5fZ2Fpbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZ2Fpbk5vZGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9nYWluTm9kZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW5Ob2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QW1wbGl0dWRlRW52ZWxvcGUuanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE9tbmlPc2NpbGxhdG9yIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL09tbmlPc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBTb3VyY2UgfSBmcm9tIFwiLi4vc291cmNlL1NvdXJjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbi8qKlxuICogU3ludGggaXMgY29tcG9zZWQgc2ltcGx5IG9mIGEgW1tPbW5pT3NjaWxsYXRvcl1dIHJvdXRlZCB0aHJvdWdoIGFuIFtbQW1wbGl0dWRlRW52ZWxvcGVdXS5cbiAqIGBgYFxuICogKy0tLS0tLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8IE9tbmlPc2NpbGxhdG9yICs+LS0+IEFtcGxpdHVkZUVudmVsb3BlICs+LS0+IE91dHB1dFxuICogKy0tLS0tLS0tLS0tLS0tLS0rICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBuZXcgT21uaU9zY2lsbGF0b3IoT2JqZWN0LmFzc2lnbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBkZXR1bmU6IG9wdGlvbnMuZGV0dW5lLFxuICAgICAgICAgICAgb25zdG9wOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSxcbiAgICAgICAgfSwgb3B0aW9ucy5vc2NpbGxhdG9yKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLmVudmVsb3BlKSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG9zY2lsbGF0b3JzIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmNoYWluKHRoaXMuZW52ZWxvcGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wib3NjaWxsYXRvclwiLCBcImZyZXF1ZW5jeVwiLCBcImRldHVuZVwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4zLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFsuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksIFwiZnJlcXVlbmN5XCIsIFwiZGV0dW5lXCJdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwidHJpYW5nbGVcIixcbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIGF0dGFjayBwb3J0aW9uIG9mIHRoZSBlbnZlbG9wZVxuICAgICAqIEBwYXJhbSB0aW1lIHRoZSB0aW1lIHRoZSBhdHRhY2sgc2hvdWxkIHN0YXJ0XG4gICAgICogQHBhcmFtIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgbm90ZSAoMC0xKVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVBdHRhY2sodGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgLy8gdGhlIGVudmVsb3Blc1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHJlbGVhc2UgcG9ydGlvbiwgc3RvcCB0aGUgb3NjaWxsYXRvclxuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZEF0dGFjayA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkRGVjYXkgPSB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KTtcbiAgICAgICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyBjb21wdXRlZEF0dGFjayArIGNvbXB1dGVkRGVjYXkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHN0YXJ0IHRoZSByZWxlYXNlIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIHJlbGVhc2Ugc2hvdWxkIHN0YXJ0XG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZVJlbGVhc2UodGltZSkge1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RvcCh0aW1lICsgdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5yZWxlYXNlKSk7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogY2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgYm90aCBBTSBhbmQgRk0gc3ludGhzXG4gKi9cbmV4cG9ydCBjbGFzcyBNb2R1bGF0aW9uU3ludGggZXh0ZW5kcyBNb25vcGhvbmljIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1vZHVsYXRpb25TeW50aFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9kdWxhdGlvblN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIgPSBuZXcgU3ludGgoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogb3B0aW9ucy5vc2NpbGxhdG9yLFxuICAgICAgICAgICAgZW52ZWxvcGU6IG9wdGlvbnMuZW52ZWxvcGUsXG4gICAgICAgICAgICBvbnNpbGVuY2U6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICAgICAgdm9sdW1lOiAtMTAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0b3IgPSBuZXcgU3ludGgoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogb3B0aW9ucy5tb2R1bGF0aW9uLFxuICAgICAgICAgICAgZW52ZWxvcGU6IG9wdGlvbnMubW9kdWxhdGlvbkVudmVsb3BlLFxuICAgICAgICAgICAgdm9sdW1lOiAtMTAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSB0aGlzLl9jYXJyaWVyLm9zY2lsbGF0b3I7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUgPSB0aGlzLl9jYXJyaWVyLmVudmVsb3BlO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb24gPSB0aGlzLl9tb2R1bGF0b3Iub3NjaWxsYXRvcjtcbiAgICAgICAgdGhpcy5tb2R1bGF0aW9uRW52ZWxvcGUgPSB0aGlzLl9tb2R1bGF0b3IuZW52ZWxvcGU7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmhhcm1vbmljaXR5ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmhhcm1vbmljaXR5LFxuICAgICAgICAgICAgbWluVmFsdWU6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZSA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmcmVxdWVuY3lcIiwgXCJoYXJtb25pY2l0eVwiLCBcIm9zY2lsbGF0b3JcIiwgXCJlbnZlbG9wZVwiLCBcIm1vZHVsYXRpb25cIiwgXCJtb2R1bGF0aW9uRW52ZWxvcGVcIiwgXCJkZXR1bmVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGFybW9uaWNpdHk6IDMsXG4gICAgICAgICAgICBvc2NpbGxhdG9yOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KE9tbmlPc2NpbGxhdG9yLmdldERlZmF1bHRzKCksIFtcbiAgICAgICAgICAgICAgICAuLi5PYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSksXG4gICAgICAgICAgICAgICAgXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgICAgICBcImRldHVuZVwiXG4gICAgICAgICAgICBdKSwge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2luZVwiXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAxLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIG1vZHVsYXRpb246IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoT21uaU9zY2lsbGF0b3IuZ2V0RGVmYXVsdHMoKSwgW1xuICAgICAgICAgICAgICAgIC4uLk9iamVjdC5rZXlzKFNvdXJjZS5nZXREZWZhdWx0cygpKSxcbiAgICAgICAgICAgICAgICBcImZyZXF1ZW5jeVwiLFxuICAgICAgICAgICAgICAgIFwiZGV0dW5lXCJcbiAgICAgICAgICAgIF0pLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcXVhcmVcIlxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBtb2R1bGF0aW9uRW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICB9KVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy5fY2Fycmllci5fdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9tb2R1bGF0b3IuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLl9jYXJyaWVyLl90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpO1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuX21vZHVsYXRvci5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGFybW9uaWNpdHkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uTm9kZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1vZHVsYXRpb25TeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBBdWRpb1RvR2FpbiB9IGZyb20gXCIuLi9zaWduYWwvQXVkaW9Ub0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTW9kdWxhdGlvblN5bnRoIH0gZnJvbSBcIi4vTW9kdWxhdGlvblN5bnRoXCI7XG4vKipcbiAqIEFNU3ludGggdXNlcyB0aGUgb3V0cHV0IG9mIG9uZSBUb25lLlN5bnRoIHRvIG1vZHVsYXRlIHRoZVxuICogYW1wbGl0dWRlIG9mIGFub3RoZXIgVG9uZS5TeW50aC4gVGhlIGhhcm1vbmljaXR5ICh0aGUgcmF0aW8gYmV0d2VlblxuICogdGhlIHR3byBzaWduYWxzKSBhZmZlY3RzIHRoZSB0aW1icmUgb2YgdGhlIG91dHB1dCBzaWduYWwgZ3JlYXRseS5cbiAqIFJlYWQgbW9yZSBhYm91dCBBbXBsaXR1ZGUgTW9kdWxhdGlvbiBTeW50aGVzaXMgb25cbiAqIFtTb3VuZE9uU291bmRdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwNDEwMzY1My9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb206ODAvc29zL21hcjAwL2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLkFNU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiNG5cIik7XG4gKlxuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEFNU3ludGggZXh0ZW5kcyBNb2R1bGF0aW9uU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkFNU3ludGhcIjtcbiAgICAgICAgdGhpcy5fbW9kdWxhdGlvblNjYWxlID0gbmV3IEF1ZGlvVG9HYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNoYWluKHRoaXMuX21vZHVsYXRpb25TY2FsZSwgdGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX2NhcnJpZXIuY2hhaW4odGhpcy5fbW9kdWxhdGlvbk5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9tb2R1bGF0aW9uU2NhbGUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BTVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFRoaW4gd3JhcHBlciBhcm91bmQgdGhlIG5hdGl2ZSBXZWIgQXVkaW8gW0JpcXVhZEZpbHRlck5vZGVdKGh0dHBzOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI2JpcXVhZGZpbHRlcm5vZGUpLlxuICogQmlxdWFkRmlsdGVyIGlzIHNpbWlsYXIgdG8gW1tGaWx0ZXJdXSBidXQgZG9lc24ndCBoYXZlIHRoZSBvcHRpb24gdG8gc2V0IHRoZSBcInJvbGxvZmZcIiB2YWx1ZS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEJpcXVhZEZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXF1YWRGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQmlxdWFkRmlsdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXF1YWRGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9maWx0ZXI7XG4gICAgICAgIHRoaXMuUSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJudW1iZXJcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9maWx0ZXIuZGV0dW5lLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5nYWluID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmdhaW4sXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZmlsdGVyLmdhaW4sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBROiAxLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvZiB0aGlzIEJpcXVhZEZpbHRlck5vZGUuIEZvciBhIGNvbXBsZXRlIGxpc3Qgb2YgdHlwZXMgYW5kIHRoZWlyIGF0dHJpYnV0ZXMsIHNlZSB0aGVcbiAgICAgKiBbV2ViIEF1ZGlvIEFQSV0oaHR0cHM6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jZG9tLWJpcXVhZGZpbHRlcnR5cGUtbG93cGFzcylcbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZpbHRlci50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID0gW1wibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsIFwiYmFuZHBhc3NcIixcbiAgICAgICAgICAgIFwibG93c2hlbGZcIiwgXCJoaWdoc2hlbGZcIiwgXCJub3RjaFwiLCBcImFsbHBhc3NcIiwgXCJwZWFraW5nXCJdO1xuICAgICAgICBhc3NlcnQodHlwZXMuaW5kZXhPZih0eXBlKSAhPT0gLTEsIGBJbnZhbGlkIGZpbHRlciB0eXBlOiAke3R5cGV9YCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlci50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgLy8gc3RhcnQgd2l0aCBhbGwgMXNcbiAgICAgICAgY29uc3QgZnJlcVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybSA9IE1hdGgucG93KGkgLyBsZW4sIDIpO1xuICAgICAgICAgICAgY29uc3QgZnJlcSA9IG5vcm0gKiAoMjAwMDAgLSAyMCkgKyAyMDtcbiAgICAgICAgICAgIGZyZXFWYWx1ZXNbaV0gPSBmcmVxO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hZ1ZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgY29uc3QgcGhhc2VWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIC8vIGNsb25lIHRoZSBmaWx0ZXIgdG8gcmVtb3ZlIGFueSBjb25uZWN0aW9ucyB3aGljaCBtYXkgYmUgY2hhbmdpbmcgdGhlIHZhbHVlXG4gICAgICAgIGNvbnN0IGZpbHRlckNsb25lID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICBmaWx0ZXJDbG9uZS50eXBlID0gdGhpcy50eXBlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5RLnZhbHVlID0gdGhpcy5RLnZhbHVlO1xuICAgICAgICBmaWx0ZXJDbG9uZS5mcmVxdWVuY3kudmFsdWUgPSB0aGlzLmZyZXF1ZW5jeS52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZ2Fpbi52YWx1ZSA9IHRoaXMuZ2Fpbi52YWx1ZTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UoZnJlcVZhbHVlcywgbWFnVmFsdWVzLCBwaGFzZVZhbHVlcyk7XG4gICAgICAgIHJldHVybiBtYWdWYWx1ZXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmlsdGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRldHVuZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpcXVhZEZpbHRlci5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuaW1wb3J0IHsgQmlxdWFkRmlsdGVyIH0gZnJvbSBcIi4vQmlxdWFkRmlsdGVyXCI7XG4vKipcbiAqIFRvbmUuRmlsdGVyIGlzIGEgZmlsdGVyIHdoaWNoIGFsbG93cyBmb3IgYWxsIG9mIHRoZSBzYW1lIG5hdGl2ZSBtZXRob2RzXG4gKiBhcyB0aGUgW0JpcXVhZEZpbHRlck5vZGVdKGh0dHA6Ly93ZWJhdWRpby5naXRodWIuaW8vd2ViLWF1ZGlvLWFwaS8jdGhlLWJpcXVhZGZpbHRlcm5vZGUtaW50ZXJmYWNlKS5cbiAqIFRvbmUuRmlsdGVyIGhhcyB0aGUgYWRkZWQgYWJpbGl0eSB0byBzZXQgdGhlIGZpbHRlciByb2xsb2ZmIGF0IC0xMlxuICogKGRlZmF1bHQpLCAtMjQgYW5kIC00OC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmaWx0ZXIgPSBuZXcgVG9uZS5GaWx0ZXIoMTUwMCwgXCJoaWdocGFzc1wiKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBmaWx0ZXIuZnJlcXVlbmN5LnJhbXBUbygyMDAwMCwgMTApO1xuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLmNvbm5lY3QoZmlsdGVyKS5zdGFydCgpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcInR5cGVcIiwgXCJyb2xsb2ZmXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRmlsdGVyXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fZmlsdGVycyA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiLCBcInJvbGxvZmZcIl0pO1xuICAgICAgICB0aGlzLl9maWx0ZXJzID0gW107XG4gICAgICAgIHRoaXMuUSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRldHVuZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiY2VudHNcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRldHVuZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZ2FpbiA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZ2FpbixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMucm9sbG9mZiA9IG9wdGlvbnMucm9sbG9mZjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZGV0dW5lXCIsIFwiZnJlcXVlbmN5XCIsIFwiZ2FpblwiLCBcIlFcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgIGRldHVuZTogMCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMzUwLFxuICAgICAgICAgICAgZ2FpbjogMCxcbiAgICAgICAgICAgIHJvbGxvZmY6IC0xMixcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHR5cGUgb2YgdGhlIGZpbHRlci4gVHlwZXM6IFwibG93cGFzc1wiLCBcImhpZ2hwYXNzXCIsXG4gICAgICogXCJiYW5kcGFzc1wiLCBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIG9yIFwicGVha2luZ1wiLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICBjb25zdCB0eXBlcyA9IFtcImxvd3Bhc3NcIiwgXCJoaWdocGFzc1wiLCBcImJhbmRwYXNzXCIsXG4gICAgICAgICAgICBcImxvd3NoZWxmXCIsIFwiaGlnaHNoZWxmXCIsIFwibm90Y2hcIiwgXCJhbGxwYXNzXCIsIFwicGVha2luZ1wiXTtcbiAgICAgICAgYXNzZXJ0KHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xLCBgSW52YWxpZCBmaWx0ZXIgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiBmaWx0ZXIudHlwZSA9IHR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcm9sbG9mZiBvZiB0aGUgZmlsdGVyIHdoaWNoIGlzIHRoZSBkcm9wIGluIGRiXG4gICAgICogcGVyIG9jdGF2ZS4gSW1wbGVtZW50ZWQgaW50ZXJuYWxseSBieSBjYXNjYWRpbmcgZmlsdGVycy5cbiAgICAgKiBPbmx5IGFjY2VwdHMgdGhlIHZhbHVlcyAtMTIsIC0yNCwgLTQ4IGFuZCAtOTYuXG4gICAgICovXG4gICAgZ2V0IHJvbGxvZmYoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9yb2xsb2ZmO1xuICAgIH1cbiAgICBzZXQgcm9sbG9mZihyb2xsb2ZmKSB7XG4gICAgICAgIGNvbnN0IHJvbGxvZmZOdW0gPSBpc051bWJlcihyb2xsb2ZmKSA/IHJvbGxvZmYgOiBwYXJzZUludChyb2xsb2ZmLCAxMCk7XG4gICAgICAgIGNvbnN0IHBvc3NpYmlsaXRpZXMgPSBbLTEyLCAtMjQsIC00OCwgLTk2XTtcbiAgICAgICAgbGV0IGNhc2NhZGluZ0NvdW50ID0gcG9zc2liaWxpdGllcy5pbmRleE9mKHJvbGxvZmZOdW0pO1xuICAgICAgICAvLyBjaGVjayB0aGUgcm9sbG9mZiBpcyB2YWxpZFxuICAgICAgICBhc3NlcnQoY2FzY2FkaW5nQ291bnQgIT09IC0xLCBgcm9sbG9mZiBjYW4gb25seSBiZSAke3Bvc3NpYmlsaXRpZXMuam9pbihcIiwgXCIpfWApO1xuICAgICAgICBjYXNjYWRpbmdDb3VudCArPSAxO1xuICAgICAgICB0aGlzLl9yb2xsb2ZmID0gcm9sbG9mZk51bTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMuZm9yRWFjaChmaWx0ZXIgPT4gZmlsdGVyLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnMgPSBuZXcgQXJyYXkoY2FzY2FkaW5nQ291bnQpO1xuICAgICAgICBmb3IgKGxldCBjb3VudCA9IDA7IGNvdW50IDwgY2FzY2FkaW5nQ291bnQ7IGNvdW50KyspIHtcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlciA9IG5ldyBCaXF1YWRGaWx0ZXIoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZmlsdGVyLnR5cGUgPSB0aGlzLl90eXBlO1xuICAgICAgICAgICAgdGhpcy5mcmVxdWVuY3kuY29ubmVjdChmaWx0ZXIuZnJlcXVlbmN5KTtcbiAgICAgICAgICAgIHRoaXMuZGV0dW5lLmNvbm5lY3QoZmlsdGVyLmRldHVuZSk7XG4gICAgICAgICAgICB0aGlzLlEuY29ubmVjdChmaWx0ZXIuUSk7XG4gICAgICAgICAgICB0aGlzLmdhaW4uY29ubmVjdChmaWx0ZXIuZ2Fpbik7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXJzW2NvdW50XSA9IGZpbHRlcjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gdGhpcy5fZmlsdGVycztcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9pbnRlcm5hbENoYW5uZWxzLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlLiBUaGlzIGN1cnZlIHJlcHJlc2VudHMgaG93IHRoZSBmaWx0ZXJcbiAgICAgKiByZXNwb25zZXMgdG8gZnJlcXVlbmNpZXMgYmV0d2VlbiAyMGh6LTIwa2h6LlxuICAgICAqIEBwYXJhbSAgbGVuIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRvIHJldHVyblxuICAgICAqIEByZXR1cm4gVGhlIGZyZXF1ZW5jeSByZXNwb25zZSBjdXJ2ZSBiZXR3ZWVuIDIwLTIwa0h6XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuID0gMTI4KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlckNsb25lID0gbmV3IEJpcXVhZEZpbHRlcih7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IHRoaXMuZnJlcXVlbmN5LnZhbHVlLFxuICAgICAgICAgICAgZ2FpbjogdGhpcy5nYWluLnZhbHVlLFxuICAgICAgICAgICAgUTogdGhpcy5RLnZhbHVlLFxuICAgICAgICAgICAgdHlwZTogdGhpcy5fdHlwZSxcbiAgICAgICAgICAgIGRldHVuZTogdGhpcy5kZXR1bmUudmFsdWUsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBzdGFydCB3aXRoIGFsbCAxc1xuICAgICAgICBjb25zdCB0b3RhbFJlc3BvbnNlID0gbmV3IEZsb2F0MzJBcnJheShsZW4pLm1hcCgoKSA9PiAxKTtcbiAgICAgICAgdGhpcy5fZmlsdGVycy5mb3JFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gZmlsdGVyQ2xvbmUuZ2V0RnJlcXVlbmN5UmVzcG9uc2UobGVuKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLmZvckVhY2goKHZhbCwgaSkgPT4gdG90YWxSZXNwb25zZVtpXSAqPSB2YWwpO1xuICAgICAgICB9KTtcbiAgICAgICAgZmlsdGVyQ2xvbmUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdG90YWxSZXNwb25zZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXAuXG4gICAgICovXG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IHtcbiAgICAgICAgICAgIGZpbHRlci5kaXNwb3NlKCk7XG4gICAgICAgIH0pO1xuICAgICAgICB3cml0YWJsZSh0aGlzLCBbXCJkZXR1bmVcIiwgXCJmcmVxdWVuY3lcIiwgXCJnYWluXCIsIFwiUVwiXSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmdhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBTY2FsZSB9IGZyb20gXCIuLi8uLi9zaWduYWwvU2NhbGVcIjtcbmltcG9ydCB7IFBvdyB9IGZyb20gXCIuLi8uLi9zaWduYWwvUG93XCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogRnJlcXVlbmN5RW52ZWxvcGUgaXMgYW4gW1tFbnZlbG9wZV1dIHdoaWNoIHJhbXBzIGJldHdlZW4gW1tiYXNlRnJlcXVlbmN5XV1cbiAqIGFuZCBbW29jdGF2ZXNdXS4gSXQgY2FuIGFsc28gaGF2ZSBhbiBvcHRpb25hbCBbW2V4cG9uZW50XV0gdG8gYWRqdXN0IHRoZSBjdXJ2ZVxuICogd2hpY2ggaXQgcmFtcHMuXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIGNvbnN0IGZyZXFFbnYgPSBuZXcgVG9uZS5GcmVxdWVuY3lFbnZlbG9wZSh7XG4gKiBcdGF0dGFjazogMC4yLFxuICogXHRiYXNlRnJlcXVlbmN5OiBcIkMyXCIsXG4gKiBcdG9jdGF2ZXM6IDRcbiAqIH0pO1xuICogZnJlcUVudi5jb25uZWN0KG9zY2lsbGF0b3IuZnJlcXVlbmN5KTtcbiAqIGZyZXFFbnYudHJpZ2dlckF0dGFjaygpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRnJlcXVlbmN5RW52ZWxvcGUgZXh0ZW5kcyBFbnZlbG9wZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYXR0YWNrXCIsIFwiZGVjYXlcIiwgXCJzdXN0YWluXCIsIFwicmVsZWFzZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeUVudmVsb3BlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVxdWVuY3lFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImF0dGFja1wiLCBcImRlY2F5XCIsIFwic3VzdGFpblwiLCBcInJlbGVhc2VcIl0pO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9leHBvbmVudCA9IHRoaXMuaW5wdXQgPSBuZXcgUG93KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmV4cG9uZW50XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZSA9IHRoaXMub3V0cHV0ID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogdGhpcy5fYmFzZUZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1heDogdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIHRoaXMuX29jdGF2ZXMpLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2lnLmNoYWluKHRoaXMuX2V4cG9uZW50LCB0aGlzLl9zY2FsZSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgZXhwb25lbnQ6IDEsXG4gICAgICAgICAgICBvY3RhdmVzOiA0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVudmVsb3BlJ3MgbWluaW11bSBvdXRwdXQgdmFsdWUuIFRoaXMgaXMgdGhlIHZhbHVlIHdoaWNoIGl0XG4gICAgICogc3RhcnRzIGF0LlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3kobWluKSB7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KG1pbik7XG4gICAgICAgIGFzc2VydFJhbmdlKGZyZXEsIDApO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gZnJlcTtcbiAgICAgICAgdGhpcy5fc2NhbGUubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBtYXggdmFsdWUgd2hlbiB0aGUgbWluIGNoYW5nZXNcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5IHRoYXQgdGhlXG4gICAgICogZW52ZWxvcGUgd2lsbCBzY2FsZSB0by5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdGF2ZXMpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9jdGF2ZXM7XG4gICAgICAgIHRoaXMuX3NjYWxlLm1heCA9IHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCBvY3RhdmVzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGVudmVsb3BlJ3MgZXhwb25lbnQgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IGV4cG9uZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXhwb25lbnQudmFsdWU7XG4gICAgfVxuICAgIHNldCBleHBvbmVudChleHBvbmVudCkge1xuICAgICAgICB0aGlzLl9leHBvbmVudC52YWx1ZSA9IGV4cG9uZW50O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cFxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZXhwb25lbnQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeUVudmVsb3BlLmpzLm1hcCIsImltcG9ydCB7IEFtcGxpdHVkZUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9BbXBsaXR1ZGVFbnZlbG9wZVwiO1xuaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi4vaW5zdHJ1bWVudC9Nb25vcGhvbmljXCI7XG5pbXBvcnQgeyBPbW5pT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9PbW5pT3NjaWxsYXRvclwiO1xuaW1wb3J0IHsgU291cmNlIH0gZnJvbSBcIi4uL3NvdXJjZS9Tb3VyY2VcIjtcbmltcG9ydCB7IEZyZXF1ZW5jeUVudmVsb3BlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9lbnZlbG9wZS9GcmVxdWVuY3lFbnZlbG9wZVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuLyoqXG4gKiBNb25vU3ludGggaXMgY29tcG9zZWQgb2Ygb25lIGBvc2NpbGxhdG9yYCwgb25lIGBmaWx0ZXJgLCBhbmQgdHdvIGBlbnZlbG9wZXNgLlxuICogVGhlIGFtcGxpdHVkZSBvZiB0aGUgT3NjaWxsYXRvciBhbmQgdGhlIGN1dG9mZiBmcmVxdWVuY3kgb2YgdGhlXG4gKiBGaWx0ZXIgYXJlIGNvbnRyb2xsZWQgYnkgRW52ZWxvcGVzLlxuICogPGltZyBzcmM9XCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9kcmF3aW5ncy9kLzFnYVkxREY5X0h6a29kcWY4SkkxQ2cyVlpmd1NFbHBGUWZJOTRJUXdhZDM4L3B1Yj93PTkyNCZoPTI0MFwiPlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTW9ub1N5bnRoKHtcbiAqIFx0b3NjaWxsYXRvcjoge1xuICogXHRcdHR5cGU6IFwic3F1YXJlXCJcbiAqIFx0fSxcbiAqIFx0ZW52ZWxvcGU6IHtcbiAqIFx0XHRhdHRhY2s6IDAuMVxuICogXHR9XG4gKiB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM0XCIsIFwiOG5cIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTW9ub1N5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb25vU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3IgPSBuZXcgT21uaU9zY2lsbGF0b3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm9zY2lsbGF0b3IsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRldHVuZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgICAgICBvbnN0b3A6ICgpID0+IHRoaXMub25zaWxlbmNlKHRoaXMpLFxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSB0aGlzLm9zY2lsbGF0b3IuZGV0dW5lO1xuICAgICAgICB0aGlzLmZpbHRlciA9IG5ldyBGaWx0ZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zLmZpbHRlciwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlID0gbmV3IEZyZXF1ZW5jeUVudmVsb3BlKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXJFbnZlbG9wZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5lbnZlbG9wZSwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBvc2NpbGxhdG9ycyB0byB0aGUgb3V0cHV0XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5jaGFpbih0aGlzLmZpbHRlciwgdGhpcy5lbnZlbG9wZSwgdGhpcy5vdXRwdXQpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBmaWx0ZXIgZW52ZWxvcGVcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS5jb25uZWN0KHRoaXMuZmlsdGVyLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIm9zY2lsbGF0b3JcIiwgXCJmcmVxdWVuY3lcIiwgXCJkZXR1bmVcIiwgXCJmaWx0ZXJcIiwgXCJmaWx0ZXJFbnZlbG9wZVwiLCBcImVudmVsb3BlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNb25vcGhvbmljLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAwNSxcbiAgICAgICAgICAgICAgICBkZWNheTogMC4xLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC45LFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBmaWx0ZXI6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRmlsdGVyLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgUTogMSxcbiAgICAgICAgICAgICAgICByb2xsb2ZmOiAtMTIsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiBPYmplY3QuYXNzaWduKG9taXRGcm9tT2JqZWN0KEZyZXF1ZW5jeUVudmVsb3BlLmdldERlZmF1bHRzKCksIE9iamVjdC5rZXlzKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjYsXG4gICAgICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjIsXG4gICAgICAgICAgICAgICAgZXhwb25lbnQ6IDIsXG4gICAgICAgICAgICAgICAgb2N0YXZlczogMyxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAyLFxuICAgICAgICAgICAgICAgIHN1c3RhaW46IDAuNSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChPbW5pT3NjaWxsYXRvci5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBzdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3BlXG4gICAgICogQHBhcmFtIHRpbWUgdGhlIHRpbWUgdGhlIGF0dGFjayBzaG91bGQgc3RhcnRcbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgdGhlIHZlbG9jaXR5IG9mIHRoZSBub3RlICgwLTEpXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5maWx0ZXJFbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUpO1xuICAgICAgICB0aGlzLm9zY2lsbGF0b3Iuc3RhcnQodGltZSk7XG4gICAgICAgIGlmICh0aGlzLmVudmVsb3BlLnN1c3RhaW4gPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbXB1dGVkQXR0YWNrID0gdGhpcy50b1NlY29uZHModGhpcy5lbnZlbG9wZS5hdHRhY2spO1xuICAgICAgICAgICAgY29uc3QgY29tcHV0ZWREZWNheSA9IHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpO1xuICAgICAgICAgICAgdGhpcy5vc2NpbGxhdG9yLnN0b3AodGltZSArIGNvbXB1dGVkQXR0YWNrICsgY29tcHV0ZWREZWNheSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogc3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVcbiAgICAgKiBAcGFyYW0gdGltZSB0aGUgdGltZSB0aGUgcmVsZWFzZSBzaG91bGQgc3RhcnRcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKSB7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMuZmlsdGVyRW52ZWxvcGUudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLnJlbGVhc2UpKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3NjaWxsYXRvci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZpbHRlckVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Nb25vU3ludGguanMubWFwIiwiaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IE1vbm9TeW50aCB9IGZyb20gXCIuL01vbm9TeW50aFwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IEdhaW4sIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuLyoqXG4gKiBEdW9TeW50aCBpcyBhIG1vbm9waG9uaWMgc3ludGggY29tcG9zZWQgb2YgdHdvIFtbTW9ub1N5bnRoc11dIHJ1biBpbiBwYXJhbGxlbCB3aXRoIGNvbnRyb2wgb3ZlciB0aGVcbiAqIGZyZXF1ZW5jeSByYXRpbyBiZXR3ZWVuIHRoZSB0d28gdm9pY2VzIGFuZCB2aWJyYXRvIGVmZmVjdC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkdW9TeW50aCA9IG5ldyBUb25lLkR1b1N5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogZHVvU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjJuXCIpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIER1b1N5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKER1b1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkR1b1N5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhEdW9TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnZvaWNlMCA9IG5ldyBNb25vU3ludGgoT2JqZWN0LmFzc2lnbihvcHRpb25zLnZvaWNlMCwge1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgb25zaWxlbmNlOiAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKVxuICAgICAgICB9KSk7XG4gICAgICAgIHRoaXMudm9pY2UxID0gbmV3IE1vbm9TeW50aChPYmplY3QuYXNzaWduKG9wdGlvbnMudm9pY2UxLCB7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eSA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl92aWJyYXRvID0gbmV3IExGTyh7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMudmlicmF0b1JhdGUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtaW46IC01MCxcbiAgICAgICAgICAgIG1heDogNTBcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSB2aWJyYXRvIGltbWVkaWF0ZWx5XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uc3RhcnQoKTtcbiAgICAgICAgdGhpcy52aWJyYXRvUmF0ZSA9IHRoaXMuX3ZpYnJhdG8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl92aWJyYXRvR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLnZpYnJhdG9BbW91bnRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudmlicmF0b0Ftb3VudCA9IHRoaXMuX3ZpYnJhdG9HYWluLmdhaW47XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiA0NDBcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGV0dW5lID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJjZW50c1wiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuZGV0dW5lXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb250cm9sIHRoZSB0d28gdm9pY2VzIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jb25uZWN0KHRoaXMudm9pY2UwLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKHRoaXMuaGFybW9uaWNpdHksIHRoaXMudm9pY2UxLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG8uY29ubmVjdCh0aGlzLl92aWJyYXRvR2Fpbik7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmZhbih0aGlzLnZvaWNlMC5kZXR1bmUsIHRoaXMudm9pY2UxLmRldHVuZSk7XG4gICAgICAgIHRoaXMuZGV0dW5lLmZhbih0aGlzLnZvaWNlMC5kZXR1bmUsIHRoaXMudm9pY2UxLmRldHVuZSk7XG4gICAgICAgIHRoaXMudm9pY2UwLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLnZvaWNlMS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1widm9pY2UwXCIsIFwidm9pY2UxXCIsIFwiZnJlcXVlbmN5XCIsIFwidmlicmF0b0Ftb3VudFwiLCBcInZpYnJhdG9SYXRlXCJdKTtcbiAgICB9XG4gICAgZ2V0TGV2ZWxBdFRpbWUodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzLnZvaWNlMC5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKSArIHRoaXMudm9pY2UxLmVudmVsb3BlLmdldFZhbHVlQXRUaW1lKHRpbWUpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB2aWJyYXRvQW1vdW50OiAwLjUsXG4gICAgICAgICAgICB2aWJyYXRvUmF0ZTogNSxcbiAgICAgICAgICAgIGhhcm1vbmljaXR5OiAxLjUsXG4gICAgICAgICAgICB2b2ljZTA6IGRlZXBNZXJnZShvbWl0RnJvbU9iamVjdChNb25vU3ludGguZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBmaWx0ZXJFbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZW52ZWxvcGU6IHtcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAxLFxuICAgICAgICAgICAgICAgICAgICBkZWNheTogMC4wLFxuICAgICAgICAgICAgICAgICAgICBzdXN0YWluOiAxLFxuICAgICAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIHZvaWNlMTogZGVlcE1lcmdlKG9taXRGcm9tT2JqZWN0KE1vbm9TeW50aC5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhNb25vcGhvbmljLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGZpbHRlckVudmVsb3BlOiB7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMSxcbiAgICAgICAgICAgICAgICAgICAgZGVjYXk6IDAuMCxcbiAgICAgICAgICAgICAgICAgICAgc3VzdGFpbjogMSxcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZTogMC41XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDEsXG4gICAgICAgICAgICAgICAgICAgIGRlY2F5OiAwLjAsXG4gICAgICAgICAgICAgICAgICAgIHN1c3RhaW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuNVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKi9cbiAgICBfdHJpZ2dlckVudmVsb3BlQXR0YWNrKHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTAuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgdGhpcy52b2ljZTEuX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgbm90ZVxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMC5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnZvaWNlMS5fdHJpZ2dlckVudmVsb3BlUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2ljZTAuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvaWNlMS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl92aWJyYXRvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52aWJyYXRvUmF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3ZpYnJhdG9HYWluLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oYXJtb25pY2l0eS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUR1b1N5bnRoLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTXVsdGlwbHkgfSBmcm9tIFwiLi4vc2lnbmFsL011bHRpcGx5XCI7XG5pbXBvcnQgeyBNb2R1bGF0aW9uU3ludGggfSBmcm9tIFwiLi9Nb2R1bGF0aW9uU3ludGhcIjtcbi8qKlxuICogRk1TeW50aCBpcyBjb21wb3NlZCBvZiB0d28gVG9uZS5TeW50aHMgd2hlcmUgb25lIFRvbmUuU3ludGggbW9kdWxhdGVzXG4gKiB0aGUgZnJlcXVlbmN5IG9mIGEgc2Vjb25kIFRvbmUuU3ludGguIEEgbG90IG9mIHNwZWN0cmFsIGNvbnRlbnRcbiAqIGNhbiBiZSBleHBsb3JlZCB1c2luZyB0aGUgbW9kdWxhdGlvbkluZGV4IHBhcmFtZXRlci4gUmVhZCBtb3JlIGFib3V0XG4gKiBmcmVxdWVuY3kgbW9kdWxhdGlvbiBzeW50aGVzaXMgb24gU291bmQgT24gU291bmQ6IFtQYXJ0IDFdKGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE2MDQwMzEyMzcwNC9odHRwOi8vd3d3LnNvdW5kb25zb3VuZC5jb20vc29zL2FwcjAwL2FydGljbGVzL3N5bnRoc2VjcmV0cy5odG0pLCBbUGFydCAyXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDMxMTU4MzUvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tL3Nvcy9tYXkwMC9hcnRpY2xlcy9zeW50aC5odG0pLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmbVN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIGZtU3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNVwiLCBcIjRuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBGTVN5bnRoIGV4dGVuZHMgTW9kdWxhdGlvblN5bnRoIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRk1TeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGTVN5bnRoXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGTVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMubW9kdWxhdGlvbkluZGV4ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIHR3byB2b2ljZXMgZnJlcXVlbmN5XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5jaGFpbih0aGlzLmhhcm1vbmljaXR5LCB0aGlzLl9tb2R1bGF0b3IuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuY2hhaW4odGhpcy5tb2R1bGF0aW9uSW5kZXgsIHRoaXMuX21vZHVsYXRpb25Ob2RlKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZmFuKHRoaXMuX2NhcnJpZXIuZGV0dW5lLCB0aGlzLl9tb2R1bGF0b3IuZGV0dW5lKTtcbiAgICAgICAgdGhpcy5fbW9kdWxhdG9yLmNvbm5lY3QodGhpcy5fbW9kdWxhdGlvbk5vZGUuZ2Fpbik7XG4gICAgICAgIHRoaXMuX21vZHVsYXRpb25Ob2RlLmNvbm5lY3QodGhpcy5fY2Fycmllci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9jYXJyaWVyLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1vZHVsYXRpb25TeW50aC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtb2R1bGF0aW9uSW5kZXg6IDEwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1vZHVsYXRpb25JbmRleC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZNU3ludGguanMubWFwIiwiaW1wb3J0IHsgRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0VudmVsb3BlXCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSwgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZNT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9GTU9zY2lsbGF0b3JcIjtcbmltcG9ydCB7IE1vbm9waG9uaWMgfSBmcm9tIFwiLi9Nb25vcGhvbmljXCI7XG4vKipcbiAqIEluaGFybW9uaWMgcmF0aW8gb2YgZnJlcXVlbmNpZXMgYmFzZWQgb24gdGhlIFJvbGFuZCBUUi04MDhcbiAqIFRha2VuIGZyb20gaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvcGFwZXJzL3RyLTgwOC1jeW1iYWwtcGh5c2ljYWxseS1pbmZvcm1lZC1jaXJjdWl0LWJlbmRhYmxlLWRpZ2l0YWwtbW9kZWxcbiAqL1xuY29uc3QgaW5oYXJtUmF0aW9zID0gWzEuMCwgMS40ODMsIDEuOTMyLCAyLjU0NiwgMi42MzAsIDMuODk3XTtcbi8qKlxuICogQSBoaWdobHkgaW5oYXJtb25pYyBhbmQgc3BlY3RyYWxseSBjb21wbGV4IHNvdXJjZSB3aXRoIGEgaGlnaHBhc3MgZmlsdGVyXG4gKiBhbmQgYW1wbGl0dWRlIGVudmVsb3BlIHdoaWNoIGlzIGdvb2QgZm9yIG1ha2luZyBtZXRhbGxvcGhvbmUgc291bmRzLlxuICogQmFzZWQgb24gQ3ltYmFsU3ludGggYnkgW0Bwb2x5cmh5dGhtYXRpY10oaHR0cHM6Ly9naXRodWIuY29tL3BvbHlyaHl0aG1hdGljKS5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1NvdW5kIG9uIFNvdW5kXShodHRwczovL3Nob3J0dXJsLmF0L3JTWjEyKS5cbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRhbFN5bnRoIGV4dGVuZHMgTW9ub3Bob25pYyB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGFsU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0YWxTeW50aFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGFycmF5IG9mIEZNT3NjaWxsYXRvcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX29zY2lsbGF0b3JzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgZnJlcXVlbmN5IG11bHRpcGxpZXJzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9mcmVxTXVsdGlwbGllcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGFsU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5kZXR1bmUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcImNlbnRzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZXR1bmUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGUgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5faGlnaHBhc3MgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIC8vIFE6IC0zLjAxMDI5OTk1NjYzOTgxMjUsXG4gICAgICAgICAgICBROiAwLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJoaWdocGFzc1wiLFxuICAgICAgICB9KS5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5oYXJtUmF0aW9zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBvc2MgPSBuZXcgRk1Pc2NpbGxhdG9yKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgaGFybW9uaWNpdHk6IG9wdGlvbnMuaGFybW9uaWNpdHksXG4gICAgICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiBvcHRpb25zLm1vZHVsYXRpb25JbmRleCxcbiAgICAgICAgICAgICAgICBtb2R1bGF0aW9uVHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgICAgICAgICBvbnN0b3A6IGkgPT09IDAgPyAoKSA9PiB0aGlzLm9uc2lsZW5jZSh0aGlzKSA6IG5vT3AsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJzcXVhcmVcIixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgb3NjLmNvbm5lY3QodGhpcy5faGlnaHBhc3MpO1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnNbaV0gPSBvc2M7XG4gICAgICAgICAgICBjb25zdCBtdWx0ID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGluaGFybVJhdGlvc1tpXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fZnJlcU11bHRpcGxpZXJzW2ldID0gbXVsdDtcbiAgICAgICAgICAgIHRoaXMuZnJlcXVlbmN5LmNoYWluKG11bHQsIG9zYy5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgdGhpcy5kZXR1bmUuY29ubmVjdChvc2MuZGV0dW5lKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heDogNzAwMCxcbiAgICAgICAgICAgIG1pbjogdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLnJlc29uYW5jZSksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEVudmVsb3BlKHtcbiAgICAgICAgICAgIGF0dGFjazogb3B0aW9ucy5lbnZlbG9wZS5hdHRhY2ssXG4gICAgICAgICAgICBhdHRhY2tDdXJ2ZTogXCJsaW5lYXJcIixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlY2F5OiBvcHRpb25zLmVudmVsb3BlLmRlY2F5LFxuICAgICAgICAgICAgcmVsZWFzZTogb3B0aW9ucy5lbnZlbG9wZS5yZWxlYXNlLFxuICAgICAgICAgICAgc3VzdGFpbjogMCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZW52ZWxvcGUuY2hhaW4odGhpcy5fZmlsdGVyRnJlcVNjYWxlciwgdGhpcy5faGlnaHBhc3MuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5jb25uZWN0KHRoaXMuX2FtcGxpdHVkZS5nYWluKTtcbiAgICAgICAgLy8gc2V0IHRoZSBvY3RhdmVzXG4gICAgICAgIHRoaXMuX29jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gZGVlcE1lcmdlKE1vbm9waG9uaWMuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZW52ZWxvcGU6IE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoRW52ZWxvcGUuZ2V0RGVmYXVsdHMoKSwgT2JqZWN0LmtleXMoVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpKSksIHtcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDAxLFxuICAgICAgICAgICAgICAgIGRlY2F5OiAxLjQsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBoYXJtb25pY2l0eTogNS4xLFxuICAgICAgICAgICAgbW9kdWxhdGlvbkluZGV4OiAzMixcbiAgICAgICAgICAgIG9jdGF2ZXM6IDEuNSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogNDAwMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjay5cbiAgICAgKiBAcGFyYW0gdGltZSBXaGVuIHRoZSBhdHRhY2sgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAcGFyYW0gdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRoYXQgdGhlIGVudmVsb3BlIHNob3VsZCBiZSB0cmlnZ2VyZWQgYXQuXG4gICAgICovXG4gICAgX3RyaWdnZXJFbnZlbG9wZUF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyQXR0YWNrKHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLnN0YXJ0KHRpbWUpKTtcbiAgICAgICAgaWYgKHRoaXMuZW52ZWxvcGUuc3VzdGFpbiA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4ge1xuICAgICAgICAgICAgICAgIG9zYy5zdG9wKHRpbWUgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmF0dGFjaykgKyB0aGlzLnRvU2Vjb25kcyh0aGlzLmVudmVsb3BlLmRlY2F5KSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgZW52ZWxvcGUuXG4gICAgICogQHBhcmFtIHRpbWUgV2hlbiB0aGUgcmVsZWFzZSBzaG91bGQgYmUgdHJpZ2dlcmVkLlxuICAgICAqL1xuICAgIF90cmlnZ2VyRW52ZWxvcGVSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS50cmlnZ2VyUmVsZWFzZSh0aW1lKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldExldmVsQXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcy5lbnZlbG9wZS5nZXRWYWx1ZUF0VGltZSh0aW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG1vZHVsYXRpb25JbmRleCBvZiB0aGUgb3NjaWxsYXRvcnMgd2hpY2ggbWFrZSB1cCB0aGUgc291cmNlLlxuICAgICAqIHNlZSBbW0ZNT3NjaWxsYXRvci5tb2R1bGF0aW9uSW5kZXhdXVxuICAgICAqIEBtaW4gMVxuICAgICAqIEBtYXggMTAwXG4gICAgICovXG4gICAgZ2V0IG1vZHVsYXRpb25JbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29zY2lsbGF0b3JzWzBdLm1vZHVsYXRpb25JbmRleC52YWx1ZTtcbiAgICB9XG4gICAgc2V0IG1vZHVsYXRpb25JbmRleCh2YWwpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gKG9zYy5tb2R1bGF0aW9uSW5kZXgudmFsdWUgPSB2YWwpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGhhcm1vbmljaXR5IG9mIHRoZSBvc2NpbGxhdG9ycyB3aGljaCBtYWtlIHVwIHRoZSBzb3VyY2UuXG4gICAgICogc2VlIFRvbmUuRk1Pc2NpbGxhdG9yLmhhcm1vbmljaXR5XG4gICAgICogQG1pbiAwLjFcbiAgICAgKiBAbWF4IDEwXG4gICAgICovXG4gICAgZ2V0IGhhcm1vbmljaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb3NjaWxsYXRvcnNbMF0uaGFybW9uaWNpdHkudmFsdWU7XG4gICAgfVxuICAgIHNldCBoYXJtb25pY2l0eSh2YWwpIHtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gKG9zYy5oYXJtb25pY2l0eS52YWx1ZSA9IHZhbCkpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbG93ZXIgbGV2ZWwgb2YgdGhlIGhpZ2hwYXNzIGZpbHRlciB3aGljaCBpcyBhdHRhY2hlZCB0byB0aGUgZW52ZWxvcGUuXG4gICAgICogVGhpcyB2YWx1ZSBzaG91bGQgYmUgYmV0d2VlbiBbMCwgNzAwMF1cbiAgICAgKiBAbWluIDBcbiAgICAgKiBAbWF4IDcwMDBcbiAgICAgKi9cbiAgICBnZXQgcmVzb25hbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5taW47XG4gICAgfVxuICAgIHNldCByZXNvbmFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX2ZpbHRlckZyZXFTY2FsZXIubWluID0gdGhpcy50b0ZyZXF1ZW5jeSh2YWwpO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG9jdGF2ZXMgYWJvdmUgdGhlIFwicmVzb25hbmNlXCIgZnJlcXVlbmN5XG4gICAgICogdGhhdCB0aGUgZmlsdGVyIHJhbXBzIGR1cmluZyB0aGUgYXR0YWNrL2RlY2F5IGVudmVsb3BlXG4gICAgICogQG1pbiAwXG4gICAgICogQG1heCA4XG4gICAgICovXG4gICAgZ2V0IG9jdGF2ZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICBzZXQgb2N0YXZlcyh2YWwpIHtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IHZhbDtcbiAgICAgICAgdGhpcy5fZmlsdGVyRnJlcVNjYWxlci5tYXggPSB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLm1pbiAqIE1hdGgucG93KDIsIHZhbCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fb3NjaWxsYXRvcnMuZm9yRWFjaChvc2MgPT4gb3NjLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2ZyZXFNdWx0aXBsaWVycy5mb3JFYWNoKGZyZXFNdWx0ID0+IGZyZXFNdWx0LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZXR1bmUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXJGcmVxU2NhbGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5lbnZlbG9wZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2hpZ2hwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0YWxTeW50aC5qcy5tYXAiLCJpbXBvcnQgeyBfX2RlY29yYXRlIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTW9ub3Bob25pYyB9IGZyb20gXCIuL01vbm9waG9uaWNcIjtcbmltcG9ydCB7IFN5bnRoIH0gZnJvbSBcIi4vU3ludGhcIjtcbmltcG9ydCB7IHJhbmdlLCB0aW1lUmFuZ2UgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlY29yYXRvclwiO1xuLyoqXG4gKiBNZW1icmFuZVN5bnRoIG1ha2VzIGtpY2sgYW5kIHRvbSBzb3VuZHMgdXNpbmcgYSBzaW5nbGUgb3NjaWxsYXRvclxuICogd2l0aCBhbiBhbXBsaXR1ZGUgZW52ZWxvcGUgYW5kIGZyZXF1ZW5jeSByYW1wLiBBIFRvbmUuT21uaU9zY2lsbGF0b3JcbiAqIGlzIHJvdXRlZCB0aHJvdWdoIGEgVG9uZS5BbXBsaXR1ZGVFbnZlbG9wZSB0byB0aGUgb3V0cHV0LiBUaGUgZHJ1bVxuICogcXVhbGl0eSBvZiB0aGUgc291bmQgY29tZXMgZnJvbSB0aGUgZnJlcXVlbmN5IGVudmVsb3BlIGFwcGxpZWRcbiAqIGR1cmluZyBNZW1icmFuZVN5bnRoLnRyaWdnZXJBdHRhY2sobm90ZSkuIFRoZSBmcmVxdWVuY3kgZW52ZWxvcGVcbiAqIHN0YXJ0cyBhdCA8Y29kZT5ub3RlICogLm9jdGF2ZXM8L2NvZGU+IGFuZCByYW1wcyB0byA8Y29kZT5ub3RlPC9jb2RlPlxuICogb3ZlciB0aGUgZHVyYXRpb24gb2YgPGNvZGU+LnBpdGNoRGVjYXk8L2NvZGU+LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuTWVtYnJhbmVTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzJcIiwgXCI4blwiKTtcbiAqIEBjYXRlZ29yeSBJbnN0cnVtZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZW1icmFuZVN5bnRoIGV4dGVuZHMgU3ludGgge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNZW1icmFuZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1lbWJyYW5lU3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBvcnRhbWVudG8gaXMgaWdub3JlZCBpbiB0aGlzIHN5bnRoLiB1c2UgcGl0Y2ggZGVjYXkgaW5zdGVhZC5cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMucG9ydGFtZW50byA9IDA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZW1icmFuZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucGl0Y2hEZWNheSA9IG9wdGlvbnMucGl0Y2hEZWNheTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJvc2NpbGxhdG9yXCIsIFwiZW52ZWxvcGVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoTW9ub3Bob25pYy5nZXREZWZhdWx0cygpLCBTeW50aC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZToge1xuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMDEsXG4gICAgICAgICAgICAgICAgYXR0YWNrQ3VydmU6IFwiZXhwb25lbnRpYWxcIixcbiAgICAgICAgICAgICAgICBkZWNheTogMC40LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDEuNCxcbiAgICAgICAgICAgICAgICBzdXN0YWluOiAwLjAxLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9jdGF2ZXM6IDEwLFxuICAgICAgICAgICAgb3NjaWxsYXRvcjoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBpdGNoRGVjYXk6IDAuMDUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzZXROb3RlKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3Qgc2Vjb25kcyA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBjb25zdCBoZXJ0eiA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSBpbnN0YW5jZW9mIEZyZXF1ZW5jeUNsYXNzID8gbm90ZS50b0ZyZXF1ZW5jeSgpIDogbm90ZSk7XG4gICAgICAgIGNvbnN0IG1heE5vdGUgPSBoZXJ0eiAqIHRoaXMub2N0YXZlcztcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5zZXRWYWx1ZUF0VGltZShtYXhOb3RlLCBzZWNvbmRzKTtcbiAgICAgICAgdGhpcy5vc2NpbGxhdG9yLmZyZXF1ZW5jeS5leHBvbmVudGlhbFJhbXBUb1ZhbHVlQXRUaW1lKGhlcnR6LCBzZWNvbmRzICsgdGhpcy50b1NlY29uZHModGhpcy5waXRjaERlY2F5KSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbl9fZGVjb3JhdGUoW1xuICAgIHJhbmdlKDApXG5dLCBNZW1icmFuZVN5bnRoLnByb3RvdHlwZSwgXCJvY3RhdmVzXCIsIHZvaWQgMCk7XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIE1lbWJyYW5lU3ludGgucHJvdG90eXBlLCBcInBpdGNoRGVjYXlcIiwgdm9pZCAwKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1lbWJyYW5lU3ludGguanMubWFwIiwiaW1wb3J0IHsgQW1wbGl0dWRlRW52ZWxvcGUgfSBmcm9tIFwiLi4vY29tcG9uZW50L2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5pbXBvcnQgeyBvbWl0RnJvbU9iamVjdCwgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBFbnZlbG9wZSB9IGZyb20gXCIuLi9jb21wb25lbnQvZW52ZWxvcGUvRW52ZWxvcGVcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvU291cmNlXCI7XG4vKipcbiAqIFRvbmUuTm9pc2VTeW50aCBpcyBjb21wb3NlZCBvZiBbW05vaXNlXV0gdGhyb3VnaCBhbiBbW0FtcGxpdHVkZUVudmVsb3BlXV0uXG4gKiBgYGBcbiAqICstLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogfCBOb2lzZSArPi0tPiBBbXBsaXR1ZGVFbnZlbG9wZSArPi0tPiBPdXRwdXRcbiAqICstLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBub2lzZVN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiOG5cIiwgMC4wNSk7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgTm9pc2VTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhOb2lzZVN5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk5vaXNlU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE5vaXNlU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5ub2lzZSA9IG5ldyBOb2lzZShPYmplY3QuYXNzaWduKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSwgb3B0aW9ucy5ub2lzZSkpO1xuICAgICAgICB0aGlzLmVudmVsb3BlID0gbmV3IEFtcGxpdHVkZUVudmVsb3BlKE9iamVjdC5hc3NpZ24oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9LCBvcHRpb25zLmVudmVsb3BlKSk7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIG5vaXNlIHRvIHRoZSBvdXRwdXRcbiAgICAgICAgdGhpcy5ub2lzZS5jaGFpbih0aGlzLmVudmVsb3BlLCB0aGlzLm91dHB1dCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBlbnZlbG9wZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChFbnZlbG9wZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCkpKSwge1xuICAgICAgICAgICAgICAgIGRlY2F5OiAwLjEsXG4gICAgICAgICAgICAgICAgc3VzdGFpbjogMC4wLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBub2lzZTogT2JqZWN0LmFzc2lnbihvbWl0RnJvbU9iamVjdChOb2lzZS5nZXREZWZhdWx0cygpLCBPYmplY3Qua2V5cyhTb3VyY2UuZ2V0RGVmYXVsdHMoKSkpLCB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJ3aGl0ZVwiLFxuICAgICAgICAgICAgfSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIGVudmVsb3Blcy4gVW5saWtlIG90aGVyXG4gICAgICogaW5zdHJ1bWVudHMsIFRvbmUuTm9pc2VTeW50aCBkb2Vzbid0IGhhdmUgYSBub3RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm9pc2VTeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogbm9pc2VTeW50aC50cmlnZ2VyQXR0YWNrKCk7XG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICAvLyB0aGUgZW52ZWxvcGVzXG4gICAgICAgIHRoaXMuZW52ZWxvcGUudHJpZ2dlckF0dGFjayh0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIC8vIHN0YXJ0IHRoZSBub2lzZVxuICAgICAgICB0aGlzLm5vaXNlLnN0YXJ0KHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5lbnZlbG9wZS5zdXN0YWluID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLm5vaXNlLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuYXR0YWNrKSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUuZGVjYXkpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiB0aGUgZW52ZWxvcGVzLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLnRyaWdnZXJSZWxlYXNlKHRpbWUpO1xuICAgICAgICB0aGlzLm5vaXNlLnN0b3AodGltZSArIHRoaXMudG9TZWNvbmRzKHRoaXMuZW52ZWxvcGUucmVsZWFzZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgc3luYygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3N5bmNTdGF0ZSgpKSB7XG4gICAgICAgICAgICB0aGlzLl9zeW5jTWV0aG9kKFwidHJpZ2dlckF0dGFja1wiLCAwKTtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyUmVsZWFzZVwiLCAwKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2UoZHVyYXRpb24sIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGR1cmF0aW9uID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICB0aGlzLnRyaWdnZXJBdHRhY2sodGltZSwgdmVsb2NpdHkpO1xuICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKHRpbWUgKyBkdXJhdGlvbik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubm9pc2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmVudmVsb3BlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Tm9pc2VTeW50aC5qcy5tYXAiLCIvKipcbiAqIEFsbCBvZiB0aGUgY2xhc3NlcyBvciBmdW5jdGlvbnMgd2hpY2ggYXJlIGxvYWRlZCBpbnRvIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZVxuICovXG5jb25zdCB3b3JrbGV0Q29udGV4dCA9IG5ldyBTZXQoKTtcbi8qKlxuICogQWRkIGEgY2xhc3MgdG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRUb1dvcmtsZXQoY2xhc3NPckZ1bmN0aW9uKSB7XG4gICAgd29ya2xldENvbnRleHQuYWRkKGNsYXNzT3JGdW5jdGlvbik7XG59XG4vKipcbiAqIFJlZ2lzdGVyIGEgcHJvY2Vzc29yIGluIHRoZSBBdWRpb1dvcmtsZXRHbG9iYWxTY29wZSB3aXRoIHRoZSBnaXZlbiBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclByb2Nlc3NvcihuYW1lLCBjbGFzc0Rlc2MpIHtcbiAgICBjb25zdCBwcm9jZXNzb3IgPSAvKiBqYXZhc2NyaXB0ICovIGByZWdpc3RlclByb2Nlc3NvcihcIiR7bmFtZX1cIiwgJHtjbGFzc0Rlc2N9KWA7XG4gICAgd29ya2xldENvbnRleHQuYWRkKHByb2Nlc3Nvcik7XG59XG4vKipcbiAqIEdldCBhbGwgb2YgdGhlIG1vZHVsZXMgd2hpY2ggaGF2ZSBiZWVuIHJlZ2lzdGVyZWQgdG8gdGhlIEF1ZGlvV29ya2xldEdsb2JhbFNjb3BlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3JrbGV0R2xvYmFsU2NvcGUoKSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20od29ya2xldENvbnRleHQpLmpvaW4oXCJcXG5cIik7XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Xb3JrbGV0R2xvYmFsU2NvcGUuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGdldFdvcmtsZXRHbG9iYWxTY29wZSB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNsYXNzIFRvbmVBdWRpb1dvcmtsZXQgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVBdWRpb1dvcmtsZXRcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjb25zdHJ1Y3RvciBvcHRpb25zIGZvciB0aGUgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy53b3JrbGV0T3B0aW9ucyA9IHt9O1xuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hpY2ggaXMgaW52b2tlZCB3aGVuIHRoZXJlIGlzIGFuIGVycm9yIGluIHRoZSBwcm9jZXNzaW5nXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm9ucHJvY2Vzc29yZXJyb3IgPSBub09wO1xuICAgICAgICBjb25zdCBibG9iVXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChuZXcgQmxvYihbZ2V0V29ya2xldEdsb2JhbFNjb3BlKCldLCB7IHR5cGU6IFwidGV4dC9qYXZhc2NyaXB0XCIgfSkpO1xuICAgICAgICBjb25zdCBuYW1lID0gdGhpcy5fYXVkaW9Xb3JrbGV0TmFtZSgpO1xuICAgICAgICB0aGlzLl9kdW1teUdhaW4gPSB0aGlzLmNvbnRleHQuY3JlYXRlR2FpbigpO1xuICAgICAgICB0aGlzLl9kdW1teVBhcmFtID0gdGhpcy5fZHVtbXlHYWluLmdhaW47XG4gICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBwcm9jZXNzb3JcbiAgICAgICAgdGhpcy5jb250ZXh0LmFkZEF1ZGlvV29ya2xldE1vZHVsZShibG9iVXJsLCBuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSB0aGUgd29ya2xldCB3aGVuIGl0J3MgcmVhZFxuICAgICAgICAgICAgaWYgKCF0aGlzLmRpc3Bvc2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fd29ya2xldCA9IHRoaXMuY29udGV4dC5jcmVhdGVBdWRpb1dvcmtsZXROb2RlKG5hbWUsIHRoaXMud29ya2xldE9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQub25wcm9jZXNzb3JlcnJvciA9IHRoaXMub25wcm9jZXNzb3JlcnJvci5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMub25SZWFkeSh0aGlzLl93b3JrbGV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZHVtbXlHYWluLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgaWYgKHRoaXMuX3dvcmtsZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3dvcmtsZXQucG9ydC5wb3N0TWVzc2FnZShcImRpc3Bvc2VcIik7XG4gICAgICAgICAgICB0aGlzLl93b3JrbGV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Ub25lQXVkaW9Xb3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuY29uc3QgdG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHQvKipcblx0ICogVGhlIGJhc2UgQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGZvciB1c2UgaW4gVG9uZS5qcy4gV29ya3Mgd2l0aCB0aGUgW1tUb25lQXVkaW9Xb3JrbGV0XV0uIFxuXHQgKi9cblx0Y2xhc3MgVG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRcblx0XHRcdHN1cGVyKG9wdGlvbnMpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiBJZiB0aGUgcHJvY2Vzc29yIHdhcyBkaXNwb3NlZCBvciBub3QuIEtlZXAgYWxpdmUgdW50aWwgaXQncyBkaXNwb3NlZC5cblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5kaXNwb3NlZCA9IGZhbHNlO1xuXHRcdCAgIFx0LyoqIFxuXHRcdFx0ICogVGhlIG51bWJlciBvZiBzYW1wbGVzIGluIHRoZSBwcm9jZXNzaW5nIGJsb2NrXG5cdFx0XHQgKi9cblx0XHRcdHRoaXMuYmxvY2tTaXplID0gMTI4O1xuXHRcdFx0LyoqXG5cdFx0XHQgKiB0aGUgc2FtcGxlIHJhdGVcblx0XHRcdCAqL1xuXHRcdFx0dGhpcy5zYW1wbGVSYXRlID0gc2FtcGxlUmF0ZTtcblxuXHRcdFx0dGhpcy5wb3J0Lm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuXHRcdFx0XHQvLyB3aGVuIGl0IHJlY2VpdmVzIGEgZGlzcG9zZSBcblx0XHRcdFx0aWYgKGV2ZW50LmRhdGEgPT09IFwiZGlzcG9zZVwiKSB7XG5cdFx0XHRcdFx0dGhpcy5kaXNwb3NlZCA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHR9XG5gO1xuYWRkVG9Xb3JrbGV0KHRvbmVBdWRpb1dvcmtsZXRQcm9jZXNzb3IpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9VG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCBcIi4vVG9uZUF1ZGlvV29ya2xldFByb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgeyBhZGRUb1dvcmtsZXQgfSBmcm9tIFwiLi9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCBzaW5nbGVJT1Byb2Nlc3MgPSAvKiBqYXZhc2NyaXB0ICovIGBcblx0LyoqXG5cdCAqIEFic3RyYWN0IGNsYXNzIGZvciBhIHNpbmdsZSBpbnB1dC9vdXRwdXQgcHJvY2Vzc29yLiBcblx0ICogaGFzIGEgJ2dlbmVyYXRlJyBmdW5jdGlvbiB3aGljaCBwcm9jZXNzZXMgb25lIHNhbXBsZSBhdCBhIHRpbWVcblx0ICovXG5cdGNsYXNzIFNpbmdsZUlPUHJvY2Vzc29yIGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldFByb2Nlc3NvciB7XG5cblx0XHRjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG5cdFx0XHRzdXBlcihPYmplY3QuYXNzaWduKG9wdGlvbnMsIHtcblx0XHRcdFx0bnVtYmVyT2ZJbnB1dHM6IDEsXG5cdFx0XHRcdG51bWJlck9mT3V0cHV0czogMVxuXHRcdFx0fSkpO1xuXHRcdFx0LyoqXG5cdFx0XHQgKiBIb2xkcyB0aGUgbmFtZSBvZiB0aGUgcGFyYW1ldGVyIGFuZCBhIHNpbmdsZSB2YWx1ZSBvZiB0aGF0XG5cdFx0XHQgKiBwYXJhbWV0ZXIgYXQgdGhlIGN1cnJlbnQgc2FtcGxlXG5cdFx0XHQgKiBAdHlwZSB7IFtuYW1lOiBzdHJpbmddOiBudW1iZXIgfVxuXHRcdFx0ICovXG5cdFx0XHR0aGlzLnBhcmFtcyA9IHt9XG5cdFx0fVxuXG5cdFx0LyoqXG5cdFx0ICogR2VuZXJhdGUgYW4gb3V0cHV0IHNhbXBsZSBmcm9tIHRoZSBpbnB1dCBzYW1wbGUgYW5kIHBhcmFtZXRlcnNcblx0XHQgKiBAYWJzdHJhY3Rcblx0XHQgKiBAcGFyYW0gaW5wdXQgbnVtYmVyXG5cdFx0ICogQHBhcmFtIGNoYW5uZWwgbnVtYmVyXG5cdFx0ICogQHBhcmFtIHBhcmFtZXRlcnMgeyBbbmFtZTogc3RyaW5nXTogbnVtYmVyIH1cblx0XHQgKiBAcmV0dXJucyBudW1iZXJcblx0XHQgKi9cblx0XHRnZW5lcmF0ZSgpe31cblxuXHRcdC8qKlxuXHRcdCAqIFVwZGF0ZSB0aGUgcHJpdmF0ZSBwYXJhbXMgb2JqZWN0IHdpdGggdGhlIFxuXHRcdCAqIHZhbHVlcyBvZiB0aGUgcGFyYW1ldGVycyBhdCB0aGUgZ2l2ZW4gaW5kZXhcblx0XHQgKiBAcGFyYW0gcGFyYW1ldGVycyB7IFtuYW1lOiBzdHJpbmddOiBGbG9hdDMyQXJyYXkgfSxcblx0XHQgKiBAcGFyYW0gaW5kZXggbnVtYmVyXG5cdFx0ICovXG5cdFx0dXBkYXRlUGFyYW1zKHBhcmFtZXRlcnMsIGluZGV4KSB7XG5cdFx0XHRmb3IgKGNvbnN0IHBhcmFtTmFtZSBpbiBwYXJhbWV0ZXJzKSB7XG5cdFx0XHRcdGNvbnN0IHBhcmFtID0gcGFyYW1ldGVyc1twYXJhbU5hbWVdO1xuXHRcdFx0XHRpZiAocGFyYW0ubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdHRoaXMucGFyYW1zW3BhcmFtTmFtZV0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV1baW5kZXhdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMucGFyYW1zW3BhcmFtTmFtZV0gPSBwYXJhbWV0ZXJzW3BhcmFtTmFtZV1bMF07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBQcm9jZXNzIGEgc2luZ2xlIGZyYW1lIG9mIHRoZSBhdWRpb1xuXHRcdCAqIEBwYXJhbSBpbnB1dHMgRmxvYXQzMkFycmF5W11bXVxuXHRcdCAqIEBwYXJhbSBvdXRwdXRzIEZsb2F0MzJBcnJheVtdW11cblx0XHQgKi9cblx0XHRwcm9jZXNzKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykge1xuXHRcdFx0Y29uc3QgaW5wdXQgPSBpbnB1dHNbMF07XG5cdFx0XHRjb25zdCBvdXRwdXQgPSBvdXRwdXRzWzBdO1xuXHRcdFx0Ly8gZ2V0IHRoZSBwYXJhbWV0ZXIgdmFsdWVzXG5cdFx0XHRjb25zdCBjaGFubmVsQ291bnQgPSBNYXRoLm1heChpbnB1dCAmJiBpbnB1dC5sZW5ndGggfHwgMCwgb3V0cHV0Lmxlbmd0aCk7XG5cdFx0XHRmb3IgKGxldCBzYW1wbGUgPSAwOyBzYW1wbGUgPCB0aGlzLmJsb2NrU2l6ZTsgc2FtcGxlKyspIHtcblx0XHRcdFx0dGhpcy51cGRhdGVQYXJhbXMocGFyYW1ldGVycywgc2FtcGxlKTtcblx0XHRcdFx0Zm9yIChsZXQgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCBjaGFubmVsQ291bnQ7IGNoYW5uZWwrKykge1xuXHRcdFx0XHRcdGNvbnN0IGlucHV0U2FtcGxlID0gaW5wdXQgJiYgaW5wdXQubGVuZ3RoID8gaW5wdXRbY2hhbm5lbF1bc2FtcGxlXSA6IDA7XG5cdFx0XHRcdFx0b3V0cHV0W2NoYW5uZWxdW3NhbXBsZV0gPSB0aGlzLmdlbmVyYXRlKGlucHV0U2FtcGxlLCBjaGFubmVsLCB0aGlzLnBhcmFtcyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiAhdGhpcy5kaXNwb3NlZDtcblx0XHR9XG5cdH07XG5gO1xuYWRkVG9Xb3JrbGV0KHNpbmdsZUlPUHJvY2Vzcyk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0LmpzLm1hcCIsImltcG9ydCB7IGFkZFRvV29ya2xldCB9IGZyb20gXCIuL1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuY29uc3QgZGVsYXlMaW5lID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdC8qKlxuXHQgKiBBIG11bHRpY2hhbm5lbCBidWZmZXIgZm9yIHVzZSB3aXRoaW4gYW4gQXVkaW9Xb3JrbGV0UHJvY2Vzc29yIGFzIGEgZGVsYXkgbGluZVxuXHQgKi9cblx0Y2xhc3MgRGVsYXlMaW5lIHtcblx0XHRcblx0XHRjb25zdHJ1Y3RvcihzaXplLCBjaGFubmVscykge1xuXHRcdFx0dGhpcy5idWZmZXIgPSBbXTtcblx0XHRcdHRoaXMud3JpdGVIZWFkID0gW11cblx0XHRcdHRoaXMuc2l6ZSA9IHNpemU7XG5cblx0XHRcdC8vIGNyZWF0ZSB0aGUgZW1wdHkgY2hhbm5lbHNcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY2hhbm5lbHM7IGkrKykge1xuXHRcdFx0XHR0aGlzLmJ1ZmZlcltpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5zaXplKTtcblx0XHRcdFx0dGhpcy53cml0ZUhlYWRbaV0gPSAwO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8qKlxuXHRcdCAqIFB1c2ggYSB2YWx1ZSBvbnRvIHRoZSBlbmRcblx0XHQgKiBAcGFyYW0gY2hhbm5lbCBudW1iZXJcblx0XHQgKiBAcGFyYW0gdmFsdWUgbnVtYmVyXG5cdFx0ICovXG5cdFx0cHVzaChjaGFubmVsLCB2YWx1ZSkge1xuXHRcdFx0dGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gKz0gMTtcblx0XHRcdGlmICh0aGlzLndyaXRlSGVhZFtjaGFubmVsXSA+IHRoaXMuc2l6ZSkge1xuXHRcdFx0XHR0aGlzLndyaXRlSGVhZFtjaGFubmVsXSA9IDA7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmJ1ZmZlcltjaGFubmVsXVt0aGlzLndyaXRlSGVhZFtjaGFubmVsXV0gPSB2YWx1ZTtcblx0XHR9XG5cblx0XHQvKipcblx0XHQgKiBHZXQgdGhlIHJlY29yZGVkIHZhbHVlIG9mIHRoZSBjaGFubmVsIGdpdmVuIHRoZSBkZWxheVxuXHRcdCAqIEBwYXJhbSBjaGFubmVsIG51bWJlclxuXHRcdCAqIEBwYXJhbSBkZWxheSBudW1iZXIgZGVsYXkgc2FtcGxlc1xuXHRcdCAqL1xuXHRcdGdldChjaGFubmVsLCBkZWxheSkge1xuXHRcdFx0bGV0IHJlYWRIZWFkID0gdGhpcy53cml0ZUhlYWRbY2hhbm5lbF0gLSBNYXRoLmZsb29yKGRlbGF5KTtcblx0XHRcdGlmIChyZWFkSGVhZCA8IDApIHtcblx0XHRcdFx0cmVhZEhlYWQgKz0gdGhpcy5zaXplO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXMuYnVmZmVyW2NoYW5uZWxdW3JlYWRIZWFkXTtcblx0XHR9XG5cdH1cbmA7XG5hZGRUb1dvcmtsZXQoZGVsYXlMaW5lKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPURlbGF5TGluZS53b3JrbGV0LmpzLm1hcCIsImltcG9ydCBcIi4uLy4uL2NvcmUvd29ya2xldC9TaW5nbGVJT1Byb2Nlc3Nvci53b3JrbGV0XCI7XG5pbXBvcnQgXCIuLi8uLi9jb3JlL3dvcmtsZXQvRGVsYXlMaW5lLndvcmtsZXRcIjtcbmltcG9ydCB7IHJlZ2lzdGVyUHJvY2Vzc29yIH0gZnJvbSBcIi4uLy4uL2NvcmUvd29ya2xldC9Xb3JrbGV0R2xvYmFsU2NvcGVcIjtcbmV4cG9ydCBjb25zdCB3b3JrbGV0TmFtZSA9IFwiZmVlZGJhY2stY29tYi1maWx0ZXJcIjtcbmNvbnN0IGZlZWRiYWNrQ29tYkZpbHRlciA9IC8qIGphdmFzY3JpcHQgKi8gYFxuXHRjbGFzcyBGZWVkYmFja0NvbWJGaWx0ZXJXb3JrbGV0IGV4dGVuZHMgU2luZ2xlSU9Qcm9jZXNzb3Ige1xuXG5cdFx0Y29uc3RydWN0b3Iob3B0aW9ucykge1xuXHRcdFx0c3VwZXIob3B0aW9ucyk7XG5cdFx0XHR0aGlzLmRlbGF5TGluZSA9IG5ldyBEZWxheUxpbmUodGhpcy5zYW1wbGVSYXRlLCBvcHRpb25zLmNoYW5uZWxDb3VudCB8fCAyKTtcblx0XHR9XG5cblx0XHRzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkge1xuXHRcdFx0cmV0dXJuIFt7XG5cdFx0XHRcdG5hbWU6IFwiZGVsYXlUaW1lXCIsXG5cdFx0XHRcdGRlZmF1bHRWYWx1ZTogMC4xLFxuXHRcdFx0XHRtaW5WYWx1ZTogMCxcblx0XHRcdFx0bWF4VmFsdWU6IDEsXG5cdFx0XHRcdGF1dG9tYXRpb25SYXRlOiBcImstcmF0ZVwiXG5cdFx0XHR9LCB7XG5cdFx0XHRcdG5hbWU6IFwiZmVlZGJhY2tcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAwLjUsXG5cdFx0XHRcdG1pblZhbHVlOiAwLFxuXHRcdFx0XHRtYXhWYWx1ZTogMC45OTk5LFxuXHRcdFx0XHRhdXRvbWF0aW9uUmF0ZTogXCJrLXJhdGVcIlxuXHRcdFx0fV07XG5cdFx0fVxuXG5cdFx0Z2VuZXJhdGUoaW5wdXQsIGNoYW5uZWwsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IGRlbGF5ZWRTYW1wbGUgPSB0aGlzLmRlbGF5TGluZS5nZXQoY2hhbm5lbCwgcGFyYW1ldGVycy5kZWxheVRpbWUgKiB0aGlzLnNhbXBsZVJhdGUpO1xuXHRcdFx0dGhpcy5kZWxheUxpbmUucHVzaChjaGFubmVsLCBpbnB1dCArIGRlbGF5ZWRTYW1wbGUgKiBwYXJhbWV0ZXJzLmZlZWRiYWNrKTtcblx0XHRcdHJldHVybiBkZWxheWVkU2FtcGxlO1xuXHRcdH1cblx0fVxuYDtcbnJlZ2lzdGVyUHJvY2Vzc29yKHdvcmtsZXROYW1lLCBmZWVkYmFja0NvbWJGaWx0ZXIpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXQuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyBjb25uZWN0U2VyaWVzLCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb1dvcmtsZXQgfSBmcm9tIFwiLi4vLi4vY29yZS93b3JrbGV0L1RvbmVBdWRpb1dvcmtsZXRcIjtcbmltcG9ydCB7IHdvcmtsZXROYW1lIH0gZnJvbSBcIi4vRmVlZGJhY2tDb21iRmlsdGVyLndvcmtsZXRcIjtcbi8qKlxuICogQ29tYiBmaWx0ZXJzIGFyZSBiYXNpYyBidWlsZGluZyBibG9ja3MgZm9yIHBoeXNpY2FsIG1vZGVsaW5nLiBSZWFkIG1vcmVcbiAqIGFib3V0IGNvbWIgZmlsdGVycyBvbiBbQ0NSTUEncyB3ZWJzaXRlXShodHRwczovL2Njcm1hLnN0YW5mb3JkLmVkdS9+am9zL3Bhc3AvRmVlZGJhY2tfQ29tYl9GaWx0ZXJzLmh0bWwpLlxuICpcbiAqIFRoaXMgY29tYiBmaWx0ZXIgaXMgaW1wbGVtZW50ZWQgd2l0aCB0aGUgQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBhbGxvd3MgaXQgdG8gaGF2ZSBmZWVkYmFjayBkZWxheXMgbGVzcyB0aGFuIHRoZVxuICogV2ViIEF1ZGlvIHByb2Nlc3NpbmcgYmxvY2sgb2YgMTI4IHNhbXBsZXMuIFRoZXJlIGlzIGEgcG9seWZpbGwgZm9yIGJyb3dzZXJzIHRoYXQgZG9uJ3QgeWV0IHN1cHBvcnQgdGhlXG4gKiBBdWRpb1dvcmtsZXROb2RlLCBidXQgaXQgd2lsbCBhZGQgc29tZSBsYXRlbmN5IGFuZCBoYXZlIHNsb3dlciBwZXJmb3JtYW5jZSB0aGFuIHRoZSBBdWRpb1dvcmtsZXROb2RlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRmVlZGJhY2tDb21iRmlsdGVyIGV4dGVuZHMgVG9uZUF1ZGlvV29ya2xldCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEZlZWRiYWNrQ29tYkZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcInJlc29uYW5jZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZlZWRiYWNrQ29tYkZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRmVlZGJhY2tDb21iRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwicmVzb25hbmNlXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICBtaW5WYWx1ZTogMCxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlc29uYW5jZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yZXNvbmFuY2UsXG4gICAgICAgICAgICB1bml0czogXCJub3JtYWxSYW5nZVwiLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2R1bW15UGFyYW0sXG4gICAgICAgICAgICBzd2FwcGFibGU6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyZXNvbmFuY2VcIiwgXCJkZWxheVRpbWVcIl0pO1xuICAgIH1cbiAgICBfYXVkaW9Xb3JrbGV0TmFtZSgpIHtcbiAgICAgICAgcmV0dXJuIHdvcmtsZXROYW1lO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZGVmYXVsdCBwYXJhbWV0ZXJzXG4gICAgICovXG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogMC4xLFxuICAgICAgICAgICAgcmVzb25hbmNlOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBvblJlYWR5KG5vZGUpIHtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCBub2RlLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGNvbnN0IGRlbGF5VGltZSA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJkZWxheVRpbWVcIik7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuc2V0UGFyYW0oZGVsYXlUaW1lKTtcbiAgICAgICAgY29uc3QgZmVlZGJhY2sgPSBub2RlLnBhcmFtZXRlcnMuZ2V0KFwiZmVlZGJhY2tcIik7XG4gICAgICAgIDtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2Uuc2V0UGFyYW0oZmVlZGJhY2spO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0NvbWJGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIEEgb25lIHBvbGUgZmlsdGVyIHdpdGggNmRiLXBlci1vY3RhdmUgcm9sbG9mZi4gRWl0aGVyIFwiaGlnaHBhc3NcIiBvciBcImxvd3Bhc3NcIi5cbiAqIE5vdGUgdGhhdCBjaGFuZ2luZyB0aGUgdHlwZSBvciBmcmVxdWVuY3kgbWF5IHJlc3VsdCBpbiBhIGRpc2NvbnRpbnVpdHkgd2hpY2hcbiAqIGNhbiBzb3VuZCBsaWtlIGEgY2xpY2sgb3IgcG9wLlxuICogUmVmZXJlbmNlczpcbiAqICogaHR0cDovL3d3dy5lYXJsZXZlbC5jb20vbWFpbi8yMDEyLzEyLzE1L2Etb25lLXBvbGUtZmlsdGVyL1xuICogKiBodHRwOi8vd3d3LmRzcGd1aWRlLmNvbS9jaDE5LzIuaHRtXG4gKiAqIGh0dHBzOi8vZ2l0aHViLmNvbS92aXRhbGl5LWJvYnJvdi9qcy1yb2Nrcy9ibG9iL21hc3Rlci9zcmMvYXBwL2F1ZGlvL2VmZmVjdHMvb25lLXBvbGUtZmlsdGVycy50c1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgT25lUG9sZUZpbHRlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhPbmVQb2xlRmlsdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwidHlwZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk9uZVBvbGVGaWx0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE9uZVBvbGVGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJ0eXBlXCJdKTtcbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5ID0gb3B0aW9ucy5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX3R5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDg4MCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBmaWx0ZXIgYW5kIGRpc3Bvc2UgdGhlIG9sZCBvbmVcbiAgICAgKi9cbiAgICBfY3JlYXRlRmlsdGVyKCkge1xuICAgICAgICBjb25zdCBvbGRGaWx0ZXIgPSB0aGlzLl9maWx0ZXI7XG4gICAgICAgIGNvbnN0IGZyZXEgPSB0aGlzLnRvRnJlcXVlbmN5KHRoaXMuX2ZyZXF1ZW5jeSk7XG4gICAgICAgIGNvbnN0IHQgPSAxIC8gKDIgKiBNYXRoLlBJICogZnJlcSk7XG4gICAgICAgIGlmICh0aGlzLl90eXBlID09PSBcImxvd3Bhc3NcIikge1xuICAgICAgICAgICAgY29uc3QgYTAgPSAxIC8gKHQgKiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSk7XG4gICAgICAgICAgICBjb25zdCBiMSA9IGEwIC0gMTtcbiAgICAgICAgICAgIHRoaXMuX2ZpbHRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoW2EwLCAwXSwgWzEsIGIxXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBiMSA9IDEgLyAodCAqIHRoaXMuY29udGV4dC5zYW1wbGVSYXRlKSAtIDE7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlSUlSRmlsdGVyKFsxLCAtMV0sIFsxLCBiMV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaW5wdXQuY2hhaW4odGhpcy5fZmlsdGVyLCB0aGlzLm91dHB1dCk7XG4gICAgICAgIGlmIChvbGRGaWx0ZXIpIHtcbiAgICAgICAgICAgIC8vIGRpc3Bvc2UgaXQgb24gdGhlIG5leHQgYmxvY2tcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZGlzcG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5kaXNjb25uZWN0KG9sZEZpbHRlcik7XG4gICAgICAgICAgICAgICAgICAgIG9sZEZpbHRlci5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSwgdGhpcy5ibG9ja1RpbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBmcmVxdWVuY3kgdmFsdWUuXG4gICAgICovXG4gICAgZ2V0IGZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGZyZXF1ZW5jeShmcSkge1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBmcTtcbiAgICAgICAgdGhpcy5fY3JlYXRlRmlsdGVyKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBPbmVQb2xlIEZpbHRlciB0eXBlLCBlaXRoZXIgXCJoaWdocGFzc1wiIG9yIFwibG93cGFzc1wiXG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl90eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0KSB7XG4gICAgICAgIHRoaXMuX3R5cGUgPSB0O1xuICAgICAgICB0aGlzLl9jcmVhdGVGaWx0ZXIoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBmcmVxdWVuY3kgcmVzcG9uc2UgY3VydmUuIFRoaXMgY3VydmUgcmVwcmVzZW50cyBob3cgdGhlIGZpbHRlclxuICAgICAqIHJlc3BvbnNlcyB0byBmcmVxdWVuY2llcyBiZXR3ZWVuIDIwaHotMjBraHouXG4gICAgICogQHBhcmFtICBsZW4gVGhlIG51bWJlciBvZiB2YWx1ZXMgdG8gcmV0dXJuXG4gICAgICogQHJldHVybiBUaGUgZnJlcXVlbmN5IHJlc3BvbnNlIGN1cnZlIGJldHdlZW4gMjAtMjBrSHpcbiAgICAgKi9cbiAgICBnZXRGcmVxdWVuY3lSZXNwb25zZShsZW4gPSAxMjgpIHtcbiAgICAgICAgY29uc3QgZnJlcVZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgbm9ybSA9IE1hdGgucG93KGkgLyBsZW4sIDIpO1xuICAgICAgICAgICAgY29uc3QgZnJlcSA9IG5vcm0gKiAoMjAwMDAgLSAyMCkgKyAyMDtcbiAgICAgICAgICAgIGZyZXFWYWx1ZXNbaV0gPSBmcmVxO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1hZ1ZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobGVuKTtcbiAgICAgICAgY29uc3QgcGhhc2VWYWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KGxlbik7XG4gICAgICAgIHRoaXMuX2ZpbHRlci5nZXRGcmVxdWVuY3lSZXNwb25zZShmcmVxVmFsdWVzLCBtYWdWYWx1ZXMsIHBoYXNlVmFsdWVzKTtcbiAgICAgICAgcmV0dXJuIG1hZ1ZhbHVlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9maWx0ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1PbmVQb2xlRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRmVlZGJhY2tDb21iRmlsdGVyIH0gZnJvbSBcIi4vRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5pbXBvcnQgeyBPbmVQb2xlRmlsdGVyIH0gZnJvbSBcIi4vT25lUG9sZUZpbHRlclwiO1xuLyoqXG4gKiBBIGxvd3Bhc3MgZmVlZGJhY2sgY29tYiBmaWx0ZXIuIEl0IGlzIHNpbWlsYXIgdG9cbiAqIFtbRmVlZGJhY2tDb21iRmlsdGVyXV0sIGJ1dCBpbmNsdWRlcyBhIGxvd3Bhc3MgZmlsdGVyLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTG93cGFzc0NvbWJGaWx0ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTG93cGFzc0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIiwgXCJkYW1wZW5pbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMb3dwYXNzQ29tYkZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTG93cGFzc0NvbWJGaWx0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWxheVRpbWVcIiwgXCJyZXNvbmFuY2VcIiwgXCJkYW1wZW5pbmdcIl0pO1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVyID0gdGhpcy5vdXRwdXQgPSBuZXcgRmVlZGJhY2tDb21iRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICByZXNvbmFuY2U6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9jb21iRmlsdGVyLmRlbGF5VGltZTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSB0aGlzLl9jb21iRmlsdGVyLnJlc29uYW5jZTtcbiAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMuaW5wdXQgPSBuZXcgT25lUG9sZUZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZGFtcGVuaW5nLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmNvbm5lY3QodGhpcy5fY29tYkZpbHRlcik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkYW1wZW5pbmc6IDMwMDAsXG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMSxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRhbXBlbmluZyBjb250cm9sIG9mIHRoZSBmZWVkYmFja1xuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhmcSkge1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmZyZXF1ZW5jeSA9IGZxO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TG93cGFzc0NvbWJGaWx0ZXIuanMubWFwIiwiaW1wb3J0IHsgTG93cGFzc0NvbWJGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9Mb3dwYXNzQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgZGVlcE1lcmdlIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBOb2lzZSB9IGZyb20gXCIuLi9zb3VyY2UvTm9pc2VcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG4vKipcbiAqIEthcnBsdXMtU3RyaW5nIHN0cmluZyBzeW50aGVzaXMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGx1Y2t5ID0gbmV3IFRvbmUuUGx1Y2tTeW50aCgpLnRvRGVzdGluYXRpb24oKTtcbiAqIHBsdWNreS50cmlnZ2VyQXR0YWNrKFwiQzRcIiwgXCIrMC41XCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDM1wiLCBcIisxXCIpO1xuICogcGx1Y2t5LnRyaWdnZXJBdHRhY2soXCJDMlwiLCBcIisxLjVcIik7XG4gKiBwbHVja3kudHJpZ2dlckF0dGFjayhcIkMxXCIsIFwiKzJcIik7XG4gKiBAY2F0ZWdvcnkgSW5zdHJ1bWVudFxuICovXG5leHBvcnQgY2xhc3MgUGx1Y2tTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQbHVja1N5bnRoLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlBsdWNrU3ludGhcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBsdWNrU3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5fbm9pc2UgPSBuZXcgTm9pc2Uoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogXCJwaW5rXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuYXR0YWNrTm9pc2UgPSBvcHRpb25zLmF0dGFja05vaXNlO1xuICAgICAgICB0aGlzLl9sZmNmID0gbmV3IExvd3Bhc3NDb21iRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGRhbXBlbmluZzogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICByZXNvbmFuY2U6IG9wdGlvbnMucmVzb25hbmNlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yZXNvbmFuY2UgPSBvcHRpb25zLnJlc29uYW5jZTtcbiAgICAgICAgdGhpcy5yZWxlYXNlID0gb3B0aW9ucy5yZWxlYXNlO1xuICAgICAgICB0aGlzLl9ub2lzZS5jb25uZWN0KHRoaXMuX2xmY2YpO1xuICAgICAgICB0aGlzLl9sZmNmLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBkZWVwTWVyZ2UoSW5zdHJ1bWVudC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2tOb2lzZTogMSxcbiAgICAgICAgICAgIGRhbXBlbmluZzogNDAwMCxcbiAgICAgICAgICAgIHJlc29uYW5jZTogMC43LFxuICAgICAgICAgICAgcmVsZWFzZTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkYW1wZW5pbmcgY29udHJvbC4gaS5lLiB0aGUgbG93cGFzcyBmaWx0ZXIgZnJlcXVlbmN5IG9mIHRoZSBjb21iIGZpbHRlclxuICAgICAqIEBtaW4gMFxuICAgICAqIEBtYXggNzAwMFxuICAgICAqL1xuICAgIGdldCBkYW1wZW5pbmcoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZmNmLmRhbXBlbmluZztcbiAgICB9XG4gICAgc2V0IGRhbXBlbmluZyhmcSkge1xuICAgICAgICB0aGlzLl9sZmNmLmRhbXBlbmluZyA9IGZxO1xuICAgIH1cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUpIHtcbiAgICAgICAgY29uc3QgZnJlcSA9IHRoaXMudG9GcmVxdWVuY3kobm90ZSk7XG4gICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgY29uc3QgZGVsYXlBbW91bnQgPSAxIC8gZnJlcTtcbiAgICAgICAgdGhpcy5fbGZjZi5kZWxheVRpbWUuc2V0VmFsdWVBdFRpbWUoZGVsYXlBbW91bnQsIHRpbWUpO1xuICAgICAgICB0aGlzLl9ub2lzZS5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbm9pc2Uuc3RvcCh0aW1lICsgZGVsYXlBbW91bnQgKiB0aGlzLmF0dGFja05vaXNlKTtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2UuY2FuY2VsU2NoZWR1bGVkVmFsdWVzKHRpbWUpO1xuICAgICAgICB0aGlzLl9sZmNmLnJlc29uYW5jZS5zZXRWYWx1ZUF0VGltZSh0aGlzLnJlc29uYW5jZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSYW1wIGRvd24gdGhlIFtbcmVzb25hbmNlXV0gdG8gMCBvdmVyIHRoZSBkdXJhdGlvbiBvZiB0aGUgcmVsZWFzZSB0aW1lLlxuICAgICAqL1xuICAgIHRyaWdnZXJSZWxlYXNlKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZjZi5yZXNvbmFuY2UubGluZWFyUmFtcFRvKDAsIHRoaXMucmVsZWFzZSwgdGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX25vaXNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZjZi5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBsdWNrU3ludGguanMubWFwIiwiaW1wb3J0IHsgTWlkaUNsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9NaWRpXCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UsIG9taXRGcm9tT2JqZWN0LCBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IGlzQXJyYXksIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IEluc3RydW1lbnQgfSBmcm9tIFwiLi9JbnN0cnVtZW50XCI7XG5pbXBvcnQgeyBTeW50aCB9IGZyb20gXCIuL1N5bnRoXCI7XG5pbXBvcnQgeyBhc3NlcnQsIHdhcm4gfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBvbHlTeW50aCBoYW5kbGVzIHZvaWNlIGNyZWF0aW9uIGFuZCBhbGxvY2F0aW9uIGZvciBhbnlcbiAqIGluc3RydW1lbnRzIHBhc3NlZCBpbiBhcyB0aGUgc2Vjb25kIHBhcmFtdGVyLiBQb2x5U3ludGggaXNcbiAqIG5vdCBhIHN5bnRoZXNpemVyIGJ5IGl0c2VsZiwgaXQgbWVyZWx5IG1hbmFnZXMgdm9pY2VzIG9mXG4gKiBvbmUgb2YgdGhlIG90aGVyIHR5cGVzIG9mIHN5bnRocywgYWxsb3dpbmcgYW55IG9mIHRoZVxuICogbW9ub3Bob25pYyBzeW50aGVzaXplcnMgdG8gYmUgcG9seXBob25pYy5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBzZXQgdGhlIGF0dHJpYnV0ZXMgYWNyb3NzIGFsbCB0aGUgdm9pY2VzIHVzaW5nICdzZXQnXG4gKiBzeW50aC5zZXQoeyBkZXR1bmU6IC0xMjAwIH0pO1xuICogLy8gcGxheSBhIGNob3JkXG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDNFwiLCBcIkU0XCIsIFwiQTRcIl0sIDEpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBvbHlTeW50aCBleHRlbmRzIEluc3RydW1lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQb2x5U3ludGguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ2b2ljZVwiLCBcIm9wdGlvbnNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQb2x5U3ludGhcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB2b2ljZXMgd2hpY2ggYXJlIG5vdCBjdXJyZW50bHkgaW4gdXNlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIHZvaWNlc1xuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGwgb2YgdGhlIGFsbG9jYXRlZCB2b2ljZXMgZm9yIHRoaXMgc3ludGguXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl92b2ljZXMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBHQyB0aW1lb3V0LiBIZWxkIHNvIHRoYXQgaXQgY291bGQgYmUgY2FuY2VsbGVkIHdoZW4gdGhlIG5vZGUgaXMgZGlzcG9zZWQuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nY1RpbWVvdXQgPSAtMTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgbW92aW5nIGF2ZXJhZ2Ugb2YgdGhlIG51bWJlciBvZiBhY3RpdmUgdm9pY2VzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzID0gMDtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBvbHlTeW50aC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvaWNlXCIsIFwib3B0aW9uc1wiXSk7XG4gICAgICAgIC8vIGNoZWNrIGFnYWluc3QgdGhlIG9sZCBBUEkgKHByZSAxNC4zLjApXG4gICAgICAgIGFzc2VydCghaXNOdW1iZXIob3B0aW9ucy52b2ljZSksIFwiREVQUkVDQVRFRDogVGhlIHBvbHlwaG9ueSBjb3VudCBpcyBubyBsb25nZXIgdGhlIGZpcnN0IGFyZ3VtZW50LlwiKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSBvcHRpb25zLnZvaWNlLmdldERlZmF1bHRzKCk7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdHMsIG9wdGlvbnMub3B0aW9ucyk7XG4gICAgICAgIHRoaXMudm9pY2UgPSBvcHRpb25zLnZvaWNlO1xuICAgICAgICB0aGlzLm1heFBvbHlwaG9ueSA9IG9wdGlvbnMubWF4UG9seXBob255O1xuICAgICAgICAvLyBjcmVhdGUgdGhlIGZpcnN0IHZvaWNlXG4gICAgICAgIHRoaXMuX2R1bW15Vm9pY2UgPSB0aGlzLl9nZXROZXh0QXZhaWxhYmxlVm9pY2UoKTtcbiAgICAgICAgLy8gcmVtb3ZlIGl0IGZyb20gdGhlIHZvaWNlcyBsaXN0XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdm9pY2VzLmluZGV4T2YodGhpcy5fZHVtbXlWb2ljZSk7XG4gICAgICAgIHRoaXMuX3ZvaWNlcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAvLyBraWNrIG9mZiB0aGUgR0MgaW50ZXJ2YWxcbiAgICAgICAgdGhpcy5fZ2NUaW1lb3V0ID0gdGhpcy5jb250ZXh0LnNldEludGVydmFsKHRoaXMuX2NvbGxlY3RHYXJiYWdlLmJpbmQodGhpcyksIDEpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbWF4UG9seXBob255OiAzMixcbiAgICAgICAgICAgIG9wdGlvbnM6IHt9LFxuICAgICAgICAgICAgdm9pY2U6IFN5bnRoLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBhY3RpdmUgdm9pY2VzLlxuICAgICAqL1xuICAgIGdldCBhY3RpdmVWb2ljZXMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hY3RpdmVWb2ljZXMubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2VkIHdoZW4gdGhlIHNvdXJjZSBpcyBkb25lIG1ha2luZyBzb3VuZCwgc28gdGhhdCBpdCBjYW4gYmVcbiAgICAgKiByZWFkZGVkIHRvIHRoZSBwb29sIG9mIGF2YWlsYWJsZSB2b2ljZXNcbiAgICAgKi9cbiAgICBfbWFrZVZvaWNlQXZhaWxhYmxlKHZvaWNlKSB7XG4gICAgICAgIHRoaXMuX2F2YWlsYWJsZVZvaWNlcy5wdXNoKHZvaWNlKTtcbiAgICAgICAgLy8gcmVtb3ZlIHRoZSBtaWRpIG5vdGUgZnJvbSAnYWN0aXZlIHZvaWNlcydcbiAgICAgICAgY29uc3QgYWN0aXZlVm9pY2VJbmRleCA9IHRoaXMuX2FjdGl2ZVZvaWNlcy5maW5kSW5kZXgoKGUpID0+IGUudm9pY2UgPT09IHZvaWNlKTtcbiAgICAgICAgdGhpcy5fYWN0aXZlVm9pY2VzLnNwbGljZShhY3RpdmVWb2ljZUluZGV4LCAxKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IGFuIGF2YWlsYWJsZSB2b2ljZSBmcm9tIHRoZSBwb29sIG9mIGF2YWlsYWJsZSB2b2ljZXMuXG4gICAgICogSWYgb25lIGlzIG5vdCBhdmFpbGFibGUgYW5kIHRoZSBtYXhQb2x5cGhvbnkgbGltaXQgaXMgcmVhY2hlZCxcbiAgICAgKiBzdGVhbCBhIHZvaWNlLCBvdGhlcndpc2UgcmV0dXJuIG51bGwuXG4gICAgICovXG4gICAgX2dldE5leHRBdmFpbGFibGVWb2ljZSgpIHtcbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIGF2YWlsYWJsZSB2b2ljZXMsIHJldHVybiB0aGUgZmlyc3Qgb25lXG4gICAgICAgIGlmICh0aGlzLl9hdmFpbGFibGVWb2ljZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fYXZhaWxhYmxlVm9pY2VzLnNoaWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fdm9pY2VzLmxlbmd0aCA8IHRoaXMubWF4UG9seXBob255KSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgdGhlcmUgaXMgc3RpbGwgbW9yZSBtYXhQb2x5cGhvbnksIG1ha2UgYSBuZXcgdm9pY2VcbiAgICAgICAgICAgIGNvbnN0IHZvaWNlID0gbmV3IHRoaXMudm9pY2UoT2JqZWN0LmFzc2lnbih0aGlzLm9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgb25zaWxlbmNlOiB0aGlzLl9tYWtlVm9pY2VBdmFpbGFibGUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHZvaWNlLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgICAgICAgICAgdGhpcy5fdm9pY2VzLnB1c2godm9pY2UpO1xuICAgICAgICAgICAgcmV0dXJuIHZvaWNlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgd2FybihcIk1heCBwb2x5cGhvbnkgZXhjZWVkZWQuIE5vdGUgZHJvcHBlZC5cIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogT2NjYXNpb25hbGx5IGNoZWNrIGlmIHRoZXJlIGFyZSBhbnkgYWxsb2NhdGVkIHZvaWNlcyB3aGljaCBjYW4gYmUgY2xlYW5lZCB1cC5cbiAgICAgKi9cbiAgICBfY29sbGVjdEdhcmJhZ2UoKSB7XG4gICAgICAgIHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgPSBNYXRoLm1heCh0aGlzLl9hdmVyYWdlQWN0aXZlVm9pY2VzICogMC45NSwgdGhpcy5hY3RpdmVWb2ljZXMpO1xuICAgICAgICBpZiAodGhpcy5fYXZhaWxhYmxlVm9pY2VzLmxlbmd0aCAmJiB0aGlzLl92b2ljZXMubGVuZ3RoID4gTWF0aC5jZWlsKHRoaXMuX2F2ZXJhZ2VBY3RpdmVWb2ljZXMgKyAxKSkge1xuICAgICAgICAgICAgLy8gdGFrZSBvZmYgYW4gYXZhaWxhYmxlIG5vdGVcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0QXZhaWwgPSB0aGlzLl9hdmFpbGFibGVWb2ljZXMuc2hpZnQoKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fdm9pY2VzLmluZGV4T2YoZmlyc3RBdmFpbCk7XG4gICAgICAgICAgICB0aGlzLl92b2ljZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZXh0LmlzT2ZmbGluZSkge1xuICAgICAgICAgICAgICAgIGZpcnN0QXZhaWwuZGlzcG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB3aGljaCB0cmlnZ2VycyB0aGUgYXR0YWNrXG4gICAgICovXG4gICAgX3RyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpTm90ZSA9IG5ldyBNaWRpQ2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIGNvbnN0IHZvaWNlID0gdGhpcy5fZ2V0TmV4dEF2YWlsYWJsZVZvaWNlKCk7XG4gICAgICAgICAgICBpZiAodm9pY2UpIHtcbiAgICAgICAgICAgICAgICB2b2ljZS50cmlnZ2VyQXR0YWNrKG5vdGUsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLl9hY3RpdmVWb2ljZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIG1pZGk6IG1pZGlOb3RlLCB2b2ljZSwgcmVsZWFzZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMubG9nKFwidHJpZ2dlckF0dGFja1wiLCBub3RlLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIG1ldGhvZCB3aGljaCB0cmlnZ2VycyB0aGUgcmVsZWFzZVxuICAgICAqL1xuICAgIF90cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICBub3Rlcy5mb3JFYWNoKG5vdGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgbWlkaU5vdGUgPSBuZXcgTWlkaUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHRoaXMuX2FjdGl2ZVZvaWNlcy5maW5kKCh7IG1pZGksIHJlbGVhc2VkIH0pID0+IG1pZGkgPT09IG1pZGlOb3RlICYmICFyZWxlYXNlZCk7XG4gICAgICAgICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICAvLyB0cmlnZ2VyIHJlbGVhc2Ugb24gdGhhdCBub3RlXG4gICAgICAgICAgICAgICAgZXZlbnQudm9pY2UudHJpZ2dlclJlbGVhc2UodGltZSk7XG4gICAgICAgICAgICAgICAgLy8gbWFyayBpdCBhcyByZWxlYXNlZFxuICAgICAgICAgICAgICAgIGV2ZW50LnJlbGVhc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIG5vdGUsIHRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2NoZWR1bGUgdGhlIGF0dGFjay9yZWxlYXNlIGV2ZW50cy4gSWYgdGhlIHRpbWUgaXMgaW4gdGhlIGZ1dHVyZSwgdGhlbiBpdCBzaG91bGQgc2V0IGEgdGltZW91dFxuICAgICAqIHRvIHdhaXQgZm9yIGp1c3QtaW4tdGltZSBzY2hlZHVsaW5nXG4gICAgICovXG4gICAgX3NjaGVkdWxlRXZlbnQodHlwZSwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KSB7XG4gICAgICAgIGFzc2VydCghdGhpcy5kaXNwb3NlZCwgXCJTeW50aCB3YXMgYWxyZWFkeSBkaXNwb3NlZFwiKTtcbiAgICAgICAgLy8gaWYgdGhlIG5vdGVzIGFyZSBncmVhdGVyIHRoYW4gdGhpcyBhbW91bnQgb2YgdGltZSBpbiB0aGUgZnV0dXJlLCB0aGV5IHNob3VsZCBiZSBzY2hlZHVsZWQgd2l0aCBzZXRUaW1lb3V0XG4gICAgICAgIGlmICh0aW1lIDw9IHRoaXMubm93KCkpIHtcbiAgICAgICAgICAgIC8vIGRvIGl0IGltbWVkaWF0ZWx5XG4gICAgICAgICAgICBpZiAodHlwZSA9PT0gXCJhdHRhY2tcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX3RyaWdnZXJSZWxlYXNlKG5vdGVzLCB0aW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNjaGVkdWxlIGl0IHRvIHN0YXJ0IGluIHRoZSBmdXR1cmVcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KHR5cGUsIG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICB9LCB0aW1lIC0gdGhpcy5ub3coKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgYXR0YWNrIHBvcnRpb24gb2YgdGhlIG5vdGVcbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSBzdGFydCB0aW1lIG9mIHRoZSBub3RlLlxuICAgICAqIEBwYXJhbSB2ZWxvY2l0eSBUaGUgdmVsb2NpdHkgb2YgdGhlIG5vdGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aChUb25lLkZNU3ludGgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiAvLyB0cmlnZ2VyIGEgY2hvcmQgaW1tZWRpYXRlbHkgd2l0aCBhIHZlbG9jaXR5IG9mIDAuMlxuICAgICAqIHN5bnRoLnRyaWdnZXJBdHRhY2soW1wiQWIzXCIsIFwiQzRcIiwgXCJGNVwiXSwgVG9uZS5ub3coKSwgMC4yKTtcbiAgICAgKi9cbiAgICB0cmlnZ2VyQXR0YWNrKG5vdGVzLCB0aW1lLCB2ZWxvY2l0eSkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobm90ZXMpKSB7XG4gICAgICAgICAgICBub3RlcyA9IFtub3Rlc107XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX3NjaGVkdWxlRXZlbnQoXCJhdHRhY2tcIiwgbm90ZXMsIGNvbXB1dGVkVGltZSwgdmVsb2NpdHkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVHJpZ2dlciB0aGUgcmVsZWFzZSBvZiB0aGUgbm90ZS4gVW5saWtlIG1vbm9waG9uaWMgaW5zdHJ1bWVudHMsXG4gICAgICogYSBub3RlIChvciBhcnJheSBvZiBub3RlcykgbmVlZHMgdG8gYmUgcGFzc2VkIGluIGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAgICAgKiBAcGFyYW0gIG5vdGVzIFRoZSBub3RlcyB0byBwbGF5LiBBY2NlcHRzIGEgc2luZ2xlIEZyZXF1ZW5jeSBvciBhbiBhcnJheSBvZiBmcmVxdWVuY2llcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdGhlIHJlbGVhc2Ugd2lsbCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoVG9uZS5BTVN5bnRoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrKFtcIkFiM1wiLCBcIkM0XCIsIFwiRjVcIl0pO1xuICAgICAqIC8vIHRyaWdnZXIgdGhlIHJlbGVhc2Ugb2YgdGhlIGdpdmVuIG5vdGVzLlxuICAgICAqIHBvbHkudHJpZ2dlclJlbGVhc2UoW1wiQWIzXCIsIFwiQzRcIl0sIFwiKzFcIik7XG4gICAgICogcG9seS50cmlnZ2VyUmVsZWFzZShcIkY1XCIsIFwiKzNcIik7XG4gICAgICovXG4gICAgdHJpZ2dlclJlbGVhc2Uobm90ZXMsIHRpbWUpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9zY2hlZHVsZUV2ZW50KFwicmVsZWFzZVwiLCBub3RlcywgY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIGF0dGFjayBhbmQgcmVsZWFzZSBhZnRlciB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uXG4gICAgICogQHBhcmFtICBub3RlcyBUaGUgbm90ZXMgdG8gcGxheS4gQWNjZXB0cyBhIHNpbmdsZSAgRnJlcXVlbmN5IG9yIGFuIGFycmF5IG9mIGZyZXF1ZW5jaWVzLlxuICAgICAqIEBwYXJhbSAgZHVyYXRpb24gdGhlIGR1cmF0aW9uIG9mIHRoZSBub3RlXG4gICAgICogQHBhcmFtICB0aW1lICBpZiBubyB0aW1lIGlzIGdpdmVuLCBkZWZhdWx0cyB0byBub3dcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IHRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrICgwLTEpXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBwb2x5ID0gbmV3IFRvbmUuUG9seVN5bnRoKFRvbmUuQU1TeW50aCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIC8vIGNhbiBwYXNzIGluIGFuIGFycmF5IG9mIGR1cmF0aW9ucyBhcyB3ZWxsXG4gICAgICogcG9seS50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJFYjNcIiwgXCJHNFwiLCBcIkJiNFwiLCBcIkQ1XCJdLCBbNCwgMywgMiwgMV0pO1xuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2tSZWxlYXNlKG5vdGVzLCBkdXJhdGlvbiwgdGltZSwgdmVsb2NpdHkpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmIChpc0FycmF5KGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkobm90ZXMpLCBcIklmIHRoZSBkdXJhdGlvbiBpcyBhbiBhcnJheSwgdGhlIG5vdGVzIG11c3QgYWxzbyBiZSBhbiBhcnJheVwiKTtcbiAgICAgICAgICAgIG5vdGVzID0gbm90ZXM7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vdGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGR1cmF0aW9uW01hdGgubWluKGksIGR1cmF0aW9uLmxlbmd0aCAtIDEpXTtcbiAgICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvblNlY29uZHMgPSB0aGlzLnRvU2Vjb25kcyhkKTtcbiAgICAgICAgICAgICAgICBhc3NlcnQoZHVyYXRpb25TZWNvbmRzID4gMCwgXCJUaGUgZHVyYXRpb24gbXVzdCBiZSBncmVhdGVyIHRoYW4gMFwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzW2ldLCBjb21wdXRlZFRpbWUgKyBkdXJhdGlvblNlY29uZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gdGhpcy50b1NlY29uZHMoZHVyYXRpb24pO1xuICAgICAgICAgICAgYXNzZXJ0KGR1cmF0aW9uU2Vjb25kcyA+IDAsIFwiVGhlIGR1cmF0aW9uIG11c3QgYmUgZ3JlYXRlciB0aGFuIDBcIik7XG4gICAgICAgICAgICB0aGlzLnRyaWdnZXJSZWxlYXNlKG5vdGVzLCBjb21wdXRlZFRpbWUgKyBkdXJhdGlvblNlY29uZHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgYSBtZW1iZXIvYXR0cmlidXRlIG9mIHRoZSB2b2ljZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBvbHkgPSBuZXcgVG9uZS5Qb2x5U3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICogLy8gc2V0IGFsbCBvZiB0aGUgdm9pY2VzIHVzaW5nIGFuIG9wdGlvbnMgb2JqZWN0IGZvciB0aGUgc3ludGggdHlwZVxuICAgICAqIHBvbHkuc2V0KHtcbiAgICAgKiBcdGVudmVsb3BlOiB7XG4gICAgICogXHRcdGF0dGFjazogMC4yNVxuICAgICAqIFx0fVxuICAgICAqIH0pO1xuICAgICAqIHBvbHkudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJCYjNcIiwgMC4yKTtcbiAgICAgKi9cbiAgICBzZXQob3B0aW9ucykge1xuICAgICAgICAvLyByZW1vdmUgb3B0aW9ucyB3aGljaCBhcmUgY29udHJvbGxlZCBieSB0aGUgUG9seVN5bnRoXG4gICAgICAgIGNvbnN0IHNhbml0aXplZE9wdGlvbnMgPSBvbWl0RnJvbU9iamVjdChvcHRpb25zLCBbXCJvbnNpbGVuY2VcIiwgXCJjb250ZXh0XCJdKTtcbiAgICAgICAgLy8gc3RvcmUgYWxsIG9mIHRoZSBvcHRpb25zXG4gICAgICAgIHRoaXMub3B0aW9ucyA9IGRlZXBNZXJnZSh0aGlzLm9wdGlvbnMsIHNhbml0aXplZE9wdGlvbnMpO1xuICAgICAgICB0aGlzLl92b2ljZXMuZm9yRWFjaCh2b2ljZSA9PiB2b2ljZS5zZXQoc2FuaXRpemVkT3B0aW9ucykpO1xuICAgICAgICB0aGlzLl9kdW1teVZvaWNlLnNldChzYW5pdGl6ZWRPcHRpb25zKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2R1bW15Vm9pY2UuZ2V0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgdGhlIHJlbGVhc2UgcG9ydGlvbiBvZiBhbGwgdGhlIGN1cnJlbnRseSBhY3RpdmUgdm9pY2VzIGltbWVkaWF0ZWx5LlxuICAgICAqIFVzZWZ1bCBmb3Igc2lsZW5jaW5nIHRoZSBzeW50aC5cbiAgICAgKi9cbiAgICByZWxlYXNlQWxsKHRpbWUpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcy5mb3JFYWNoKCh7IHZvaWNlIH0pID0+IHtcbiAgICAgICAgICAgIHZvaWNlLnRyaWdnZXJSZWxlYXNlKGNvbXB1dGVkVGltZSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kdW1teVZvaWNlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9pY2VzLmZvckVhY2godiA9PiB2LmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVZvaWNlcyA9IFtdO1xuICAgICAgICB0aGlzLl9hdmFpbGFibGVWb2ljZXMgPSBbXTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmNsZWFySW50ZXJ2YWwodGhpcy5fZ2NUaW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UG9seVN5bnRoLmpzLm1hcCIsImltcG9ydCB7IF9fZGVjb3JhdGUgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlcnMgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlcnNcIjtcbmltcG9ydCB7IGZ0b21mLCBpbnRlcnZhbFRvRnJlcXVlbmN5UmF0aW8gfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBGcmVxdWVuY3lDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvRnJlcXVlbmN5XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNOb3RlLCBpc051bWJlciB9IGZyb20gXCIuLi9jb3JlL3V0aWwvVHlwZUNoZWNrXCI7XG5pbXBvcnQgeyBJbnN0cnVtZW50IH0gZnJvbSBcIi4uL2luc3RydW1lbnQvSW5zdHJ1bWVudFwiO1xuaW1wb3J0IHsgVG9uZUJ1ZmZlclNvdXJjZSB9IGZyb20gXCIuLi9zb3VyY2UvYnVmZmVyL1RvbmVCdWZmZXJTb3VyY2VcIjtcbmltcG9ydCB7IHRpbWVSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVjb3JhdG9yXCI7XG5pbXBvcnQgeyBhc3NlcnQgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFBhc3MgaW4gYW4gb2JqZWN0IHdoaWNoIG1hcHMgdGhlIG5vdGUncyBwaXRjaCBvciBtaWRpIHZhbHVlIHRvIHRoZSB1cmwsXG4gKiB0aGVuIHlvdSBjYW4gdHJpZ2dlciB0aGUgYXR0YWNrIGFuZCByZWxlYXNlIG9mIHRoYXQgbm90ZSBsaWtlIG90aGVyIGluc3RydW1lbnRzLlxuICogQnkgYXV0b21hdGljYWxseSByZXBpdGNoaW5nIHRoZSBzYW1wbGVzLCBpdCBpcyBwb3NzaWJsZSB0byBwbGF5IHBpdGNoZXMgd2hpY2hcbiAqIHdlcmUgbm90IGV4cGxpY2l0bHkgaW5jbHVkZWQgd2hpY2ggY2FuIHNhdmUgbG9hZGluZyB0aW1lLlxuICpcbiAqIEZvciBzYW1wbGUgb3IgYnVmZmVyIHBsYXliYWNrIHdoZXJlIHJlcGl0Y2hpbmcgaXMgbm90IG5lY2Vzc2FyeSxcbiAqIHVzZSBbW1BsYXllcl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHNhbXBsZXIgPSBuZXcgVG9uZS5TYW1wbGVyKHtcbiAqIFx0dXJsczoge1xuICogXHRcdEExOiBcIkExLm1wM1wiLFxuICogXHRcdEEyOiBcIkEyLm1wM1wiLFxuICogXHR9LFxuICogXHRiYXNlVXJsOiBcImh0dHBzOi8vdG9uZWpzLmdpdGh1Yi5pby9hdWRpby9jYXNpby9cIixcbiAqIFx0b25sb2FkOiAoKSA9PiB7XG4gKiBcdFx0c2FtcGxlci50cmlnZ2VyQXR0YWNrUmVsZWFzZShbXCJDMVwiLCBcIkUxXCIsIFwiRzFcIiwgXCJCMVwiXSwgMC41KTtcbiAqIFx0fVxuICogfSkudG9EZXN0aW5hdGlvbigpO1xuICogQGNhdGVnb3J5IEluc3RydW1lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNhbXBsZXIgZXh0ZW5kcyBJbnN0cnVtZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU2FtcGxlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInVybHNcIiwgXCJvbmxvYWRcIiwgXCJiYXNlVXJsXCJdLCBcInVybHNcIikpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNhbXBsZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBvYmplY3Qgb2YgYWxsIGN1cnJlbnRseSBwbGF5aW5nIEJ1ZmZlclNvdXJjZXNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FjdGl2ZVNvdXJjZXMgPSBuZXcgTWFwKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTYW1wbGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsc1wiLCBcIm9ubG9hZFwiLCBcImJhc2VVcmxcIl0sIFwidXJsc1wiKTtcbiAgICAgICAgY29uc3QgdXJsTWFwID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMudXJscykuZm9yRWFjaCgobm90ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm90ZU51bWJlciA9IHBhcnNlSW50KG5vdGUsIDEwKTtcbiAgICAgICAgICAgIGFzc2VydChpc05vdGUobm90ZSlcbiAgICAgICAgICAgICAgICB8fCAoaXNOdW1iZXIobm90ZU51bWJlcikgJiYgaXNGaW5pdGUobm90ZU51bWJlcikpLCBgdXJsIGtleSBpcyBuZWl0aGVyIGEgbm90ZSBvciBtaWRpIHBpdGNoOiAke25vdGV9YCk7XG4gICAgICAgICAgICBpZiAoaXNOb3RlKG5vdGUpKSB7XG4gICAgICAgICAgICAgICAgLy8gY29udmVydCB0aGUgbm90ZSBuYW1lIHRvIE1JRElcbiAgICAgICAgICAgICAgICBjb25zdCBtaWQgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgICAgICB1cmxNYXBbbWlkXSA9IG9wdGlvbnMudXJsc1tub3RlXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzTnVtYmVyKG5vdGVOdW1iZXIpICYmIGlzRmluaXRlKG5vdGVOdW1iZXIpKSB7XG4gICAgICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGlmIGl0J3MgbnVtYmVycyBhc3N1bWUgaXQncyBtaWRpXG4gICAgICAgICAgICAgICAgdXJsTWFwW25vdGVOdW1iZXJdID0gb3B0aW9ucy51cmxzW25vdGVOdW1iZXJdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYnVmZmVycyA9IG5ldyBUb25lQXVkaW9CdWZmZXJzKHtcbiAgICAgICAgICAgIHVybHM6IHVybE1hcCxcbiAgICAgICAgICAgIG9ubG9hZDogb3B0aW9ucy5vbmxvYWQsXG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmJhc2VVcmwsXG4gICAgICAgICAgICBvbmVycm9yOiBvcHRpb25zLm9uZXJyb3IsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG9wdGlvbnMuYXR0YWNrO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBvcHRpb25zLnJlbGVhc2U7XG4gICAgICAgIHRoaXMuY3VydmUgPSBvcHRpb25zLmN1cnZlO1xuICAgICAgICAvLyBpbnZva2UgdGhlIGNhbGxiYWNrIGlmIGl0J3MgYWxyZWFkeSBsb2FkZWRcbiAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMubG9hZGVkKSB7XG4gICAgICAgICAgICAvLyBpbnZva2Ugb25sb2FkIGRlZmVycmVkXG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKG9wdGlvbnMub25sb2FkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEluc3RydW1lbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYXR0YWNrOiAwLFxuICAgICAgICAgICAgYmFzZVVybDogXCJcIixcbiAgICAgICAgICAgIGN1cnZlOiBcImV4cG9uZW50aWFsXCIsXG4gICAgICAgICAgICBvbmxvYWQ6IG5vT3AsXG4gICAgICAgICAgICBvbmVycm9yOiBub09wLFxuICAgICAgICAgICAgcmVsZWFzZTogMC4xLFxuICAgICAgICAgICAgdXJsczoge30sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBkaWZmZXJlbmNlIGluIHN0ZXBzIGJldHdlZW4gdGhlIGdpdmVuIG1pZGkgbm90ZSBhdCB0aGUgY2xvc2V0cyBzYW1wbGUuXG4gICAgICovXG4gICAgX2ZpbmRDbG9zZXN0KG1pZGkpIHtcbiAgICAgICAgLy8gc2VhcmNoZXMgd2l0aGluIDggb2N0YXZlcyBvZiB0aGUgZ2l2ZW4gbWlkaSBub3RlXG4gICAgICAgIGNvbnN0IE1BWF9JTlRFUlZBTCA9IDk2O1xuICAgICAgICBsZXQgaW50ZXJ2YWwgPSAwO1xuICAgICAgICB3aGlsZSAoaW50ZXJ2YWwgPCBNQVhfSU5URVJWQUwpIHtcbiAgICAgICAgICAgIC8vIGNoZWNrIGFib3ZlIGFuZCBiZWxvd1xuICAgICAgICAgICAgaWYgKHRoaXMuX2J1ZmZlcnMuaGFzKG1pZGkgKyBpbnRlcnZhbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gLWludGVydmFsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fYnVmZmVycy5oYXMobWlkaSAtIGludGVydmFsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpbnRlcnZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGludGVydmFsKys7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBhdmFpbGFibGUgYnVmZmVycyBmb3Igbm90ZTogJHttaWRpfWApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byBwbGF5LCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIHRpbWUgICAgIFdoZW4gdG8gcGxheSB0aGUgbm90ZVxuICAgICAqIEBwYXJhbSAgdmVsb2NpdHkgVGhlIHZlbG9jaXR5IHRvIHBsYXkgdGhlIHNhbXBsZSBiYWNrLlxuICAgICAqL1xuICAgIHRyaWdnZXJBdHRhY2sobm90ZXMsIHRpbWUsIHZlbG9jaXR5ID0gMSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJBdHRhY2tcIiwgbm90ZXMsIHRpbWUsIHZlbG9jaXR5KTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpRmxvYXQgPSBmdG9tZihuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b0ZyZXF1ZW5jeSgpKTtcbiAgICAgICAgICAgIGNvbnN0IG1pZGkgPSBNYXRoLnJvdW5kKG1pZGlGbG9hdCk7XG4gICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBtaWRpRmxvYXQgLSBtaWRpO1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgY2xvc2VzdCBub3RlIHBpdGNoXG4gICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gdGhpcy5fZmluZENsb3Nlc3QobWlkaSk7XG4gICAgICAgICAgICBjb25zdCBjbG9zZXN0Tm90ZSA9IG1pZGkgLSBkaWZmZXJlbmNlO1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fYnVmZmVycy5nZXQoY2xvc2VzdE5vdGUpO1xuICAgICAgICAgICAgY29uc3QgcGxheWJhY2tSYXRlID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGRpZmZlcmVuY2UgKyByZW1haW5kZXIpO1xuICAgICAgICAgICAgLy8gcGxheSB0aGF0IG5vdGVcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IG5ldyBUb25lQnVmZmVyU291cmNlKHtcbiAgICAgICAgICAgICAgICB1cmw6IGJ1ZmZlcixcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgY3VydmU6IHRoaXMuY3VydmUsXG4gICAgICAgICAgICAgICAgZmFkZUluOiB0aGlzLmF0dGFjayxcbiAgICAgICAgICAgICAgICBmYWRlT3V0OiB0aGlzLnJlbGVhc2UsXG4gICAgICAgICAgICAgICAgcGxheWJhY2tSYXRlLFxuICAgICAgICAgICAgfSkuY29ubmVjdCh0aGlzLm91dHB1dCk7XG4gICAgICAgICAgICBzb3VyY2Uuc3RhcnQodGltZSwgMCwgYnVmZmVyLmR1cmF0aW9uIC8gcGxheWJhY2tSYXRlLCB2ZWxvY2l0eSk7XG4gICAgICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGFjdGl2ZSBzb3VyY2VzXG4gICAgICAgICAgICBpZiAoIWlzQXJyYXkodGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zZXQobWlkaSwgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkucHVzaChzb3VyY2UpO1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGl0IHdoZW4gaXQncyBkb25lXG4gICAgICAgICAgICBzb3VyY2Uub25lbmRlZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcyAmJiB0aGlzLl9hY3RpdmVTb3VyY2VzLmhhcyhtaWRpKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gc291cmNlcy5pbmRleE9mKHNvdXJjZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogQHBhcmFtICBub3Rlc1x0VGhlIG5vdGUgdG8gcmVsZWFzZSwgb3IgYW4gYXJyYXkgb2Ygbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBcdFdoZW4gdG8gcmVsZWFzZSB0aGUgbm90ZS5cbiAgICAgKi9cbiAgICB0cmlnZ2VyUmVsZWFzZShub3RlcywgdGltZSkge1xuICAgICAgICB0aGlzLmxvZyhcInRyaWdnZXJSZWxlYXNlXCIsIG5vdGVzLCB0aW1lKTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KG5vdGVzKSkge1xuICAgICAgICAgICAgbm90ZXMgPSBbbm90ZXNdO1xuICAgICAgICB9XG4gICAgICAgIG5vdGVzLmZvckVhY2gobm90ZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBtaWRpID0gbmV3IEZyZXF1ZW5jeUNsYXNzKHRoaXMuY29udGV4dCwgbm90ZSkudG9NaWRpKCk7XG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBub3RlXG4gICAgICAgICAgICBpZiAodGhpcy5fYWN0aXZlU291cmNlcy5oYXMobWlkaSkgJiYgdGhpcy5fYWN0aXZlU291cmNlcy5nZXQobWlkaSkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlcyA9IHRoaXMuX2FjdGl2ZVNvdXJjZXMuZ2V0KG1pZGkpO1xuICAgICAgICAgICAgICAgIHRpbWUgPSB0aGlzLnRvU2Vjb25kcyh0aW1lKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VzLmZvckVhY2goc291cmNlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlLnN0b3AodGltZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5zZXQobWlkaSwgW10pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlbGVhc2UgYWxsIGN1cnJlbnRseSBhY3RpdmUgbm90ZXMuXG4gICAgICogQHBhcmFtICB0aW1lICAgICBcdFdoZW4gdG8gcmVsZWFzZSB0aGUgbm90ZXMuXG4gICAgICovXG4gICAgcmVsZWFzZUFsbCh0aW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbXB1dGVkVGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlcyA9PiB7XG4gICAgICAgICAgICB3aGlsZSAoc291cmNlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBzb3VyY2VzLnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgc291cmNlLnN0b3AoY29tcHV0ZWRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBzeW5jKCkge1xuICAgICAgICBpZiAodGhpcy5fc3luY1N0YXRlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuX3N5bmNNZXRob2QoXCJ0cmlnZ2VyQXR0YWNrXCIsIDEpO1xuICAgICAgICAgICAgdGhpcy5fc3luY01ldGhvZChcInRyaWdnZXJSZWxlYXNlXCIsIDEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnZva2UgdGhlIGF0dGFjayBwaGFzZSwgdGhlbiBhZnRlciB0aGUgZHVyYXRpb24sIGludm9rZSB0aGUgcmVsZWFzZS5cbiAgICAgKiBAcGFyYW0gIG5vdGVzXHRUaGUgbm90ZSB0byBwbGF5IGFuZCByZWxlYXNlLCBvciBhbiBhcnJheSBvZiBub3Rlcy5cbiAgICAgKiBAcGFyYW0gIGR1cmF0aW9uIFRoZSB0aW1lIHRoZSBub3RlIHNob3VsZCBiZSBoZWxkXG4gICAgICogQHBhcmFtICB0aW1lICAgICBXaGVuIHRvIHN0YXJ0IHRoZSBhdHRhY2tcbiAgICAgKiBAcGFyYW0gIHZlbG9jaXR5IFRoZSB2ZWxvY2l0eSBvZiB0aGUgYXR0YWNrXG4gICAgICovXG4gICAgdHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZXMsIGR1cmF0aW9uLCB0aW1lLCB2ZWxvY2l0eSA9IDEpIHtcbiAgICAgICAgY29uc3QgY29tcHV0ZWRUaW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIHRoaXMudHJpZ2dlckF0dGFjayhub3RlcywgY29tcHV0ZWRUaW1lLCB2ZWxvY2l0eSk7XG4gICAgICAgIGlmIChpc0FycmF5KGR1cmF0aW9uKSkge1xuICAgICAgICAgICAgYXNzZXJ0KGlzQXJyYXkobm90ZXMpLCBcIm5vdGVzIG11c3QgYmUgYW4gYXJyYXkgd2hlbiBkdXJhdGlvbiBpcyBhcnJheVwiKTtcbiAgICAgICAgICAgIG5vdGVzLmZvckVhY2goKG5vdGUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZCA9IGR1cmF0aW9uW01hdGgubWluKGluZGV4LCBkdXJhdGlvbi5sZW5ndGggLSAxKV07XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyUmVsZWFzZShub3RlLCBjb21wdXRlZFRpbWUgKyB0aGlzLnRvU2Vjb25kcyhkKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlclJlbGVhc2Uobm90ZXMsIGNvbXB1dGVkVGltZSArIHRoaXMudG9TZWNvbmRzKGR1cmF0aW9uKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFkZCBhIG5vdGUgdG8gdGhlIHNhbXBsZXIuXG4gICAgICogQHBhcmFtICBub3RlICAgICAgVGhlIGJ1ZmZlcidzIHBpdGNoLlxuICAgICAqIEBwYXJhbSAgdXJsICBFaXRoZXIgdGhlIHVybCBvZiB0aGUgYnVmZmVyLCBvciBhIGJ1ZmZlciB3aGljaCB3aWxsIGJlIGFkZGVkIHdpdGggdGhlIGdpdmVuIG5hbWUuXG4gICAgICogQHBhcmFtICBjYWxsYmFjayAgVGhlIGNhbGxiYWNrIHRvIGludm9rZSB3aGVuIHRoZSB1cmwgaXMgbG9hZGVkLlxuICAgICAqL1xuICAgIGFkZChub3RlLCB1cmwsIGNhbGxiYWNrKSB7XG4gICAgICAgIGFzc2VydChpc05vdGUobm90ZSkgfHwgaXNGaW5pdGUobm90ZSksIGBub3RlIG11c3QgYmUgYSBwaXRjaCBvciBtaWRpOiAke25vdGV9YCk7XG4gICAgICAgIGlmIChpc05vdGUobm90ZSkpIHtcbiAgICAgICAgICAgIC8vIGNvbnZlcnQgdGhlIG5vdGUgbmFtZSB0byBNSURJXG4gICAgICAgICAgICBjb25zdCBtaWQgPSBuZXcgRnJlcXVlbmN5Q2xhc3ModGhpcy5jb250ZXh0LCBub3RlKS50b01pZGkoKTtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG1pZCwgdXJsLCBjYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaWYgaXQncyBudW1iZXJzIGFzc3VtZSBpdCdzIG1pZGlcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlcnMuYWRkKG5vdGUsIHVybCwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgYnVmZmVycyBhcmUgbG9hZGVkIG9yIG5vdFxuICAgICAqL1xuICAgIGdldCBsb2FkZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzLmxvYWRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ2xlYW4gdXBcbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2J1ZmZlcnMuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hY3RpdmVTb3VyY2VzLmZvckVhY2goc291cmNlcyA9PiB7XG4gICAgICAgICAgICBzb3VyY2VzLmZvckVhY2goc291cmNlID0+IHNvdXJjZS5kaXNwb3NlKCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYWN0aXZlU291cmNlcy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5fX2RlY29yYXRlKFtcbiAgICB0aW1lUmFuZ2UoMClcbl0sIFNhbXBsZXIucHJvdG90eXBlLCBcImF0dGFja1wiLCB2b2lkIDApO1xuX19kZWNvcmF0ZShbXG4gICAgdGltZVJhbmdlKDApXG5dLCBTYW1wbGVyLnByb3RvdHlwZSwgXCJyZWxlYXNlXCIsIHZvaWQgMCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TYW1wbGVyLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0FNU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0R1b1N5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GTVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NZXRhbFN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9NZW1icmFuZVN5bnRoXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9Nb25vU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL05vaXNlU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BsdWNrU3ludGhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BvbHlTeW50aFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU2FtcGxlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vU3ludGhcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCBcIi4uL2NvcmUvY2xvY2svVHJhbnNwb3J0XCI7XG5pbXBvcnQgeyBUb25lV2l0aENvbnRleHQgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVXaXRoQ29udGV4dFwiO1xuaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IGRlZmF1bHRBcmcsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0Jvb2xlYW4sIGlzTnVtYmVyIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbi8qKlxuICogVG9uZUV2ZW50IGFic3RyYWN0cyBhd2F5IHRoaXMuY29udGV4dC50cmFuc3BvcnQuc2NoZWR1bGUgYW5kIHByb3ZpZGVzIGEgc2NoZWR1bGFibGVcbiAqIGNhbGxiYWNrIGZvciBhIHNpbmdsZSBvciByZXBlYXRhYmxlIGV2ZW50cyBhbG9uZyB0aGUgdGltZWxpbmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuUG9seVN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgY2hvcmRFdmVudCA9IG5ldyBUb25lLlRvbmVFdmVudCgoKHRpbWUsIGNob3JkKSA9PiB7XG4gKiBcdC8vIHRoZSBjaG9yZCBhcyB3ZWxsIGFzIHRoZSBleGFjdCB0aW1lIG9mIHRoZSBldmVudFxuICogXHQvLyBhcmUgcGFzc2VkIGluIGFzIGFyZ3VtZW50cyB0byB0aGUgY2FsbGJhY2sgZnVuY3Rpb25cbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoY2hvcmQsIDAuNSwgdGltZSk7XG4gKiB9KSwgW1wiRDRcIiwgXCJFNFwiLCBcIkY0XCJdKTtcbiAqIC8vIHN0YXJ0IHRoZSBjaG9yZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB0cmFuc3BvcnQgdGltZWxpbmVcbiAqIGNob3JkRXZlbnQuc3RhcnQoKTtcbiAqIC8vIGxvb3AgaXQgZXZlcnkgbWVhc3VyZSBmb3IgOCBtZWFzdXJlc1xuICogY2hvcmRFdmVudC5sb29wID0gODtcbiAqIGNob3JkRXZlbnQubG9vcEVuZCA9IFwiMW1cIjtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgVG9uZUV2ZW50IGV4dGVuZHMgVG9uZVdpdGhDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlRvbmVFdmVudFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogVHJhY2tzIHRoZSBzY2hlZHVsZWQgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zdGF0ZSA9IG5ldyBTdGF0ZVRpbWVsaW5lKFwic3RvcHBlZFwiKTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgZGVsYXkgdGltZSBmcm9tIHdoZW4gdGhlIGV2ZW50IGlzIHNjaGVkdWxlZCB0byBzdGFydFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fc3RhcnRPZmZzZXQgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZVwiXSk7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBvcHRpb25zLmNhbGxiYWNrO1xuICAgICAgICB0aGlzLnZhbHVlID0gb3B0aW9ucy52YWx1ZTtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKG9wdGlvbnMubG9vcFN0YXJ0KTtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhvcHRpb25zLmxvb3BFbmQpO1xuICAgICAgICB0aGlzLl9wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBvcHRpb25zLnByb2JhYmlsaXR5O1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IG9wdGlvbnMuaHVtYW5pemU7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgICAgIHRoaXMuX3N0YXRlLmluY3JlYXNpbmcgPSB0cnVlO1xuICAgICAgICAvLyBzY2hlZHVsZSB0aGUgZXZlbnRzIGZvciB0aGUgZmlyc3QgdGltZVxuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZVdpdGhDb250ZXh0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgaHVtYW5pemU6IGZhbHNlLFxuICAgICAgICAgICAgbG9vcDogZmFsc2UsXG4gICAgICAgICAgICBsb29wRW5kOiBcIjFtXCIsXG4gICAgICAgICAgICBsb29wU3RhcnQ6IDAsXG4gICAgICAgICAgICBtdXRlOiBmYWxzZSxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiAxLFxuICAgICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXNjaGVkdWxlIGFsbCBvZiB0aGUgZXZlbnRzIGFsb25nIHRoZSB0aW1lbGluZVxuICAgICAqIHdpdGggdGhlIHVwZGF0ZWQgdmFsdWVzLlxuICAgICAqIEBwYXJhbSBhZnRlciBPbmx5IHJlc2NoZWR1bGVzIGV2ZW50cyBhZnRlciB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKi9cbiAgICBfcmVzY2hlZHVsZUV2ZW50cyhhZnRlciA9IC0xKSB7XG4gICAgICAgIC8vIGlmIG5vIGFyZ3VtZW50IGlzIGdpdmVuLCBzY2hlZHVsZXMgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgICAgdGhpcy5fc3RhdGUuZm9yRWFjaEZyb20oYWZ0ZXIsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGxldCBkdXJhdGlvbjtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0ZSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQuaWQgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC50cmFuc3BvcnQuY2xlYXIoZXZlbnQuaWQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydFRpY2sgPSBldmVudC50aW1lICsgTWF0aC5yb3VuZCh0aGlzLnN0YXJ0T2Zmc2V0IC8gdGhpcy5fcGxheWJhY2tSYXRlKTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fbG9vcCA9PT0gdHJ1ZSB8fCBpc051bWJlcih0aGlzLl9sb29wKSAmJiB0aGlzLl9sb29wID4gMSkge1xuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IEluZmluaXR5O1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNOdW1iZXIodGhpcy5fbG9vcCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gKHRoaXMuX2xvb3ApICogdGhpcy5fZ2V0TG9vcER1cmF0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV4dEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QWZ0ZXIoc3RhcnRUaWNrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSBNYXRoLm1pbihkdXJhdGlvbiwgbmV4dEV2ZW50LnRpbWUgLSBzdGFydFRpY2spO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbiAhPT0gSW5maW5pdHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNjaGVkdWxlIGEgc3RvcCBzaW5jZSBpdCdzIGZpbml0ZSBkdXJhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUuc2V0U3RhdGVBdFRpbWUoXCJzdG9wcGVkXCIsIHN0YXJ0VGljayArIGR1cmF0aW9uICsgMSwgeyBpZDogLTEgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aGlzLl9nZXRMb29wRHVyYXRpb24oKSk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZVJlcGVhdCh0aGlzLl90aWNrLmJpbmQodGhpcyksIGludGVydmFsLCBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXJ0VGljayksIGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmlkID0gdGhpcy5jb250ZXh0LnRyYW5zcG9ydC5zY2hlZHVsZSh0aGlzLl90aWNrLmJpbmQodGhpcyksIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgc3RhcnRUaWNrKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgcGxheWJhY2sgc3RhdGUgb2YgdGhlIG5vdGUsIGVpdGhlciBcInN0YXJ0ZWRcIiBvciBcInN0b3BwZWRcIi5cbiAgICAgKi9cbiAgICBnZXQgc3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHN0YXJ0IGZyb20gdGhlIHNjaGVkdWxlZCBzdGFydCB0aW1lLlxuICAgICAqL1xuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gb2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvYmFiaWxpdHkgb2YgdGhlIG5vdGVzIGJlaW5nIHRyaWdnZXJlZC5cbiAgICAgKi9cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiBzZXQgdG8gdHJ1ZSwgd2lsbCBhcHBseSBzbWFsbCByYW5kb20gdmFyaWF0aW9uXG4gICAgICogdG8gdGhlIGNhbGxiYWNrIHRpbWUuIElmIHRoZSB2YWx1ZSBpcyBnaXZlbiBhcyBhIHRpbWUsIGl0IHdpbGwgcmFuZG9taXplXG4gICAgICogYnkgdGhhdCBhbW91bnQuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBldmVudCA9IG5ldyBUb25lLlRvbmVFdmVudCgpO1xuICAgICAqIGV2ZW50Lmh1bWFuaXplID0gdHJ1ZTtcbiAgICAgKi9cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9odW1hbml6ZTtcbiAgICB9XG4gICAgc2V0IGh1bWFuaXplKHZhcmlhdGlvbikge1xuICAgICAgICB0aGlzLl9odW1hbml6ZSA9IHZhcmlhdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIG5vdGUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICBXaGVuIHRoZSBldmVudCBzaG91bGQgc3RhcnQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdG9wcGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLmFkZCh7XG4gICAgICAgICAgICAgICAgaWQ6IC0xLFxuICAgICAgICAgICAgICAgIHN0YXRlOiBcInN0YXJ0ZWRcIixcbiAgICAgICAgICAgICAgICB0aW1lOiB0aWNrcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZUV2ZW50cyh0aWNrcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIEV2ZW50IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0aGUgZXZlbnQgc2hvdWxkIHN0b3AuXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuY2FuY2VsKHRpbWUpO1xuICAgICAgICBjb25zdCB0aWNrcyA9IHRoaXMudG9UaWNrcyh0aW1lKTtcbiAgICAgICAgaWYgKHRoaXMuX3N0YXRlLmdldFZhbHVlQXRUaW1lKHRpY2tzKSA9PT0gXCJzdGFydGVkXCIpIHtcbiAgICAgICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aWNrcywgeyBpZDogLTEgfSk7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c0V2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0QmVmb3JlKHRpY2tzKTtcbiAgICAgICAgICAgIGxldCByZXNjaGVkdWxUaW1lID0gdGlja3M7XG4gICAgICAgICAgICBpZiAocHJldmlvdXNFdmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlc2NoZWR1bFRpbWUgPSBwcmV2aW91c0V2ZW50LnRpbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKHJlc2NoZWR1bFRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDYW5jZWwgYWxsIHNjaGVkdWxlZCBldmVudHMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZSBnaXZlbiB0aW1lXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBhZnRlciB3aGljaCBldmVudHMgd2lsbCBiZSBjYW5jZWwuXG4gICAgICovXG4gICAgY2FuY2VsKHRpbWUpIHtcbiAgICAgICAgdGltZSA9IGRlZmF1bHRBcmcodGltZSwgLUluZmluaXR5KTtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2hGcm9tKHRpY2tzLCBldmVudCA9PiB7XG4gICAgICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmNsZWFyKGV2ZW50LmlkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gaW52b2tlci4gQWxzb1xuICAgICAqIGNoZWNrcyBpZiB0aGUgRXZlbnQgaXMgZG9uZSBwbGF5aW5nXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBvZiB0aGUgZXZlbnQgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LmdldFRpY2tzQXRUaW1lKHRpbWUpO1xuICAgICAgICBpZiAoIXRoaXMubXV0ZSAmJiB0aGlzLl9zdGF0ZS5nZXRWYWx1ZUF0VGltZSh0aWNrcykgPT09IFwic3RhcnRlZFwiKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9iYWJpbGl0eSA8IDEgJiYgTWF0aC5yYW5kb20oKSA+IHRoaXMucHJvYmFiaWxpdHkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5odW1hbml6ZSkge1xuICAgICAgICAgICAgICAgIGxldCB2YXJpYXRpb24gPSAwLjAyO1xuICAgICAgICAgICAgICAgIGlmICghaXNCb29sZWFuKHRoaXMuaHVtYW5pemUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhcmlhdGlvbiA9IHRoaXMudG9TZWNvbmRzKHRoaXMuaHVtYW5pemUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aW1lICs9IChNYXRoLnJhbmRvbSgpICogMiAtIDEpICogdmFyaWF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGR1cmF0aW9uIG9mIHRoZSBsb29wLlxuICAgICAqL1xuICAgIF9nZXRMb29wRHVyYXRpb24oKSB7XG4gICAgICAgIHJldHVybiBNYXRoLnJvdW5kKCh0aGlzLl9sb29wRW5kIC0gdGhpcy5fbG9vcFN0YXJ0KSAvIHRoaXMuX3BsYXliYWNrUmF0ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBub3RlIHNob3VsZCBsb29wIG9yIG5vdFxuICAgICAqIGJldHdlZW4gVG9uZUV2ZW50Lmxvb3BTdGFydCBhbmRcbiAgICAgKiBUb25lRXZlbnQubG9vcEVuZC4gSWYgc2V0IHRvIHRydWUsXG4gICAgICogdGhlIGV2ZW50IHdpbGwgbG9vcCBpbmRlZmluaXRlbHksXG4gICAgICogaWYgc2V0IHRvIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAxXG4gICAgICogaXQgd2lsbCBwbGF5IGEgc3BlY2lmaWMgbnVtYmVyIG9mXG4gICAgICogdGltZXMsIGlmIHNldCB0byBmYWxzZSwgMCBvciAxLCB0aGVcbiAgICAgKiBwYXJ0IHdpbGwgb25seSBwbGF5IG9uY2UuXG4gICAgICovXG4gICAgZ2V0IGxvb3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgIH1cbiAgICBzZXQgbG9vcChsb29wKSB7XG4gICAgICAgIHRoaXMuX2xvb3AgPSBsb29wO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwbGF5YmFjayByYXRlIG9mIHRoZSBub3RlLiBEZWZhdWx0cyB0byAxLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3Qgbm90ZSA9IG5ldyBUb25lLlRvbmVFdmVudCgpO1xuICAgICAqIG5vdGUubG9vcCA9IHRydWU7XG4gICAgICogLy8gcmVwZWF0IHRoZSBub3RlIHR3aWNlIGFzIGZhc3RcbiAgICAgKiBub3RlLnBsYXliYWNrUmF0ZSA9IDI7XG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX3BsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgICAgIHRoaXMuX3Jlc2NoZWR1bGVFdmVudHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGxvb3BFbmQgcG9pbnQgaXMgdGhlIHRpbWUgdGhlIGV2ZW50IHdpbGwgbG9vcFxuICAgICAqIGlmIFRvbmVFdmVudC5sb29wIGlzIHRydWUuXG4gICAgICovXG4gICAgZ2V0IGxvb3BFbmQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BFbmQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICBzZXQgbG9vcEVuZChsb29wRW5kKSB7XG4gICAgICAgIHRoaXMuX2xvb3BFbmQgPSB0aGlzLnRvVGlja3MobG9vcEVuZCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgd2hlbiB0aGUgbG9vcCBzaG91bGQgc3RhcnQuXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcFN0YXJ0KS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChsb29wU3RhcnQpIHtcbiAgICAgICAgdGhpcy5fbG9vcFN0YXJ0ID0gdGhpcy50b1RpY2tzKGxvb3BTdGFydCk7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICB0aGlzLl9yZXNjaGVkdWxlRXZlbnRzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgcHJvZ3Jlc3Mgb2YgdGhlIGxvb3AgaW50ZXJ2YWwuXG4gICAgICogUmV0dXJucyAwIGlmIHRoZSBldmVudCBpcyBub3Qgc3RhcnRlZCB5ZXQgb3JcbiAgICAgKiBpdCBpcyBub3Qgc2V0IHRvIGxvb3AuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnRpY2tzO1xuICAgICAgICAgICAgY29uc3QgbGFzdEV2ZW50ID0gdGhpcy5fc3RhdGUuZ2V0KHRpY2tzKTtcbiAgICAgICAgICAgIGlmIChsYXN0RXZlbnQgIT09IG51bGwgJiYgbGFzdEV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvb3BEdXJhdGlvbiA9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gKHRpY2tzIC0gbGFzdEV2ZW50LnRpbWUpICUgbG9vcER1cmF0aW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBwcm9ncmVzcyAvIGxvb3BEdXJhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmNhbmNlbCgpO1xuICAgICAgICB0aGlzLl9zdGF0ZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVRvbmVFdmVudC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lRXZlbnQgfSBmcm9tIFwiLi9Ub25lRXZlbnRcIjtcbmltcG9ydCB7IFRvbmVXaXRoQ29udGV4dCB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZVdpdGhDb250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IG5vT3AgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBMb29wIGNyZWF0ZXMgYSBsb29wZWQgY2FsbGJhY2sgYXQgdGhlXG4gKiBzcGVjaWZpZWQgaW50ZXJ2YWwuIFRoZSBjYWxsYmFjayBjYW4gYmVcbiAqIHN0YXJ0ZWQsIHN0b3BwZWQgYW5kIHNjaGVkdWxlZCBhbG9uZ1xuICogdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGxvb3AgPSBuZXcgVG9uZS5Mb29wKCh0aW1lKSA9PiB7XG4gKiBcdC8vIHRyaWdnZXJlZCBldmVyeSBlaWdodGggbm90ZS5cbiAqIFx0Y29uc29sZS5sb2codGltZSk7XG4gKiB9LCBcIjhuXCIpLnN0YXJ0KDApO1xuICogVG9uZS5UcmFuc3BvcnQuc3RhcnQoKTtcbiAqIEBjYXRlZ29yeSBFdmVudFxuICovXG5leHBvcnQgY2xhc3MgTG9vcCBleHRlbmRzIFRvbmVXaXRoQ29udGV4dCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKExvb3AuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImludGVydmFsXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTG9vcFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTG9vcC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNhbGxiYWNrXCIsIFwiaW50ZXJ2YWxcIl0pO1xuICAgICAgICB0aGlzLl9ldmVudCA9IG5ldyBUb25lRXZlbnQoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3RpY2suYmluZCh0aGlzKSxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBsb29wRW5kOiBvcHRpb25zLmludGVydmFsLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiBvcHRpb25zLnBsYXliYWNrUmF0ZSxcbiAgICAgICAgICAgIHByb2JhYmlsaXR5OiBvcHRpb25zLnByb2JhYmlsaXR5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNhbGxiYWNrID0gb3B0aW9ucy5jYWxsYmFjaztcbiAgICAgICAgLy8gc2V0IHRoZSBpdGVyYXRpb25zXG4gICAgICAgIHRoaXMuaXRlcmF0aW9ucyA9IG9wdGlvbnMuaXRlcmF0aW9ucztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lV2l0aENvbnRleHQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaW50ZXJ2YWw6IFwiNG5cIixcbiAgICAgICAgICAgIGNhbGxiYWNrOiBub09wLFxuICAgICAgICAgICAgcGxheWJhY2tSYXRlOiAxLFxuICAgICAgICAgICAgaXRlcmF0aW9uczogSW5maW5pdHksXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogMSxcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgaHVtYW5pemU6IGZhbHNlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgbG9vcCBhdCB0aGUgc3BlY2lmaWVkIHRpbWUgYWxvbmcgdGhlIFRyYW5zcG9ydCdzIHRpbWVsaW5lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdGFydCB0aGUgTG9vcC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbG9vcCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgTG9vcC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQuc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBhbGwgc2NoZWR1bGVkIGV2ZW50cyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlIGdpdmVuIHRpbWVcbiAgICAgKiBAcGFyYW0gIHRpbWUgIFRoZSB0aW1lIGFmdGVyIHdoaWNoIGV2ZW50cyB3aWxsIGJlIGNhbmNlbC5cbiAgICAgKi9cbiAgICBjYW5jZWwodGltZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5jYW5jZWwodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgd2hlbiB0aGUgbm90ZXMgc2hvdWxkIGJlIGNhbGxlZFxuICAgICAqIEBwYXJhbSB0aW1lICBUaGUgdGltZSB0aGUgZXZlbnQgb2NjdXJzXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3RhdGUgb2YgdGhlIExvb3AsIGVpdGhlciBzdGFydGVkIG9yIHN0b3BwZWQuXG4gICAgICovXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBwcm9ncmVzcyBvZiB0aGUgbG9vcCBhcyBhIHZhbHVlIGJldHdlZW4gMC0xLiAwLCB3aGVuIHRoZSBsb29wIGlzIHN0b3BwZWQgb3IgZG9uZSBpdGVyYXRpbmcuXG4gICAgICovXG4gICAgZ2V0IHByb2dyZXNzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvZ3Jlc3M7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aW1lIGJldHdlZW4gc3VjY2Vzc2l2ZSBjYWxsYmFja3MuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBsb29wID0gbmV3IFRvbmUuTG9vcCgpO1xuICAgICAqIGxvb3AuaW50ZXJ2YWwgPSBcIjhuXCI7IC8vIGxvb3AgZXZlcnkgOG5cbiAgICAgKi9cbiAgICBnZXQgaW50ZXJ2YWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9ldmVudC5sb29wRW5kO1xuICAgIH1cbiAgICBzZXQgaW50ZXJ2YWwoaW50ZXJ2YWwpIHtcbiAgICAgICAgdGhpcy5fZXZlbnQubG9vcEVuZCA9IGludGVydmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGxheWJhY2sgcmF0ZSBvZiB0aGUgbG9vcC4gVGhlIG5vcm1hbCBwbGF5YmFjayByYXRlIGlzIDEgKG5vIGNoYW5nZSkuXG4gICAgICogQSBgcGxheWJhY2tSYXRlYCBvZiAyIHdvdWxkIGJlIHR3aWNlIGFzIGZhc3QuXG4gICAgICovXG4gICAgZ2V0IHBsYXliYWNrUmF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50LnBsYXliYWNrUmF0ZTtcbiAgICB9XG4gICAgc2V0IHBsYXliYWNrUmF0ZShyYXRlKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnBsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJhbmRvbSB2YXJpYXRpb24gKy8tMC4wMXMgdG8gdGhlIHNjaGVkdWxlZCB0aW1lLlxuICAgICAqIE9yIGdpdmUgaXQgYSB0aW1lIHZhbHVlIHdoaWNoIGl0IHdpbGwgcmFuZG9taXplIGJ5LlxuICAgICAqL1xuICAgIGdldCBodW1hbml6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmh1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50Lmh1bWFuaXplID0gdmFyaWF0aW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcHJvYmFibHkgb2YgdGhlIGNhbGxiYWNrIGJlaW5nIGludm9rZWQuXG4gICAgICovXG4gICAgZ2V0IHByb2JhYmlsaXR5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQucHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX2V2ZW50LnByb2JhYmlsaXR5ID0gcHJvYjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0aW5nIHRoZSBMb29wIG1lYW5zIHRoYXQgbm8gY2FsbGJhY2tzIGFyZSBpbnZva2VkLlxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnQubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl9ldmVudC5tdXRlID0gbXV0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpdGVyYXRpb25zIG9mIHRoZSBsb29wLiBUaGUgZGVmYXVsdCB2YWx1ZSBpcyBgSW5maW5pdHlgIChsb29wIGZvcmV2ZXIpLlxuICAgICAqL1xuICAgIGdldCBpdGVyYXRpb25zKCkge1xuICAgICAgICBpZiAodGhpcy5fZXZlbnQubG9vcCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgcmV0dXJuIEluZmluaXR5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50Lmxvb3A7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0IGl0ZXJhdGlvbnMoaXRlcnMpIHtcbiAgICAgICAgaWYgKGl0ZXJzID09PSBJbmZpbml0eSkge1xuICAgICAgICAgICAgdGhpcy5fZXZlbnQubG9vcCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9ldmVudC5sb29wID0gaXRlcnM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9ldmVudC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxvb3AuanMubWFwIiwiaW1wb3J0IHsgVGlja3NDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVGlja3NcIjtcbmltcG9ydCB7IFRyYW5zcG9ydFRpbWVDbGFzcyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvVHJhbnNwb3J0VGltZVwiO1xuaW1wb3J0IHsgZGVmYXVsdEFyZywgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTdGF0ZVRpbWVsaW5lIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9TdGF0ZVRpbWVsaW5lXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc0RlZmluZWQsIGlzT2JqZWN0LCBpc1VuZGVmIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9UeXBlQ2hlY2tcIjtcbmltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLyoqXG4gKiBQYXJ0IGlzIGEgY29sbGVjdGlvbiBUb25lRXZlbnRzIHdoaWNoIGNhbiBiZSBzdGFydGVkL3N0b3BwZWQgYW5kIGxvb3BlZCBhcyBhIHNpbmdsZSB1bml0LlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKCh0aW1lLCBub3RlKSA9PiB7XG4gKiBcdC8vIHRoZSBub3RlcyBnaXZlbiBhcyB0aGUgc2Vjb25kIGVsZW1lbnQgaW4gdGhlIGFycmF5XG4gKiBcdC8vIHdpbGwgYmUgcGFzc2VkIGluIGFzIHRoZSBzZWNvbmQgYXJndW1lbnRcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgXCI4blwiLCB0aW1lKTtcbiAqIH0pLCBbWzAsIFwiQzJcIl0sIFtcIjA6MlwiLCBcIkMzXCJdLCBbXCIwOjM6MlwiLCBcIkcyXCJdXSk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGV4YW1wbGVcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyB1c2UgYW4gYXJyYXkgb2Ygb2JqZWN0cyBhcyBsb25nIGFzIHRoZSBvYmplY3QgaGFzIGEgXCJ0aW1lXCIgYXR0cmlidXRlXG4gKiBjb25zdCBwYXJ0ID0gbmV3IFRvbmUuUGFydCgoKHRpbWUsIHZhbHVlKSA9PiB7XG4gKiBcdC8vIHRoZSB2YWx1ZSBpcyBhbiBvYmplY3Qgd2hpY2ggY29udGFpbnMgYm90aCB0aGUgbm90ZSBhbmQgdGhlIHZlbG9jaXR5XG4gKiBcdHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKHZhbHVlLm5vdGUsIFwiOG5cIiwgdGltZSwgdmFsdWUudmVsb2NpdHkpO1xuICogfSksIFt7IHRpbWU6IDAsIG5vdGU6IFwiQzNcIiwgdmVsb2NpdHk6IDAuOSB9LFxuICogXHR7IHRpbWU6IFwiMDoyXCIsIG5vdGU6IFwiQzRcIiwgdmVsb2NpdHk6IDAuNSB9XG4gKiBdKS5zdGFydCgwKTtcbiAqIFRvbmUuVHJhbnNwb3J0LnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRXZlbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhcnQgZXh0ZW5kcyBUb25lRXZlbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXJ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXJ0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUcmFja3MgdGhlIHNjaGVkdWxlZCBldmVudHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3N0YXRlID0gbmV3IFN0YXRlVGltZWxpbmUoXCJzdG9wcGVkXCIpO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGV2ZW50cyB0aGF0IGJlbG9uZyB0byB0aGlzIHBhcnRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBTZXQoKTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhcnQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiXSk7XG4gICAgICAgIC8vIG1ha2Ugc3VyZSB0aGluZ3MgYXJlIGFzc2lnbmVkIGluIHRoZSByaWdodCBvcmRlclxuICAgICAgICB0aGlzLl9zdGF0ZS5pbmNyZWFzaW5nID0gdHJ1ZTtcbiAgICAgICAgLy8gYWRkIHRoZSBldmVudHNcbiAgICAgICAgb3B0aW9ucy5ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBcnJheShldmVudCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZChldmVudFswXSwgZXZlbnRbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQoZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lRXZlbnQuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZXZlbnRzOiBbXSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgICBXaGVuIHRvIHN0YXJ0IHRoZSBwYXJ0LlxuICAgICAqIEBwYXJhbSAgb2Zmc2V0ICBUaGUgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBwYXJ0IHRvIGJlZ2luIHBsYXlpbmcgYXQuXG4gICAgICovXG4gICAgc3RhcnQodGltZSwgb2Zmc2V0KSB7XG4gICAgICAgIGNvbnN0IHRpY2tzID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICBpZiAodGhpcy5fc3RhdGUuZ2V0VmFsdWVBdFRpbWUodGlja3MpICE9PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3AgPyB0aGlzLl9sb29wU3RhcnQgOiAwKTtcbiAgICAgICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gZGVmYXVsdEFyZyhvZmZzZXQsIHRoaXMuX2xvb3BTdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBkZWZhdWx0QXJnKG9mZnNldCwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBjb21wdXRlZE9mZnNldCA9IHRoaXMudG9UaWNrcyhvZmZzZXQpO1xuICAgICAgICAgICAgdGhpcy5fc3RhdGUuYWRkKHtcbiAgICAgICAgICAgICAgICBpZDogLTEsXG4gICAgICAgICAgICAgICAgb2Zmc2V0OiBjb21wdXRlZE9mZnNldCxcbiAgICAgICAgICAgICAgICBzdGF0ZTogXCJzdGFydGVkXCIsXG4gICAgICAgICAgICAgICAgdGltZTogdGlja3MsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIGNvbXB1dGVkT2Zmc2V0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGFydCB0aGUgZXZlbnQgaW4gdGhlIGdpdmVuIGV2ZW50IGF0IHRoZSBjb3JyZWN0IHRpbWUgZ2l2ZW5cbiAgICAgKiB0aGUgdGlja3MgYW5kIG9mZnNldCBhbmQgbG9vcGluZy5cbiAgICAgKiBAcGFyYW0gIGV2ZW50XG4gICAgICogQHBhcmFtICB0aWNrc1xuICAgICAqIEBwYXJhbSAgb2Zmc2V0XG4gICAgICovXG4gICAgX3N0YXJ0Tm90ZShldmVudCwgdGlja3MsIG9mZnNldCkge1xuICAgICAgICB0aWNrcyAtPSBvZmZzZXQ7XG4gICAgICAgIGlmICh0aGlzLl9sb29wKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPj0gdGhpcy5fbG9vcFN0YXJ0ICYmIGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcEVuZCkge1xuICAgICAgICAgICAgICAgIGlmIChldmVudC5zdGFydE9mZnNldCA8IG9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBzdGFydCBpdCBvbiB0aGUgbmV4dCBsb29wXG4gICAgICAgICAgICAgICAgICAgIHRpY2tzICs9IHRoaXMuX2dldExvb3BEdXJhdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBldmVudC5zdGFydChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRpY2tzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChldmVudC5zdGFydE9mZnNldCA8IHRoaXMuX2xvb3BTdGFydCAmJiBldmVudC5zdGFydE9mZnNldCA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICBldmVudC5sb29wID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV2ZW50LnN0YXJ0T2Zmc2V0ID49IG9mZnNldCkge1xuICAgICAgICAgICAgZXZlbnQuc3RhcnQobmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCB0aWNrcykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBzdGFydE9mZnNldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQob2Zmc2V0KSB7XG4gICAgICAgIHRoaXMuX3N0YXJ0T2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICB0aGlzLl9mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgIGV2ZW50LnN0YXJ0T2Zmc2V0ICs9IHRoaXMuX3N0YXJ0T2Zmc2V0O1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcGFydCBhdCB0aGUgZ2l2ZW4gdGltZS5cbiAgICAgKiBAcGFyYW0gIHRpbWUgIFdoZW4gdG8gc3RvcCB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBzdG9wKHRpbWUpIHtcbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aWNrcyk7XG4gICAgICAgIHRoaXMuX3N0YXRlLnNldFN0YXRlQXRUaW1lKFwic3RvcHBlZFwiLCB0aWNrcyk7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnQuc3RvcCh0aW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQvU2V0IGFuIEV2ZW50J3MgdmFsdWUgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW4gYW5kIG5vIGV2ZW50IGV4aXN0cyBhdFxuICAgICAqIHRoZSBnaXZlbiB0aW1lLCBvbmUgd2lsbCBiZSBjcmVhdGVkIHdpdGggdGhhdCB2YWx1ZS5cbiAgICAgKiBJZiB0d28gZXZlbnRzIGFyZSBhdCB0aGUgc2FtZSB0aW1lLCB0aGUgZmlyc3Qgb25lIHdpbGxcbiAgICAgKiBiZSByZXR1cm5lZC5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBhcnQgPSBuZXcgVG9uZS5QYXJ0KCk7XG4gICAgICogcGFydC5hdChcIjFtXCIpOyAvLyByZXR1cm5zIHRoZSBwYXJ0IGF0IHRoZSBmaXJzdCBtZWFzdXJlXG4gICAgICogcGFydC5hdChcIjJtXCIsIFwiQzJcIik7IC8vIHNldCB0aGUgdmFsdWUgYXQgXCIybVwiIHRvIEMyLlxuICAgICAqIC8vIGlmIGFuIGV2ZW50IGRpZG4ndCBleGlzdCBhdCB0aGF0IHRpbWUsIGl0IHdpbGwgYmUgY3JlYXRlZC5cbiAgICAgKiBAcGFyYW0gdGltZSBUaGUgdGltZSBvZiB0aGUgZXZlbnQgdG8gZ2V0IG9yIHNldC5cbiAgICAgKiBAcGFyYW0gdmFsdWUgSWYgYSB2YWx1ZSBpcyBwYXNzZWQgaW4sIHRoZSB2YWx1ZSBvZiB0aGUgZXZlbnQgYXQgdGhlIGdpdmVuIHRpbWUgd2lsbCBiZSBzZXQgdG8gaXQuXG4gICAgICovXG4gICAgYXQodGltZSwgdmFsdWUpIHtcbiAgICAgICAgY29uc3QgdGltZUluVGlja3MgPSBuZXcgVHJhbnNwb3J0VGltZUNsYXNzKHRoaXMuY29udGV4dCwgdGltZSkudG9UaWNrcygpO1xuICAgICAgICBjb25zdCB0aWNrVGltZSA9IG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgMSkudG9TZWNvbmRzKCk7XG4gICAgICAgIGNvbnN0IGl0ZXJhdG9yID0gdGhpcy5fZXZlbnRzLnZhbHVlcygpO1xuICAgICAgICBsZXQgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICB3aGlsZSAoIXJlc3VsdC5kb25lKSB7XG4gICAgICAgICAgICBjb25zdCBldmVudCA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyh0aW1lSW5UaWNrcyAtIGV2ZW50LnN0YXJ0T2Zmc2V0KSA8IHRpY2tUaW1lKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0ID0gaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHRoZXJlIHdhcyBubyBldmVudCBhdCB0aGF0IHRpbWUsIGNyZWF0ZSBvbmVcbiAgICAgICAgaWYgKGlzRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIC8vIHJldHVybiB0aGUgbmV3IGV2ZW50XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hdCh0aW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZCh0aW1lLCB2YWx1ZSkge1xuICAgICAgICAvLyBleHRyYWN0IHRoZSBwYXJhbWV0ZXJzXG4gICAgICAgIGlmICh0aW1lIGluc3RhbmNlb2YgT2JqZWN0ICYmIFJlZmxlY3QuaGFzKHRpbWUsIFwidGltZVwiKSkge1xuICAgICAgICAgICAgdmFsdWUgPSB0aW1lO1xuICAgICAgICAgICAgdGltZSA9IHZhbHVlLnRpbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGlja3MgPSB0aGlzLnRvVGlja3ModGltZSk7XG4gICAgICAgIGxldCBldmVudDtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVG9uZUV2ZW50KSB7XG4gICAgICAgICAgICBldmVudCA9IHZhbHVlO1xuICAgICAgICAgICAgZXZlbnQuY2FsbGJhY2sgPSB0aGlzLl90aWNrLmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBldmVudCA9IG5ldyBUb25lRXZlbnQoe1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLl90aWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGhlIHN0YXJ0IG9mZnNldFxuICAgICAgICBldmVudC5zdGFydE9mZnNldCA9IHRpY2tzO1xuICAgICAgICAvLyBpbml0aWFsaXplIHRoZSB2YWx1ZXNcbiAgICAgICAgZXZlbnQuc2V0KHtcbiAgICAgICAgICAgIGh1bWFuaXplOiB0aGlzLmh1bWFuaXplLFxuICAgICAgICAgICAgbG9vcDogdGhpcy5sb29wLFxuICAgICAgICAgICAgbG9vcEVuZDogdGhpcy5sb29wRW5kLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiB0aGlzLmxvb3BTdGFydCxcbiAgICAgICAgICAgIHBsYXliYWNrUmF0ZTogdGhpcy5wbGF5YmFja1JhdGUsXG4gICAgICAgICAgICBwcm9iYWJpbGl0eTogdGhpcy5wcm9iYWJpbGl0eSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2V2ZW50cy5hZGQoZXZlbnQpO1xuICAgICAgICAvLyBzdGFydCB0aGUgbm90ZSBpZiBpdCBzaG91bGQgYmUgcGxheWVkIHJpZ2h0IG5vd1xuICAgICAgICB0aGlzLl9yZXN0YXJ0RXZlbnQoZXZlbnQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVzdGFydCB0aGUgZ2l2ZW4gZXZlbnRcbiAgICAgKi9cbiAgICBfcmVzdGFydEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIHRoaXMuX3N0YXRlLmZvckVhY2goKHN0YXRlRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChzdGF0ZUV2ZW50LnN0YXRlID09PSBcInN0YXJ0ZWRcIikge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXJ0Tm90ZShldmVudCwgc3RhdGVFdmVudC50aW1lLCBzdGF0ZUV2ZW50Lm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBzdG9wIHRoZSBub3RlXG4gICAgICAgICAgICAgICAgZXZlbnQuc3RvcChuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHN0YXRlRXZlbnQudGltZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVtb3ZlKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIC8vIGV4dHJhY3QgdGhlIHBhcmFtZXRlcnNcbiAgICAgICAgaWYgKGlzT2JqZWN0KHRpbWUpICYmIHRpbWUuaGFzT3duUHJvcGVydHkoXCJ0aW1lXCIpKSB7XG4gICAgICAgICAgICB2YWx1ZSA9IHRpbWU7XG4gICAgICAgICAgICB0aW1lID0gdmFsdWUudGltZTtcbiAgICAgICAgfVxuICAgICAgICB0aW1lID0gdGhpcy50b1RpY2tzKHRpbWUpO1xuICAgICAgICB0aGlzLl9ldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuc3RhcnRPZmZzZXQgPT09IHRpbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNVbmRlZih2YWx1ZSkgfHwgKGlzRGVmaW5lZCh2YWx1ZSkgJiYgZXZlbnQudmFsdWUgPT09IHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9ldmVudHMuZGVsZXRlKGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgYWxsIG9mIHRoZSBub3RlcyBmcm9tIHRoZSBncm91cC5cbiAgICAgKi9cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiBldmVudC5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLl9ldmVudHMuY2xlYXIoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENhbmNlbCBzY2hlZHVsZWQgc3RhdGUgY2hhbmdlIGV2ZW50czogaS5lLiBcInN0YXJ0XCIgYW5kIFwic3RvcFwiLlxuICAgICAqIEBwYXJhbSBhZnRlciBUaGUgdGltZSBhZnRlciB3aGljaCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBldmVudHMuXG4gICAgICovXG4gICAgY2FuY2VsKGFmdGVyKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4gZXZlbnQuY2FuY2VsKGFmdGVyKSk7XG4gICAgICAgIHRoaXMuX3N0YXRlLmNhbmNlbCh0aGlzLnRvVGlja3MoYWZ0ZXIpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEl0ZXJhdGUgb3ZlciBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIF9mb3JFYWNoKGNhbGxiYWNrKSB7XG4gICAgICAgIGlmICh0aGlzLl9ldmVudHMpIHtcbiAgICAgICAgICAgIHRoaXMuX2V2ZW50cy5mb3JFYWNoKGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBQYXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Ll9mb3JFYWNoKGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKGV2ZW50KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBhdHRyaWJ1dGUgb2YgYWxsIG9mIHRoZSBldmVudHNcbiAgICAgKiBAcGFyYW0gIGF0dHIgIHRoZSBhdHRyaWJ1dGUgdG8gc2V0XG4gICAgICogQHBhcmFtICB2YWx1ZSAgICAgIFRoZSB2YWx1ZSB0byBzZXQgaXQgdG9cbiAgICAgKi9cbiAgICBfc2V0QWxsKGF0dHIsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgZXZlbnRbYXR0cl0gPSB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHRpY2sgbWV0aG9kXG4gICAgICogQHBhcmFtICB0aW1lICBUaGUgdGltZSBvZiB0aGUgZXZlbnQgaW4gc2Vjb25kc1xuICAgICAqL1xuICAgIF90aWNrKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICghdGhpcy5tdXRlKSB7XG4gICAgICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIGV2ZW50IHNob3VsZCBiZSBjdXJyZW50bHkgbG9vcGluZ1xuICAgICAqIGdpdmVuIHRoZSBsb29wIGJvdW5kcmllcyBvZiB0aGlzIFBhcnQuXG4gICAgICogQHBhcmFtICBldmVudCAgVGhlIGV2ZW50IHRvIHRlc3RcbiAgICAgKi9cbiAgICBfdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3AgJiYgKGV2ZW50LnN0YXJ0T2Zmc2V0IDwgdGhpcy5fbG9vcFN0YXJ0IHx8IGV2ZW50LnN0YXJ0T2Zmc2V0ID49IHRoaXMuX2xvb3BFbmQpKSB7XG4gICAgICAgICAgICBldmVudC5jYW5jZWwoMCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXZlbnQuc3RhdGUgPT09IFwic3RvcHBlZFwiKSB7XG4gICAgICAgICAgICAvLyByZXNjaGVkdWxlIGl0IGlmIGl0J3Mgc3RvcHBlZFxuICAgICAgICAgICAgdGhpcy5fcmVzdGFydEV2ZW50KGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgcHJvYmFiaWxpdHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcm9iYWJpbGl0eTtcbiAgICB9XG4gICAgc2V0IHByb2JhYmlsaXR5KHByb2IpIHtcbiAgICAgICAgdGhpcy5fcHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgICAgICB0aGlzLl9zZXRBbGwoXCJwcm9iYWJpbGl0eVwiLCBwcm9iKTtcbiAgICB9XG4gICAgZ2V0IGh1bWFuaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faHVtYW5pemU7XG4gICAgfVxuICAgIHNldCBodW1hbml6ZSh2YXJpYXRpb24pIHtcbiAgICAgICAgdGhpcy5faHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgICAgIHRoaXMuX3NldEFsbChcImh1bWFuaXplXCIsIHZhcmlhdGlvbik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBwYXJ0IHNob3VsZCBsb29wIG9yIG5vdFxuICAgICAqIGJldHdlZW4gUGFydC5sb29wU3RhcnQgYW5kXG4gICAgICogUGFydC5sb29wRW5kLiBJZiBzZXQgdG8gdHJ1ZSxcbiAgICAgKiB0aGUgcGFydCB3aWxsIGxvb3AgaW5kZWZpbml0ZWx5LFxuICAgICAqIGlmIHNldCB0byBhIG51bWJlciBncmVhdGVyIHRoYW4gMVxuICAgICAqIGl0IHdpbGwgcGxheSBhIHNwZWNpZmljIG51bWJlciBvZlxuICAgICAqIHRpbWVzLCBpZiBzZXQgdG8gZmFsc2UsIDAgb3IgMSwgdGhlXG4gICAgICogcGFydCB3aWxsIG9ubHkgcGxheSBvbmNlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgcGFydCA9IG5ldyBUb25lLlBhcnQoKTtcbiAgICAgKiAvLyBsb29wIHRoZSBwYXJ0IDggdGltZXNcbiAgICAgKiBwYXJ0Lmxvb3AgPSA4O1xuICAgICAqL1xuICAgIGdldCBsb29wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobG9vcCkge1xuICAgICAgICB0aGlzLl9sb29wID0gbG9vcDtcbiAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICBldmVudC5sb29wU3RhcnQgPSB0aGlzLmxvb3BTdGFydDtcbiAgICAgICAgICAgIGV2ZW50Lmxvb3BFbmQgPSB0aGlzLmxvb3BFbmQ7XG4gICAgICAgICAgICBldmVudC5sb29wID0gbG9vcDtcbiAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wRW5kIHBvaW50IGRldGVybWluZXMgd2hlbiBpdCB3aWxsXG4gICAgICogbG9vcCBpZiBQYXJ0Lmxvb3AgaXMgdHJ1ZS5cbiAgICAgKi9cbiAgICBnZXQgbG9vcEVuZCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUaWNrc0NsYXNzKHRoaXMuY29udGV4dCwgdGhpcy5fbG9vcEVuZCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wRW5kKGxvb3BFbmQpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IHRoaXMudG9UaWNrcyhsb29wRW5kKTtcbiAgICAgICAgaWYgKHRoaXMuX2xvb3ApIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50Lmxvb3BFbmQgPSBsb29wRW5kO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Rlc3RMb29wQm91bmRyaWVzKGV2ZW50KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBsb29wU3RhcnQgcG9pbnQgZGV0ZXJtaW5lcyB3aGVuIGl0IHdpbGxcbiAgICAgKiBsb29wIGlmIFBhcnQubG9vcCBpcyB0cnVlLlxuICAgICAqL1xuICAgIGdldCBsb29wU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX2xvb3BTdGFydCkudG9TZWNvbmRzKCk7XG4gICAgfVxuICAgIHNldCBsb29wU3RhcnQobG9vcFN0YXJ0KSB7XG4gICAgICAgIHRoaXMuX2xvb3BTdGFydCA9IHRoaXMudG9UaWNrcyhsb29wU3RhcnQpO1xuICAgICAgICBpZiAodGhpcy5fbG9vcCkge1xuICAgICAgICAgICAgdGhpcy5fZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgZXZlbnQubG9vcFN0YXJ0ID0gdGhpcy5sb29wU3RhcnQ7XG4gICAgICAgICAgICAgICAgdGhpcy5fdGVzdExvb3BCb3VuZHJpZXMoZXZlbnQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBsYXliYWNrIHJhdGUgb2YgdGhlIHBhcnRcbiAgICAgKi9cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGxheWJhY2tSYXRlO1xuICAgIH1cbiAgICBzZXQgcGxheWJhY2tSYXRlKHJhdGUpIHtcbiAgICAgICAgdGhpcy5fcGxheWJhY2tSYXRlID0gcmF0ZTtcbiAgICAgICAgdGhpcy5fc2V0QWxsKFwicGxheWJhY2tSYXRlXCIsIHJhdGUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIHNjaGVkdWxlZCBub3RlcyBpbiB0aGUgcGFydC5cbiAgICAgKi9cbiAgICBnZXQgbGVuZ3RoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZXZlbnRzLnNpemU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5jbGVhcigpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXJ0LmpzLm1hcCIsImltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IGNsYW1wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9NYXRoXCI7XG4vKipcbiAqIFN0YXJ0IGF0IHRoZSBmaXJzdCB2YWx1ZSBhbmQgZ28gdXAgdG8gdGhlIGxhc3RcbiAqL1xuZnVuY3Rpb24qIHVwUGF0dGVybkdlbih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpbmRleCsrO1xuICAgIH1cbn1cbi8qKlxuICogU3RhcnQgYXQgdGhlIGxhc3QgdmFsdWUgYW5kIGdvIGRvd24gdG8gMFxuICovXG5mdW5jdGlvbiogZG93blBhdHRlcm5HZW4odmFsdWVzKSB7XG4gICAgbGV0IGluZGV4ID0gdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKGluZGV4ID49IDApIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpbmRleC0tO1xuICAgIH1cbn1cbi8qKlxuICogSW5maW5pdGVseSB5aWVsZCB0aGUgZ2VuZXJhdG9yXG4gKi9cbmZ1bmN0aW9uKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGdlbikge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHlpZWxkKiBnZW4odmFsdWVzKTtcbiAgICB9XG59XG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBpbmRleCBpcyBpbiB0aGUgZ2l2ZW4gcmFuZ2VcbiAqL1xuZnVuY3Rpb24gY2xhbXBUb0FycmF5U2l6ZShpbmRleCwgdmFsdWVzKSB7XG4gICAgcmV0dXJuIGNsYW1wKGluZGV4LCAwLCB2YWx1ZXMubGVuZ3RoIC0gMSk7XG59XG4vKipcbiAqIEFsdGVybmF0ZSBiZXR3ZWVuIHR3byBnZW5lcmF0b3JzXG4gKi9cbmZ1bmN0aW9uKiBhbHRlcm5hdGluZ0dlbmVyYXRvcih2YWx1ZXMsIGRpcmVjdGlvblVwKSB7XG4gICAgbGV0IGluZGV4ID0gZGlyZWN0aW9uVXAgPyAwIDogdmFsdWVzLmxlbmd0aCAtIDE7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpZiAoZGlyZWN0aW9uVXApIHtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICBpZiAoaW5kZXggPj0gdmFsdWVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb25VcCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgtLTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgZGlyZWN0aW9uVXAgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBTdGFydGluZyBmcm9tIHRoZSBib3R0b20gbW92ZSB1cCAyLCBkb3duIDFcbiAqL1xuZnVuY3Rpb24qIGp1bXBVcCh2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGxldCBzdGVwSW5kZXggPSAwO1xuICAgIHdoaWxlIChpbmRleCA8IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgaW5kZXggPSBjbGFtcFRvQXJyYXlTaXplKGluZGV4LCB2YWx1ZXMpO1xuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBzdGVwSW5kZXgrKztcbiAgICAgICAgaW5kZXggKz0gKHN0ZXBJbmRleCAlIDIgPyAyIDogLTEpO1xuICAgIH1cbn1cbi8qKlxuICogU3RhcnRpbmcgZnJvbSB0aGUgdG9wIG1vdmUgZG93biAyLCB1cCAxXG4gKi9cbmZ1bmN0aW9uKiBqdW1wRG93bih2YWx1ZXMpIHtcbiAgICBsZXQgaW5kZXggPSB2YWx1ZXMubGVuZ3RoIC0gMTtcbiAgICBsZXQgc3RlcEluZGV4ID0gMDtcbiAgICB3aGlsZSAoaW5kZXggPj0gMCkge1xuICAgICAgICBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUoaW5kZXgsIHZhbHVlcyk7XG4gICAgICAgIHlpZWxkIHZhbHVlc1tpbmRleF07XG4gICAgICAgIHN0ZXBJbmRleCsrO1xuICAgICAgICBpbmRleCArPSAoc3RlcEluZGV4ICUgMiA/IC0yIDogMSk7XG4gICAgfVxufVxuLyoqXG4gKiBDaG9vc2UgYSByYW5kb20gaW5kZXggZWFjaCB0aW1lXG4gKi9cbmZ1bmN0aW9uKiByYW5kb21HZW4odmFsdWVzKSB7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgY29uc3QgcmFuZG9tSW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB2YWx1ZXMubGVuZ3RoKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW3JhbmRvbUluZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFJhbmRvbWx5IGdvIHRocm91Z2ggYWxsIG9mIHRoZSB2YWx1ZXMgb25jZSBiZWZvcmUgY2hvb3NpbmcgYSBuZXcgcmFuZG9tIG9yZGVyXG4gKi9cbmZ1bmN0aW9uKiByYW5kb21PbmNlKHZhbHVlcykge1xuICAgIC8vIGNyZWF0ZSBhbiBhcnJheSBvZiBpbmRpY2VzXG4gICAgY29uc3QgY29weSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvcHkucHVzaChpKTtcbiAgICB9XG4gICAgd2hpbGUgKGNvcHkubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyByYW5kb20gY2hvb3NlIGFuIGluZGV4LCBhbmQgdGhlbiByZW1vdmUgaXQgc28gaXQncyBub3QgY2hvc2VuIGFnYWluXG4gICAgICAgIGNvbnN0IHJhbmRWYWwgPSBjb3B5LnNwbGljZShNYXRoLmZsb29yKGNvcHkubGVuZ3RoICogTWF0aC5yYW5kb20oKSksIDEpO1xuICAgICAgICBjb25zdCBpbmRleCA9IGNsYW1wVG9BcnJheVNpemUocmFuZFZhbFswXSwgdmFsdWVzKTtcbiAgICAgICAgeWllbGQgdmFsdWVzW2luZGV4XTtcbiAgICB9XG59XG4vKipcbiAqIFJhbmRvbWx5IGNob29zZSB0byB3YWxrIHVwIG9yIGRvd24gMSBpbmRleCBpbiB0aGUgdmFsdWVzIGFycmF5XG4gKi9cbmZ1bmN0aW9uKiByYW5kb21XYWxrKHZhbHVlcykge1xuICAgIC8vIHJhbmRvbWx5IGNob29zZSBhIHN0YXJ0aW5nIGluZGV4IGluIHRoZSB2YWx1ZXMgYXJyYXlcbiAgICBsZXQgaW5kZXggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB2YWx1ZXMubGVuZ3RoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIGluZGV4Kys7IC8vIGF0IGJvdHRvbSBvZiBhcnJheSwgc28gZm9yY2UgdXB3YXJkIHN0ZXBcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbmRleCA9PT0gdmFsdWVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIGluZGV4LS07IC8vIGF0IHRvcCBvZiBhcnJheSwgc28gZm9yY2UgZG93bndhcmQgc3RlcFxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKE1hdGgucmFuZG9tKCkgPCAwLjUpIHsgLy8gZWxzZSBjaG9vc2UgcmFuZG9tIGRvd253YXJkIG9yIHVwd2FyZCBzdGVwXG4gICAgICAgICAgICBpbmRleC0tO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICB5aWVsZCB2YWx1ZXNbaW5kZXhdO1xuICAgIH1cbn1cbi8qKlxuICogUGF0dGVybkdlbmVyYXRvciByZXR1cm5zIGEgZ2VuZXJhdG9yIHdoaWNoIHdpbGwgaXRlcmF0ZSBvdmVyIHRoZSBnaXZlbiBhcnJheVxuICogb2YgdmFsdWVzIGFuZCB5aWVsZCB0aGUgaXRlbXMgYWNjb3JkaW5nIHRvIHRoZSBwYXNzZWQgaW4gcGF0dGVyblxuICogQHBhcmFtIHZhbHVlcyBBbiBhcnJheSBvZiB2YWx1ZXMgdG8gaXRlcmF0ZSBvdmVyXG4gKiBAcGFyYW0gcGF0dGVybiBUaGUgbmFtZSBvZiB0aGUgcGF0dGVybiB1c2Ugd2hlbiBpdGVyYXRpbmcgb3ZlclxuICogQHBhcmFtIGluZGV4IFdoZXJlIHRvIHN0YXJ0IGluIHRoZSBvZmZzZXQgb2YgdGhlIHZhbHVlcyBhcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24qIFBhdHRlcm5HZW5lcmF0b3IodmFsdWVzLCBwYXR0ZXJuID0gXCJ1cFwiLCBpbmRleCA9IDApIHtcbiAgICAvLyBzYWZlZ3VhcmRzXG4gICAgYXNzZXJ0KHZhbHVlcy5sZW5ndGggPiAwLCBcIlRoZSBhcnJheSBtdXN0IGhhdmUgbW9yZSB0aGFuIG9uZSB2YWx1ZSBpbiBpdFwiKTtcbiAgICBzd2l0Y2ggKHBhdHRlcm4pIHtcbiAgICAgICAgY2FzZSBcInVwXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCB1cFBhdHRlcm5HZW4pO1xuICAgICAgICBjYXNlIFwiZG93blwiOlxuICAgICAgICAgICAgeWllbGQqIGluZmluaXRlR2VuKHZhbHVlcywgZG93blBhdHRlcm5HZW4pO1xuICAgICAgICBjYXNlIFwidXBEb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogYWx0ZXJuYXRpbmdHZW5lcmF0b3IodmFsdWVzLCB0cnVlKTtcbiAgICAgICAgY2FzZSBcImRvd25VcFwiOlxuICAgICAgICAgICAgeWllbGQqIGFsdGVybmF0aW5nR2VuZXJhdG9yKHZhbHVlcywgZmFsc2UpO1xuICAgICAgICBjYXNlIFwiYWx0ZXJuYXRlVXBcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIGp1bXBVcCk7XG4gICAgICAgIGNhc2UgXCJhbHRlcm5hdGVEb3duXCI6XG4gICAgICAgICAgICB5aWVsZCogaW5maW5pdGVHZW4odmFsdWVzLCBqdW1wRG93bik7XG4gICAgICAgIGNhc2UgXCJyYW5kb21cIjpcbiAgICAgICAgICAgIHlpZWxkKiByYW5kb21HZW4odmFsdWVzKTtcbiAgICAgICAgY2FzZSBcInJhbmRvbU9uY2VcIjpcbiAgICAgICAgICAgIHlpZWxkKiBpbmZpbml0ZUdlbih2YWx1ZXMsIHJhbmRvbU9uY2UpO1xuICAgICAgICBjYXNlIFwicmFuZG9tV2Fsa1wiOlxuICAgICAgICAgICAgeWllbGQqIHJhbmRvbVdhbGsodmFsdWVzKTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYXR0ZXJuR2VuZXJhdG9yLmpzLm1hcCIsImltcG9ydCB7IExvb3AgfSBmcm9tIFwiLi9Mb29wXCI7XG5pbXBvcnQgeyBQYXR0ZXJuR2VuZXJhdG9yIH0gZnJvbSBcIi4vUGF0dGVybkdlbmVyYXRvclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogUGF0dGVybiBhcnBlZ2dpYXRlcyBiZXR3ZWVuIHRoZSBnaXZlbiBub3Rlc1xuICogaW4gYSBudW1iZXIgb2YgcGF0dGVybnMuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcGF0dGVybiA9IG5ldyBUb25lLlBhdHRlcm4oKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0Ly8gdGhlIG9yZGVyIG9mIHRoZSBub3RlcyBwYXNzZWQgaW4gZGVwZW5kcyBvbiB0aGUgcGF0dGVyblxuICogfSwgW1wiQzJcIiwgXCJENFwiLCBcIkU1XCIsIFwiQTZcIl0sIFwidXBEb3duXCIpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYXR0ZXJuIGV4dGVuZHMgTG9vcCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhdHRlcm4uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcInZhbHVlc1wiLCBcInBhdHRlcm5cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQYXR0ZXJuXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYXR0ZXJuLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJ2YWx1ZXNcIiwgXCJwYXR0ZXJuXCJdKTtcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IG9wdGlvbnMuY2FsbGJhY2s7XG4gICAgICAgIHRoaXMuX3ZhbHVlcyA9IG9wdGlvbnMudmFsdWVzO1xuICAgICAgICB0aGlzLl9wYXR0ZXJuID0gUGF0dGVybkdlbmVyYXRvcihvcHRpb25zLnZhbHVlcywgb3B0aW9ucy5wYXR0ZXJuKTtcbiAgICAgICAgdGhpcy5fdHlwZSA9IG9wdGlvbnMucGF0dGVybjtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMb29wLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhdHRlcm46IFwidXBcIixcbiAgICAgICAgICAgIHZhbHVlczogW10sXG4gICAgICAgICAgICBjYWxsYmFjazogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEludGVybmFsIGZ1bmN0aW9uIGNhbGxlZCB3aGVuIHRoZSBub3RlcyBzaG91bGQgYmUgY2FsbGVkXG4gICAgICovXG4gICAgX3RpY2sodGltZSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3BhdHRlcm4ubmV4dCgpO1xuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlLnZhbHVlO1xuICAgICAgICB0aGlzLmNhbGxiYWNrKHRpbWUsIHRoaXMuX3ZhbHVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFycmF5IG9mIGV2ZW50cy5cbiAgICAgKi9cbiAgICBnZXQgdmFsdWVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdmFsdWVzO1xuICAgIH1cbiAgICBzZXQgdmFsdWVzKHZhbCkge1xuICAgICAgICB0aGlzLl92YWx1ZXMgPSB2YWw7XG4gICAgICAgIC8vIHJlc2V0IHRoZSBwYXR0ZXJuXG4gICAgICAgIHRoaXMucGF0dGVybiA9IHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBwYXR0ZXJuLlxuICAgICAqL1xuICAgIGdldCB2YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgcGF0dGVybiB0eXBlLiBTZWUgVG9uZS5DdHJsUGF0dGVybiBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBwYXR0ZXJucy5cbiAgICAgKi9cbiAgICBnZXQgcGF0dGVybigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCBwYXR0ZXJuKHBhdHRlcm4pIHtcbiAgICAgICAgdGhpcy5fdHlwZSA9IHBhdHRlcm47XG4gICAgICAgIHRoaXMuX3BhdHRlcm4gPSBQYXR0ZXJuR2VuZXJhdG9yKHRoaXMuX3ZhbHVlcywgdGhpcy5fdHlwZSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGF0dGVybi5qcy5tYXAiLCJpbXBvcnQgeyBUaWNrc0NsYXNzIH0gZnJvbSBcIi4uL2NvcmUvdHlwZS9UaWNrc1wiO1xuaW1wb3J0IHsgb21pdEZyb21PYmplY3QsIG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vY29yZS91dGlsL1R5cGVDaGVja1wiO1xuaW1wb3J0IHsgUGFydCB9IGZyb20gXCIuL1BhcnRcIjtcbmltcG9ydCB7IFRvbmVFdmVudCB9IGZyb20gXCIuL1RvbmVFdmVudFwiO1xuLyoqXG4gKiBBIHNlcXVlbmNlIGlzIGFuIGFsdGVybmF0ZSBub3RhdGlvbiBvZiBhIHBhcnQuIEluc3RlYWRcbiAqIG9mIHBhc3NpbmcgaW4gYW4gYXJyYXkgb2YgW3RpbWUsIGV2ZW50XSBwYWlycywgcGFzc1xuICogaW4gYW4gYXJyYXkgb2YgZXZlbnRzIHdoaWNoIHdpbGwgYmUgc3BhY2VkIGF0IHRoZVxuICogZ2l2ZW4gc3ViZGl2aXNpb24uIFN1Yi1hcnJheXMgd2lsbCBzdWJkaXZpZGUgdGhhdCBiZWF0XG4gKiBieSB0aGUgbnVtYmVyIG9mIGl0ZW1zIGFyZSBpbiB0aGUgYXJyYXkuXG4gKiBTZXF1ZW5jZSBub3RhdGlvbiBpbnNwaXJhdGlvbiBmcm9tIFtUaWRhbF0oaHR0cDovL3lheHUub3JnL3RpZGFsLylcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgc2VxID0gbmV3IFRvbmUuU2VxdWVuY2UoKHRpbWUsIG5vdGUpID0+IHtcbiAqIFx0c3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2Uobm90ZSwgMC4xLCB0aW1lKTtcbiAqIFx0Ly8gc3ViZGl2aXNpb25zIGFyZSBnaXZlbiBhcyBzdWJhcnJheXNcbiAqIH0sIFtcIkM0XCIsIFtcIkU0XCIsIFwiRDRcIiwgXCJFNFwiXSwgXCJHNFwiLCBbXCJBNFwiLCBcIkc0XCJdXSkuc3RhcnQoMCk7XG4gKiBUb25lLlRyYW5zcG9ydC5zdGFydCgpO1xuICogQGNhdGVnb3J5IEV2ZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXF1ZW5jZSBleHRlbmRzIFRvbmVFdmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFNlcXVlbmNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2FsbGJhY2tcIiwgXCJldmVudHNcIiwgXCJzdWJkaXZpc2lvblwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlNlcXVlbmNlXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgb2JqZWN0IHJlc3BvbnNpYmxlIGZvciBzY2hlZHVsaW5nIGFsbCBvZiB0aGUgZXZlbnRzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9wYXJ0ID0gbmV3IFBhcnQoe1xuICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMuX3NlcUNhbGxiYWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogcHJpdmF0ZSByZWZlcmVuY2UgdG8gYWxsIG9mIHRoZSBzZXF1ZW5jZSBwcm94aWVzXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwcm94aWVkIGFycmF5XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ldmVudHNBcnJheSA9IFtdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoU2VxdWVuY2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjYWxsYmFja1wiLCBcImV2ZW50c1wiLCBcInN1YmRpdmlzaW9uXCJdKTtcbiAgICAgICAgdGhpcy5fc3ViZGl2aXNpb24gPSB0aGlzLnRvVGlja3Mob3B0aW9ucy5zdWJkaXZpc2lvbik7XG4gICAgICAgIHRoaXMuZXZlbnRzID0gb3B0aW9ucy5ldmVudHM7XG4gICAgICAgIC8vIHNldCBhbGwgb2YgdGhlIHZhbHVlc1xuICAgICAgICB0aGlzLmxvb3AgPSBvcHRpb25zLmxvb3A7XG4gICAgICAgIHRoaXMubG9vcFN0YXJ0ID0gb3B0aW9ucy5sb29wU3RhcnQ7XG4gICAgICAgIHRoaXMubG9vcEVuZCA9IG9wdGlvbnMubG9vcEVuZDtcbiAgICAgICAgdGhpcy5wbGF5YmFja1JhdGUgPSBvcHRpb25zLnBsYXliYWNrUmF0ZTtcbiAgICAgICAgdGhpcy5wcm9iYWJpbGl0eSA9IG9wdGlvbnMucHJvYmFiaWxpdHk7XG4gICAgICAgIHRoaXMuaHVtYW5pemUgPSBvcHRpb25zLmh1bWFuaXplO1xuICAgICAgICB0aGlzLm11dGUgPSBvcHRpb25zLm11dGU7XG4gICAgICAgIHRoaXMucGxheWJhY2tSYXRlID0gb3B0aW9ucy5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ob21pdEZyb21PYmplY3QoVG9uZUV2ZW50LmdldERlZmF1bHRzKCksIFtcInZhbHVlXCJdKSwge1xuICAgICAgICAgICAgZXZlbnRzOiBbXSxcbiAgICAgICAgICAgIGxvb3A6IHRydWUsXG4gICAgICAgICAgICBsb29wRW5kOiAwLFxuICAgICAgICAgICAgbG9vcFN0YXJ0OiAwLFxuICAgICAgICAgICAgc3ViZGl2aXNpb246IFwiOG5cIixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlcm5hbCBjYWxsYmFjayBmb3Igd2hlbiBhbiBldmVudCBpcyBpbnZva2VkXG4gICAgICovXG4gICAgX3NlcUNhbGxiYWNrKHRpbWUsIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhpcy5jYWxsYmFjayh0aW1lLCB2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNlcXVlbmNlXG4gICAgICovXG4gICAgZ2V0IGV2ZW50cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50cztcbiAgICB9XG4gICAgc2V0IGV2ZW50cyhzKSB7XG4gICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZXZlbnRzQXJyYXkgPSBzO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSB0aGlzLl9jcmVhdGVTZXF1ZW5jZSh0aGlzLl9ldmVudHNBcnJheSk7XG4gICAgICAgIHRoaXMuX2V2ZW50c1VwZGF0ZWQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIHBhcnQgYXQgdGhlIGdpdmVuIHRpbWUuXG4gICAgICogQHBhcmFtICB0aW1lICAgIFdoZW4gdG8gc3RhcnQgdGhlIHBhcnQuXG4gICAgICogQHBhcmFtICBvZmZzZXQgIFRoZSBvZmZzZXQgaW5kZXggdG8gc3RhcnQgYXRcbiAgICAgKi9cbiAgICBzdGFydCh0aW1lLCBvZmZzZXQpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdGFydCh0aW1lLCBvZmZzZXQgPyB0aGlzLl9pbmRleFRpbWUob2Zmc2V0KSA6IG9mZnNldCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIHRoZSBwYXJ0IGF0IHRoZSBnaXZlbiB0aW1lLlxuICAgICAqIEBwYXJhbSAgdGltZSAgV2hlbiB0byBzdG9wIHRoZSBwYXJ0LlxuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9wYXJ0LnN0b3AodGltZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgc3ViZGl2aXNpb24gb2YgdGhlIHNlcXVlbmNlLiBUaGlzIGNhbiBvbmx5IGJlXG4gICAgICogc2V0IGluIHRoZSBjb25zdHJ1Y3Rvci4gVGhlIHN1YmRpdmlzaW9uIGlzIHRoZVxuICAgICAqIGludGVydmFsIGJldHdlZW4gc3VjY2Vzc2l2ZSBzdGVwcy5cbiAgICAgKi9cbiAgICBnZXQgc3ViZGl2aXNpb24oKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIHRoaXMuX3N1YmRpdmlzaW9uKS50b1NlY29uZHMoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIGEgc2VxdWVuY2UgcHJveHkgd2hpY2ggY2FuIGJlIG1vbml0b3JlZCB0byBjcmVhdGUgc3Vic2VxdWVuY2VzXG4gICAgICovXG4gICAgX2NyZWF0ZVNlcXVlbmNlKGFycmF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoYXJyYXksIHtcbiAgICAgICAgICAgIGdldDogKHRhcmdldCwgcHJvcGVydHkpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBwcm9wZXJ0eSBpcyBpbmRleCBpbiB0aGlzIGNhc2VcbiAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0W3Byb3BlcnR5XTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZXQ6ICh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChpc1N0cmluZyhwcm9wZXJ0eSkgJiYgaXNGaW5pdGUocGFyc2VJbnQocHJvcGVydHksIDEwKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdGhpcy5fY3JlYXRlU2VxdWVuY2UodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W3Byb3BlcnR5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0YXJnZXRbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuX2V2ZW50c1VwZGF0ZWQoKTtcbiAgICAgICAgICAgICAgICAvLyByZXR1cm4gdHJ1ZSB0byBhY2NlcHQgdGhlIGNoYW5nZXNcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBzZXF1ZW5jZSBoYXMgY2hhbmdlZCwgYWxsIG9mIHRoZSBldmVudHMgbmVlZCB0byBiZSByZWNyZWF0ZWRcbiAgICAgKi9cbiAgICBfZXZlbnRzVXBkYXRlZCgpIHtcbiAgICAgICAgdGhpcy5fcGFydC5jbGVhcigpO1xuICAgICAgICB0aGlzLl9yZXNjaGVkdWxlU2VxdWVuY2UodGhpcy5fZXZlbnRzQXJyYXksIHRoaXMuX3N1YmRpdmlzaW9uLCB0aGlzLnN0YXJ0T2Zmc2V0KTtcbiAgICAgICAgLy8gdXBkYXRlIHRoZSBsb29wRW5kXG4gICAgICAgIHRoaXMubG9vcEVuZCA9IHRoaXMubG9vcEVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogcmVzY2hlZHVsZSBhbGwgb2YgdGhlIGV2ZW50cyB0aGF0IG5lZWQgdG8gYmUgcmVzY2hlZHVsZWRcbiAgICAgKi9cbiAgICBfcmVzY2hlZHVsZVNlcXVlbmNlKHNlcXVlbmNlLCBzdWJkaXZpc2lvbiwgc3RhcnRPZmZzZXQpIHtcbiAgICAgICAgc2VxdWVuY2UuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBldmVudE9mZnNldCA9IGluZGV4ICogKHN1YmRpdmlzaW9uKSArIHN0YXJ0T2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVzY2hlZHVsZVNlcXVlbmNlKHZhbHVlLCBzdWJkaXZpc2lvbiAvIHZhbHVlLmxlbmd0aCwgZXZlbnRPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnRUaW1lID0gbmV3IFRpY2tzQ2xhc3ModGhpcy5jb250ZXh0LCBldmVudE9mZnNldCwgXCJpXCIpLnRvU2Vjb25kcygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3BhcnQuYWRkKHN0YXJ0VGltZSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB0aW1lIG9mIHRoZSBpbmRleCBnaXZlbiB0aGUgU2VxdWVuY2UncyBzdWJkaXZpc2lvblxuICAgICAqIEBwYXJhbSAgaW5kZXhcbiAgICAgKiBAcmV0dXJuIFRoZSB0aW1lIG9mIHRoYXQgaW5kZXhcbiAgICAgKi9cbiAgICBfaW5kZXhUaW1lKGluZGV4KSB7XG4gICAgICAgIHJldHVybiBuZXcgVGlja3NDbGFzcyh0aGlzLmNvbnRleHQsIGluZGV4ICogKHRoaXMuX3N1YmRpdmlzaW9uKSArIHRoaXMuc3RhcnRPZmZzZXQpLnRvU2Vjb25kcygpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhciBhbGwgb2YgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLl9wYXJ0LmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BhcnQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gUFJPWFkgQ0FMTFNcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBnZXQgbG9vcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQubG9vcDtcbiAgICB9XG4gICAgc2V0IGxvb3AobCkge1xuICAgICAgICB0aGlzLl9wYXJ0Lmxvb3AgPSBsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIHNlcXVlbmNlIHNob3VsZCBzdGFydCBsb29waW5nXG4gICAgICovXG4gICAgZ2V0IGxvb3BTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvb3BTdGFydDtcbiAgICB9XG4gICAgc2V0IGxvb3BTdGFydChpbmRleCkge1xuICAgICAgICB0aGlzLl9sb29wU3RhcnQgPSBpbmRleDtcbiAgICAgICAgdGhpcy5fcGFydC5sb29wU3RhcnQgPSB0aGlzLl9pbmRleFRpbWUoaW5kZXgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgaW5kZXggYXQgd2hpY2ggdGhlIHNlcXVlbmNlIHNob3VsZCBlbmQgbG9vcGluZ1xuICAgICAqL1xuICAgIGdldCBsb29wRW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbG9vcEVuZDtcbiAgICB9XG4gICAgc2V0IGxvb3BFbmQoaW5kZXgpIHtcbiAgICAgICAgdGhpcy5fbG9vcEVuZCA9IGluZGV4O1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuX3BhcnQubG9vcEVuZCA9IHRoaXMuX2luZGV4VGltZSh0aGlzLl9ldmVudHNBcnJheS5sZW5ndGgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcGFydC5sb29wRW5kID0gdGhpcy5faW5kZXhUaW1lKGluZGV4KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgc3RhcnRPZmZzZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnN0YXJ0T2Zmc2V0O1xuICAgIH1cbiAgICBzZXQgc3RhcnRPZmZzZXQoc3RhcnQpIHtcbiAgICAgICAgdGhpcy5fcGFydC5zdGFydE9mZnNldCA9IHN0YXJ0O1xuICAgIH1cbiAgICBnZXQgcGxheWJhY2tSYXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFydC5wbGF5YmFja1JhdGU7XG4gICAgfVxuICAgIHNldCBwbGF5YmFja1JhdGUocmF0ZSkge1xuICAgICAgICB0aGlzLl9wYXJ0LnBsYXliYWNrUmF0ZSA9IHJhdGU7XG4gICAgfVxuICAgIGdldCBwcm9iYWJpbGl0eSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhcnQucHJvYmFiaWxpdHk7XG4gICAgfVxuICAgIHNldCBwcm9iYWJpbGl0eShwcm9iKSB7XG4gICAgICAgIHRoaXMuX3BhcnQucHJvYmFiaWxpdHkgPSBwcm9iO1xuICAgIH1cbiAgICBnZXQgcHJvZ3Jlc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0LnByb2dyZXNzO1xuICAgIH1cbiAgICBnZXQgaHVtYW5pemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmh1bWFuaXplO1xuICAgIH1cbiAgICBzZXQgaHVtYW5pemUodmFyaWF0aW9uKSB7XG4gICAgICAgIHRoaXMuX3BhcnQuaHVtYW5pemUgPSB2YXJpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygc2NoZWR1bGVkIGV2ZW50c1xuICAgICAqL1xuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYXJ0Lmxlbmd0aDtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TZXF1ZW5jZS5qcy5tYXAiLCJleHBvcnQgKiBmcm9tIFwiLi9Mb29wXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QYXJ0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9QYXR0ZXJuXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TZXF1ZW5jZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vVG9uZUV2ZW50XCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBjb25uZWN0LCBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEdhaW5Ub0F1ZGlvIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9HYWluVG9BdWRpb1wiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9TaWduYWxcIjtcbi8qKlxuICogVG9uZS5Dcm9zc2ZhZGUgcHJvdmlkZXMgZXF1YWwgcG93ZXIgZmFkaW5nIGJldHdlZW4gdHdvIGlucHV0cy5cbiAqIE1vcmUgb24gY3Jvc3NmYWRpbmcgdGVjaG5pcXVlIFtoZXJlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9GYWRlXyhhdWRpb19lbmdpbmVlcmluZykjQ3Jvc3NmYWRpbmcpLlxuICogYGBgXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKz4gaW5wdXQgYSArPi0tK1xuICogKy0tLS0tLS0tLS0tKyAgICstLS0tLS0tLS0tLS0tLS0tLS0tLS0rICAgICB8ICAgICAgICAgfCAgIHxcbiAqIHwgMXMgc2lnbmFsICs+LS0+IHN0ZXJlb1Bhbm5lck5vZGUgIEwgKz4tLS0tPiBnYWluICAgIHwgICB8XG4gKiArLS0tLS0tLS0tLS0rICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICstLS0tLS0tLS0rICAgfFxuICogICAgICAgICAgICAgICArLT4gcGFuICAgICAgICAgICAgICAgUiArPi0rICAgICAgICAgICAgICAgIHwgICArLS0tLS0tLS0rXG4gKiAgICAgICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgIHwgICAgICAgICAgICAgICAgKy0tLT4gb3V0cHV0ICs+XG4gKiAgKy0tLS0tLSsgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICstLS0tLS0tLS0rICAgfCAgICstLS0tLS0tLStcbiAqICB8IGZhZGUgKz4tLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgfCArPiBpbnB1dCBiICs+LS0rXG4gKiAgKy0tLS0tLSsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLT4gZ2FpbiAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tLS0rXG4gKiBgYGBcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBjcm9zc0ZhZGUgPSBuZXcgVG9uZS5Dcm9zc0ZhZGUoKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiAvLyBjb25uZWN0IHR3byBpbnB1dHMgVG9uZS50byBhL2JcbiAqIGNvbnN0IGlucHV0QSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoNDQwLCBcInNxdWFyZVwiKS5jb25uZWN0KGNyb3NzRmFkZS5hKS5zdGFydCgpO1xuICogY29uc3QgaW5wdXRCID0gbmV3IFRvbmUuT3NjaWxsYXRvcig0NDAsIFwic2luZVwiKS5jb25uZWN0KGNyb3NzRmFkZS5iKS5zdGFydCgpO1xuICogLy8gdXNlIHRoZSBmYWRlIHRvIGNvbnRyb2wgdGhlIG1peCBiZXR3ZWVuIHRoZSB0d29cbiAqIGNyb3NzRmFkZS5mYWRlLnZhbHVlID0gMC41O1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ3Jvc3NGYWRlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ3Jvc3NGYWRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZmFkZVwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDcm9zc0ZhZGVcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjcm9zc2ZhZGluZyBpcyBkb25lIGJ5IGEgU3RlcmVvUGFubmVyTm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZVN0ZXJlb1Bhbm5lcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogU3BsaXQgdGhlIG91dHB1dCBvZiB0aGUgcGFubmVyIG5vZGUgaW50byB0d28gdmFsdWVzIHVzZWQgdG8gY29udHJvbCB0aGUgZ2FpbnMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9zcGxpdCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIoMik7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252ZXJ0IHRoZSBmYWRlIHZhbHVlIGludG8gYW4gYXVkaW8gcmFuZ2UgdmFsdWUgc28gaXQgY2FuIGJlIGNvbm5lY3RlZFxuICAgICAgICAgKiB0byB0aGUgcGFubmVyLnBhbiBBdWRpb1BhcmFtXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9nMmEgPSBuZXcgR2FpblRvQXVkaW8oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgaW5wdXQgd2hpY2ggaXMgYXQgZnVsbCBsZXZlbCB3aGVuIGZhZGUgPSAwXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmEgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBpbnB1dCB3aGljaCBpcyBhdCBmdWxsIGxldmVsIHdoZW4gZmFkZSA9IDFcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuYiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IDAsXG4gICAgICAgIH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG91dHB1dCBpcyBhIG1peCBiZXR3ZWVuIGBhYCBhbmQgYGJgIGF0IHRoZSByYXRpbyBvZiBgZmFkZWBcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5hLCB0aGlzLmJdO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ3Jvc3NGYWRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZmFkZVwiXSk7XG4gICAgICAgIHRoaXMuZmFkZSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZhZGUsXG4gICAgICAgIH0pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImZhZGVcIik7XG4gICAgICAgIHRoaXMuY29udGV4dC5nZXRDb25zdGFudCgxKS5jb25uZWN0KHRoaXMuX3Bhbm5lcik7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIHN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XG4gICAgICAgIC8vIGRvZXNuJ3QgbWFrZSBhbnkgZGlmZmVyZW5jZSBmb3IgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2lzc3Vlcy82NDdcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudCA9IDE7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICBjb25uZWN0KHRoaXMuX3NwbGl0LCB0aGlzLmEuZ2FpbiwgMCk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5fc3BsaXQsIHRoaXMuYi5nYWluLCAxKTtcbiAgICAgICAgdGhpcy5mYWRlLmNoYWluKHRoaXMuX2cyYSwgdGhpcy5fcGFubmVyLnBhbik7XG4gICAgICAgIHRoaXMuYS5jb25uZWN0KHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5iLmNvbm5lY3QodGhpcy5vdXRwdXQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZmFkZTogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmFkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2cyYS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Q3Jvc3NGYWRlLmpzLm1hcCIsImltcG9ydCB7IENyb3NzRmFkZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9Dcm9zc0ZhZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogRWZmZWN0IGlzIHRoZSBiYXNlIGNsYXNzIGZvciBlZmZlY3RzLiBDb25uZWN0IHRoZSBlZmZlY3QgYmV0d2VlblxuICogdGhlIGVmZmVjdFNlbmQgYW5kIGVmZmVjdFJldHVybiBHYWluTm9kZXMsIHRoZW4gY29udHJvbCB0aGUgYW1vdW50IG9mXG4gKiBlZmZlY3Qgd2hpY2ggZ29lcyB0byB0aGUgb3V0cHV0IHVzaW5nIHRoZSB3ZXQgY29udHJvbC5cbiAqL1xuZXhwb3J0IGNsYXNzIEVmZmVjdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRWZmZWN0XCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgZHJ5d2V0IGtub2IgdG8gY29udHJvbCB0aGUgYW1vdW50IG9mIGVmZmVjdFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fZHJ5V2V0ID0gbmV3IENyb3NzRmFkZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB3ZXQgY29udHJvbCBpcyBob3cgbXVjaCBvZiB0aGUgZWZmZWN0ZWRcbiAgICAgICAgICogd2lsbCBwYXNzIHRocm91Z2ggdG8gdGhlIG91dHB1dC4gMSA9IDEwMCUgZWZmZWN0ZWRcbiAgICAgICAgICogc2lnbmFsLCAwID0gMTAwJSBkcnkgc2lnbmFsLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy53ZXQgPSB0aGlzLl9kcnlXZXQuZmFkZTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNvbm5lY3QgdGhlIGVmZmVjdFNlbmQgdG8gdGhlIGlucHV0IG9mIGh0ZSBlZmZlY3RcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogY29ubmVjdCB0aGUgb3V0cHV0IG9mIHRoZSBlZmZlY3QgdG8gdGhlIGVmZmVjdFJldHVyblxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4gPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBlZmZlY3QgaW5wdXQgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGVmZmVjdCBvdXRwdXRcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdGhpcy5fZHJ5V2V0O1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmZhbih0aGlzLl9kcnlXZXQuYSwgdGhpcy5lZmZlY3RTZW5kKTtcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY29ubmVjdCh0aGlzLl9kcnlXZXQuYik7XG4gICAgICAgIHRoaXMud2V0LnNldFZhbHVlQXRUaW1lKG9wdGlvbnMud2V0LCAwKTtcbiAgICAgICAgdGhpcy5faW50ZXJuYWxDaGFubmVscyA9IFt0aGlzLmVmZmVjdFJldHVybiwgdGhpcy5lZmZlY3RTZW5kXTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ3ZXRcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3ZXQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBjaGFpbnMgdGhlIGVmZmVjdCBpbiBiZXR3ZWVuIHRoZSBlZmZlY3RTZW5kIGFuZCBlZmZlY3RSZXR1cm5cbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0KGVmZmVjdCkge1xuICAgICAgICAvLyBhZGQgaXQgdG8gdGhlIGludGVybmFsIGNoYW5uZWxzXG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMucHVzaChlZmZlY3QpO1xuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4oZWZmZWN0LCB0aGlzLmVmZmVjdFJldHVybik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RyeVdldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZWZmZWN0UmV0dXJuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53ZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgTEZPLWJhc2VkIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBMRk9FZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTEZPRWZmZWN0XCI7XG4gICAgICAgIHRoaXMuX2xmbyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGFtcGxpdHVkZTogb3B0aW9ucy5kZXB0aCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9sZm8uYW1wbGl0dWRlO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IHRoaXMuX2xmby5mcmVxdWVuY3k7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIGRlcHRoOiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIGVmZmVjdC5cbiAgICAgKi9cbiAgICBzdGFydCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmby5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIGxmb1xuICAgICAqL1xuICAgIHN0b3AodGltZSkge1xuICAgICAgICB0aGlzLl9sZm8uc3RvcCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN5bmMgdGhlIGZpbHRlciB0byB0aGUgdHJhbnNwb3J0LiBTZWUgW1tMRk8uc3luY11dXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvLnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVuc3luYyB0aGUgZmlsdGVyIGZyb20gdGhlIHRyYW5zcG9ydC5cbiAgICAgKi9cbiAgICB1bnN5bmMoKSB7XG4gICAgICAgIHRoaXMuX2xmby51bnN5bmMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0eXBlIG9mIHRoZSBMRk8ncyBvc2NpbGxhdG9yOiBTZWUgW1tPc2NpbGxhdG9yLnR5cGVdXVxuICAgICAqIEBleGFtcGxlXG4gICAgICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoKS5zdGFydCgpLnRvRGVzdGluYXRpb24oKTtcbiAgICAgKiBjb25zdCBub2lzZSA9IG5ldyBUb25lLk5vaXNlKCkuc3RhcnQoKS5jb25uZWN0KGF1dG9GaWx0ZXIpO1xuICAgICAqIGF1dG9GaWx0ZXIudHlwZSA9IFwic3F1YXJlXCI7XG4gICAgICovXG4gICAgZ2V0IHR5cGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm8udHlwZTtcbiAgICB9XG4gICAgc2V0IHR5cGUodHlwZSkge1xuICAgICAgICB0aGlzLl9sZm8udHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmRlcHRoLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TEZPRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IEZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZpbHRlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk9FZmZlY3QgfSBmcm9tIFwiLi9MRk9FZmZlY3RcIjtcbi8qKlxuICogQXV0b0ZpbHRlciBpcyBhIFRvbmUuRmlsdGVyIHdpdGggYSBUb25lLkxGTyBjb25uZWN0ZWQgdG8gdGhlIGZpbHRlciBjdXRvZmYgZnJlcXVlbmN5LlxuICogU2V0dGluZyB0aGUgTEZPIHJhdGUgYW5kIGRlcHRoIGFsbG93cyBmb3IgY29udHJvbCBvdmVyIHRoZSBmaWx0ZXIgbW9kdWxhdGlvbiByYXRlXG4gKiBhbmQgZGVwdGguXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhbiBhdXRvZmlsdGVyIGFuZCBzdGFydCBpdCdzIExGT1xuICogY29uc3QgYXV0b0ZpbHRlciA9IG5ldyBUb25lLkF1dG9GaWx0ZXIoXCI0blwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgZmlsdGVyIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGF1dG9GaWx0ZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvRmlsdGVyIGV4dGVuZHMgTEZPRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b0ZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b0ZpbHRlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b0ZpbHRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCJdKTtcbiAgICAgICAgdGhpcy5maWx0ZXIgPSBuZXcgRmlsdGVyKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5maWx0ZXIsIHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSkpO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5maWx0ZXIpO1xuICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLmZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLm9jdGF2ZXMgPSBvcHRpb25zLm9jdGF2ZXM7XG4gICAgICAgIHRoaXMuYmFzZUZyZXF1ZW5jeSA9IG9wdGlvbnMuYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMRk9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMjAwLFxuICAgICAgICAgICAgb2N0YXZlczogMi42LFxuICAgICAgICAgICAgZmlsdGVyOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCIsXG4gICAgICAgICAgICAgICAgcm9sbG9mZjogLTEyLFxuICAgICAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWluaW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgYmFzZUZyZXF1ZW5jeSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby5taW47XG4gICAgfVxuICAgIHNldCBiYXNlRnJlcXVlbmN5KGZyZXEpIHtcbiAgICAgICAgdGhpcy5fbGZvLm1pbiA9IHRoaXMudG9GcmVxdWVuY3koZnJlcSk7XG4gICAgICAgIC8vIGFuZCBzZXQgdGhlIG1heFxuICAgICAgICB0aGlzLm9jdGF2ZXMgPSB0aGlzLl9vY3RhdmVzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSB2YWx1ZSBvZiB0aGUgZmlsdGVyJ3MgY3V0b2ZmIGZyZXF1ZW5jeS5cbiAgICAgKi9cbiAgICBnZXQgb2N0YXZlcygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29jdGF2ZXM7XG4gICAgfVxuICAgIHNldCBvY3RhdmVzKG9jdCkge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0O1xuICAgICAgICB0aGlzLl9sZm8ubWF4ID0gdGhpcy5fbGZvLm1pbiAqIE1hdGgucG93KDIsIG9jdCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5maWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BdXRvRmlsdGVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBhbm5lciBpcyBhbiBlcXVhbCBwb3dlciBMZWZ0L1JpZ2h0IFBhbm5lci4gSXQgaXMgYSB3cmFwcGVyIGFyb3VuZCB0aGUgU3RlcmVvUGFubmVyTm9kZS5cbiAqIEBleGFtcGxlXG4gKiByZXR1cm4gVG9uZS5PZmZsaW5lKCgpID0+IHtcbiAqIC8vIG1vdmUgdGhlIGlucHV0IHNpZ25hbCBmcm9tIHJpZ2h0IHRvIGxlZnRcbiAqIFx0Y29uc3QgcGFubmVyID0gbmV3IFRvbmUuUGFubmVyKDEpLnRvRGVzdGluYXRpb24oKTtcbiAqIFx0cGFubmVyLnBhbi5yYW1wVG8oLTEsIDAuNSk7XG4gKiBcdGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoMTAwKS5jb25uZWN0KHBhbm5lcikuc3RhcnQoKTtcbiAqIH0sIDAuNSwgMik7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5uZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIl0pKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFubmVyXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgcGFubmVyIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX3Bhbm5lciA9IHRoaXMuY29udGV4dC5jcmVhdGVTdGVyZW9QYW5uZXIoKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX3Bhbm5lcjtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSB0aGlzLl9wYW5uZXI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIl0pO1xuICAgICAgICB0aGlzLnBhbiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBhbixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBhbixcbiAgICAgICAgICAgIG1pblZhbHVlOiAtMSxcbiAgICAgICAgICAgIG1heFZhbHVlOiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gdGhpcyBpcyBuZWNlc3NhcnkgZm9yIHN0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0XG4gICAgICAgIC8vIGRvZXNuJ3QgbWFrZSBhbnkgZGlmZmVyZW5jZSBmb3IgdGhlIG5hdGl2ZSBBdWRpb0NvbnRleHRcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2NocmlzZ3V0dGFuZGluL3N0YW5kYXJkaXplZC1hdWRpby1jb250ZXh0L2lzc3Vlcy82NDdcbiAgICAgICAgdGhpcy5fcGFubmVyLmNoYW5uZWxDb3VudCA9IG9wdGlvbnMuY2hhbm5lbENvdW50O1xuICAgICAgICB0aGlzLl9wYW5uZXIuY2hhbm5lbENvdW50TW9kZSA9IFwiZXhwbGljaXRcIjtcbiAgICAgICAgLy8gaW5pdGlhbCB2YWx1ZVxuICAgICAgICByZWFkT25seSh0aGlzLCBcInBhblwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBhbjogMCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFubmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5uZXIuanMubWFwIiwiaW1wb3J0IHsgUGFubmVyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL1Bhbm5lclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk9FZmZlY3QgfSBmcm9tIFwiLi9MRk9FZmZlY3RcIjtcbi8qKlxuICogQXV0b1Bhbm5lciBpcyBhIFtbUGFubmVyXV0gd2l0aCBhbiBbW0xGT11dIGNvbm5lY3RlZCB0byB0aGUgcGFuIGFtb3VudC5cbiAqIFtSZWxhdGVkIFJlYWRpbmddKGh0dHBzOi8vd3d3LmFibGV0b24uY29tL2VuL2Jsb2cvYXV0b3Bhbi1jaG9wcGVyLWVmZmVjdC1hbmQtbW9yZS1saXZlc2Nob29sLykuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhbiBhdXRvcGFubmVyIGFuZCBzdGFydCBpdFxuICogY29uc3QgYXV0b1Bhbm5lciA9IG5ldyBUb25lLkF1dG9QYW5uZXIoXCI0blwiKS50b0Rlc3RpbmF0aW9uKCkuc3RhcnQoKTtcbiAqIC8vIHJvdXRlIGFuIG9zY2lsbGF0b3IgdGhyb3VnaCB0aGUgcGFubmVyIGFuZCBzdGFydCBpdFxuICogY29uc3Qgb3NjaWxsYXRvciA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KGF1dG9QYW5uZXIpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBBdXRvUGFubmVyIGV4dGVuZHMgTEZPRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1Bhbm5lci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dG9QYW5uZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9QYW5uZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSBuZXcgUGFubmVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogb3B0aW9ucy5jaGFubmVsQ291bnRcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9wYW5uZXIpO1xuICAgICAgICB0aGlzLl9sZm8uY29ubmVjdCh0aGlzLl9wYW5uZXIucGFuKTtcbiAgICAgICAgdGhpcy5fbGZvLm1pbiA9IC0xO1xuICAgICAgICB0aGlzLl9sZm8ubWF4ID0gMTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihMRk9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUF1dG9QYW5uZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBPbmVQb2xlRmlsdGVyIH0gZnJvbSBcIi4uL2ZpbHRlci9PbmVQb2xlRmlsdGVyXCI7XG5pbXBvcnQgeyBBYnMgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0Fic1wiO1xuLyoqXG4gKiBGb2xsb3dlciBpcyBhIHNpbXBsZSBlbnZlbG9wZSBmb2xsb3dlci5cbiAqIEl0J3MgaW1wbGVtZW50ZWQgYnkgYXBwbHlpbmcgYSBsb3dwYXNzIGZpbHRlciB0byB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIGBgYFxuICogICAgICAgICAgKy0tLS0tKyAgICArLS0tLS0tLS0tLS0tLS0tK1xuICogSW5wdXQgKy0tPiBBYnMgKy0tLS0+IE9uZVBvbGVGaWx0ZXIgKy0tPiBPdXRwdXRcbiAqICAgICAgICAgICstLS0tLSsgICAgKy0tLS0tLS0tLS0tLS0tLStcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRm9sbG93ZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRm9sbG93ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGb2xsb3dlclwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRm9sbG93ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLl9hYnMgPSB0aGlzLmlucHV0ID0gbmV3IEFicyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbG93cGFzcyA9IHRoaXMub3V0cHV0ID0gbmV3IE9uZVBvbGVGaWx0ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiAxIC8gdGhpcy50b1NlY29uZHMob3B0aW9ucy5zbW9vdGhpbmcpLFxuICAgICAgICAgICAgdHlwZTogXCJsb3dwYXNzXCJcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Ficy5jb25uZWN0KHRoaXMuX2xvd3Bhc3MpO1xuICAgICAgICB0aGlzLl9zbW9vdGhpbmcgPSBvcHRpb25zLnNtb290aGluZztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC4wNVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiB0aW1lIGl0IHRha2VzIGEgdmFsdWUgY2hhbmdlIHRvIGFycml2ZSBhdCB0aGUgdXBkYXRlZCB2YWx1ZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHNtb290aGluZykge1xuICAgICAgICB0aGlzLl9zbW9vdGhpbmcgPSBzbW9vdGhpbmc7XG4gICAgICAgIHRoaXMuX2xvd3Bhc3MuZnJlcXVlbmN5ID0gMSAvIHRoaXMudG9TZWNvbmRzKHRoaXMuc21vb3RoaW5nKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9hYnMuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dwYXNzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Rm9sbG93ZXIuanMubWFwIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4vRWZmZWN0XCI7XG5pbXBvcnQgeyBGaWx0ZXIgfSBmcm9tIFwiLi4vY29tcG9uZW50L2ZpbHRlci9GaWx0ZXJcIjtcbmltcG9ydCB7IEZvbGxvd2VyIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9hbmFseXNpcy9Gb2xsb3dlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBTY2FsZUV4cCB9IGZyb20gXCIuLi9zaWduYWwvU2NhbGVFeHBcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQXV0b1dhaCBjb25uZWN0cyBhIFtbRm9sbG93ZXJdXSB0byBhIFtbRmlsdGVyXV0uXG4gKiBUaGUgZnJlcXVlbmN5IG9mIHRoZSBmaWx0ZXIsIGZvbGxvd3MgdGhlIGlucHV0IGFtcGxpdHVkZSBjdXJ2ZS5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgYXV0b1dhaCA9IG5ldyBUb25lLkF1dG9XYWgoNTAsIDYsIC0zMCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gaW5pdGlhbGl6ZSB0aGUgc3ludGggYW5kIGNvbm5lY3QgdG8gYXV0b3dhaFxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5TeW50aCgpLmNvbm5lY3QoYXV0b1dhaCk7XG4gKiAvLyBRIHZhbHVlIGluZmx1ZW5jZXMgdGhlIGVmZmVjdCBvZiB0aGUgd2FoIC0gZGVmYXVsdCBpcyAyXG4gKiBhdXRvV2FoLlEudmFsdWUgPSA2O1xuICogLy8gbW9yZSBhdWRpYmxlIG9uIGhpZ2hlciBub3Rlc1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQXV0b1dhaCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKEF1dG9XYWguZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJiYXNlRnJlcXVlbmN5XCIsIFwib2N0YXZlc1wiLCBcInNlbnNpdGl2aXR5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQXV0b1dhaFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQXV0b1dhaC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJhc2VGcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwic2Vuc2l0aXZpdHlcIl0pO1xuICAgICAgICB0aGlzLl9mb2xsb3dlciA9IG5ldyBGb2xsb3dlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzbW9vdGhpbmc6IG9wdGlvbnMuZm9sbG93ZXIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlID0gbmV3IFNjYWxlRXhwKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIGV4cG9uZW50OiAwLjUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9iYXNlRnJlcXVlbmN5ID0gdGhpcy50b0ZyZXF1ZW5jeShvcHRpb25zLmJhc2VGcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb3B0aW9ucy5vY3RhdmVzO1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2JhbmRwYXNzID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICByb2xsb2ZmOiAtNDgsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICBROiBvcHRpb25zLlEsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9wZWFraW5nID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInBlYWtpbmdcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGVha2luZy5nYWluLnZhbHVlID0gb3B0aW9ucy5nYWluO1xuICAgICAgICB0aGlzLmdhaW4gPSB0aGlzLl9wZWFraW5nLmdhaW47XG4gICAgICAgIHRoaXMuUSA9IHRoaXMuX2JhbmRwYXNzLlE7XG4gICAgICAgIC8vIHRoZSBjb250cm9sIHNpZ25hbCBwYXRoXG4gICAgICAgIHRoaXMuZWZmZWN0U2VuZC5jaGFpbih0aGlzLl9pbnB1dEJvb3N0LCB0aGlzLl9mb2xsb3dlciwgdGhpcy5fc3dlZXBSYW5nZSk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuY29ubmVjdCh0aGlzLl9iYW5kcGFzcy5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLmNvbm5lY3QodGhpcy5fcGVha2luZy5mcmVxdWVuY3kpO1xuICAgICAgICAvLyB0aGUgZmlsdGVyZWQgcGF0aFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuY2hhaW4odGhpcy5fYmFuZHBhc3MsIHRoaXMuX3BlYWtpbmcsIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlXG4gICAgICAgIHRoaXMuX3NldFN3ZWVwUmFuZ2UoKTtcbiAgICAgICAgdGhpcy5zZW5zaXRpdml0eSA9IG9wdGlvbnMuc2Vuc2l0aXZpdHk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImdhaW5cIiwgXCJRXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYmFzZUZyZXF1ZW5jeTogMTAwLFxuICAgICAgICAgICAgb2N0YXZlczogNixcbiAgICAgICAgICAgIHNlbnNpdGl2aXR5OiAwLFxuICAgICAgICAgICAgUTogMixcbiAgICAgICAgICAgIGdhaW46IDIsXG4gICAgICAgICAgICBmb2xsb3dlcjogMC4yLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBvY3RhdmVzIHRoYXQgdGhlIGZpbHRlciB3aWxsIHN3ZWVwIGFib3ZlIHRoZSBiYXNlRnJlcXVlbmN5LlxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgdGhpcy5fc2V0U3dlZXBSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZm9sbG93ZXIncyBzbW9vdGhpbmcgdGltZVxuICAgICAqL1xuICAgIGdldCBmb2xsb3dlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IGZvbGxvd2VyKGZvbGxvd2VyKSB7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZyA9IGZvbGxvd2VyO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYmFzZSBmcmVxdWVuY3kgZnJvbSB3aGljaCB0aGUgc3dlZXAgd2lsbCBzdGFydCBmcm9tLlxuICAgICAqL1xuICAgIGdldCBiYXNlRnJlcXVlbmN5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICB9XG4gICAgc2V0IGJhc2VGcmVxdWVuY3koYmFzZUZyZXEpIHtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3koYmFzZUZyZXEpO1xuICAgICAgICB0aGlzLl9zZXRTd2VlcFJhbmdlKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBzZW5zaXRpdml0eSB0byBjb250cm9sIGhvdyByZXNwb25zaXZlIHRvIHRoZSBpbnB1dCBzaWduYWwgdGhlIGZpbHRlciBpcy5cbiAgICAgKi9cbiAgICBnZXQgc2Vuc2l0aXZpdHkoKSB7XG4gICAgICAgIHJldHVybiBnYWluVG9EYigxIC8gdGhpcy5faW5wdXRCb29zdC5nYWluLnZhbHVlKTtcbiAgICB9XG4gICAgc2V0IHNlbnNpdGl2aXR5KHNlbnNpdGl2aXR5KSB7XG4gICAgICAgIHRoaXMuX2lucHV0Qm9vc3QuZ2Fpbi52YWx1ZSA9IDEgLyBkYlRvR2FpbihzZW5zaXRpdml0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIHNldHMgdGhlIHN3ZWVwIHJhbmdlIG9mIHRoZSBzY2FsZXJcbiAgICAgKi9cbiAgICBfc2V0U3dlZXBSYW5nZSgpIHtcbiAgICAgICAgdGhpcy5fc3dlZXBSYW5nZS5taW4gPSB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgICAgICB0aGlzLl9zd2VlcFJhbmdlLm1heCA9IE1hdGgubWluKHRoaXMuX2Jhc2VGcmVxdWVuY3kgKiBNYXRoLnBvdygyLCB0aGlzLl9vY3RhdmVzKSwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAyKTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mb2xsb3dlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N3ZWVwUmFuZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iYW5kcGFzcy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3BlYWtpbmcuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9pbnB1dEJvb3N0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9QXV0b1dhaC5qcy5tYXAiLCJpbXBvcnQgXCIuLi9jb3JlL3dvcmtsZXQvU2luZ2xlSU9Qcm9jZXNzb3Iud29ya2xldFwiO1xuaW1wb3J0IHsgcmVnaXN0ZXJQcm9jZXNzb3IgfSBmcm9tIFwiLi4vY29yZS93b3JrbGV0L1dvcmtsZXRHbG9iYWxTY29wZVwiO1xuZXhwb3J0IGNvbnN0IHdvcmtsZXROYW1lID0gXCJiaXQtY3J1c2hlclwiO1xuZXhwb3J0IGNvbnN0IGJpdENydXNoZXJXb3JrbGV0ID0gLyogamF2YXNjcmlwdCAqLyBgXG5cdGNsYXNzIEJpdENydXNoZXJXb3JrbGV0IGV4dGVuZHMgU2luZ2xlSU9Qcm9jZXNzb3Ige1xuXG5cdFx0c3RhdGljIGdldCBwYXJhbWV0ZXJEZXNjcmlwdG9ycygpIHtcblx0XHRcdHJldHVybiBbe1xuXHRcdFx0XHRuYW1lOiBcImJpdHNcIixcblx0XHRcdFx0ZGVmYXVsdFZhbHVlOiAxMixcblx0XHRcdFx0bWluVmFsdWU6IDEsXG5cdFx0XHRcdG1heFZhbHVlOiAxNixcblx0XHRcdFx0YXV0b21hdGlvblJhdGU6ICdrLXJhdGUnXG5cdFx0XHR9XTtcblx0XHR9XG5cblx0XHRnZW5lcmF0ZShpbnB1dCwgX2NoYW5uZWwsIHBhcmFtZXRlcnMpIHtcblx0XHRcdGNvbnN0IHN0ZXAgPSBNYXRoLnBvdygwLjUsIHBhcmFtZXRlcnMuYml0cyAtIDEpO1xuXHRcdFx0Y29uc3QgdmFsID0gc3RlcCAqIE1hdGguZmxvb3IoaW5wdXQgLyBzdGVwICsgMC41KTtcblx0XHRcdHJldHVybiB2YWw7XG5cdFx0fVxuXHR9XG5gO1xucmVnaXN0ZXJQcm9jZXNzb3Iod29ya2xldE5hbWUsIGJpdENydXNoZXJXb3JrbGV0KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUJpdENydXNoZXIud29ya2xldC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Xb3JrbGV0IH0gZnJvbSBcIi4uL2NvcmUvd29ya2xldC9Ub25lQXVkaW9Xb3JrbGV0XCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgY29ubmVjdFNlcmllcyB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgUGFyYW0gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L1BhcmFtXCI7XG5pbXBvcnQgeyB3b3JrbGV0TmFtZSB9IGZyb20gXCIuL0JpdENydXNoZXIud29ya2xldFwiO1xuLyoqXG4gKiBCaXRDcnVzaGVyIGRvd24tc2FtcGxlcyB0aGUgaW5jb21pbmcgc2lnbmFsIHRvIGEgZGlmZmVyZW50IGJpdCBkZXB0aC5cbiAqIExvd2VyaW5nIHRoZSBiaXQgZGVwdGggb2YgdGhlIHNpZ25hbCBjcmVhdGVzIGRpc3RvcnRpb24uIFJlYWQgbW9yZSBhYm91dCBCaXRDcnVzaGluZ1xuICogb24gW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQml0Y3J1c2hlcikuXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6ZSBjcnVzaGVyIGFuZCByb3V0ZSBhIHN5bnRoIHRocm91Z2ggaXRcbiAqIGNvbnN0IGNydXNoZXIgPSBuZXcgVG9uZS5CaXRDcnVzaGVyKDQpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuU3ludGgoKS5jb25uZWN0KGNydXNoZXIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCAyKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBCaXRDcnVzaGVyIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImJpdHNcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJCaXRDcnVzaGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhCaXRDcnVzaGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiYml0c1wiXSk7XG4gICAgICAgIHRoaXMuX2JpdENydXNoZXJXb3JrbGV0ID0gbmV3IEJpdENydXNoZXJXb3JrbGV0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGJpdHM6IG9wdGlvbnMuYml0cyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0KHRoaXMuX2JpdENydXNoZXJXb3JrbGV0KTtcbiAgICAgICAgdGhpcy5iaXRzID0gdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQuYml0cztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgYml0czogNCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYml0Q3J1c2hlcldvcmtsZXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEludGVybmFsIGNsYXNzIHdoaWNoIGNyZWF0ZXMgYW4gQXVkaW9Xb3JrbGV0IHRvIGRvIHRoZSBiaXQgY3J1c2hpbmdcbiAqL1xuY2xhc3MgQml0Q3J1c2hlcldvcmtsZXQgZXh0ZW5kcyBUb25lQXVkaW9Xb3JrbGV0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQml0Q3J1c2hlcldvcmtsZXQuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQml0Q3J1c2hlcldvcmtsZXRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEJpdENydXNoZXJXb3JrbGV0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5iaXRzID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmJpdHMsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgbWluVmFsdWU6IDEsXG4gICAgICAgICAgICBtYXhWYWx1ZTogMTYsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fZHVtbXlQYXJhbSxcbiAgICAgICAgICAgIHN3YXBwYWJsZTogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvV29ya2xldC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBiaXRzOiAxMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9hdWRpb1dvcmtsZXROYW1lKCkge1xuICAgICAgICByZXR1cm4gd29ya2xldE5hbWU7XG4gICAgfVxuICAgIG9uUmVhZHkobm9kZSkge1xuICAgICAgICBjb25uZWN0U2VyaWVzKHRoaXMuaW5wdXQsIG5vZGUsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29uc3QgYml0cyA9IG5vZGUucGFyYW1ldGVycy5nZXQoXCJiaXRzXCIpO1xuICAgICAgICB0aGlzLmJpdHMuc2V0UGFyYW0oYml0cyk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3V0cHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5iaXRzLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Qml0Q3J1c2hlci5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgV2F2ZVNoYXBlciB9IGZyb20gXCIuLi9zaWduYWwvV2F2ZVNoYXBlclwiO1xuLyoqXG4gKiBDaGVieXNoZXYgaXMgYSB3YXZlc2hhcGVyIHdoaWNoIGlzIGdvb2RcbiAqIGZvciBtYWtpbmcgZGlmZmVyZW50IHR5cGVzIG9mIGRpc3RvcnRpb24gc291bmRzLlxuICogTm90ZSB0aGF0IG9kZCBvcmRlcnMgc291bmQgdmVyeSBkaWZmZXJlbnQgZnJvbSBldmVuIG9uZXMsXG4gKiBhbmQgb3JkZXIgPSAxIGlzIG5vIGNoYW5nZS5cbiAqIFJlYWQgbW9yZSBhdCBbbXVzaWMuY29sdW1iaWEuZWR1XShodHRwOi8vbXVzaWMuY29sdW1iaWEuZWR1L2NtYy9tdXNpY2FuZGNvbXB1dGVycy9jaGFwdGVyNC8wNF8wNi5waHApLlxuICogQGV4YW1wbGVcbiAqIC8vIGNyZWF0ZSBhIG5ldyBjaGVieVxuICogY29uc3QgY2hlYnkgPSBuZXcgVG9uZS5DaGVieXNoZXYoNTApLnRvRGVzdGluYXRpb24oKTtcbiAqIC8vIGNyZWF0ZSBhIG1vbm9zeW50aCBjb25uZWN0ZWQgdG8gb3VyIGNoZWJ5XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk1vbm9TeW50aCgpLmNvbm5lY3QoY2hlYnkpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDMlwiLCAwLjQpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgQ2hlYnlzaGV2IGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hlYnlzaGV2LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wib3JkZXJcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDaGVieXNoZXZcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKENoZWJ5c2hldi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcIm9yZGVyXCJdKTtcbiAgICAgICAgdGhpcy5fc2hhcGVyID0gbmV3IFdhdmVTaGFwZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbGVuZ3RoOiA0MDk2XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9vcmRlciA9IG9wdGlvbnMub3JkZXI7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9zaGFwZXIpO1xuICAgICAgICB0aGlzLm9yZGVyID0gb3B0aW9ucy5vcmRlcjtcbiAgICAgICAgdGhpcy5vdmVyc2FtcGxlID0gb3B0aW9ucy5vdmVyc2FtcGxlO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBvcmRlcjogMSxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6IFwibm9uZVwiXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBnZXQgdGhlIGNvZWZmaWNpZW50IGZvciB0aGF0IGRlZ3JlZVxuICAgICAqIEBwYXJhbSAgeCB0aGUgeCB2YWx1ZVxuICAgICAqIEBwYXJhbSAgZGVncmVlXG4gICAgICogQHBhcmFtICBtZW1vIG1lbW9pemUgdGhlIGNvbXB1dGVkIHZhbHVlLiB0aGlzIHNwZWVkcyB1cCBjb21wdXRhdGlvbiBncmVhdGx5LlxuICAgICAqL1xuICAgIF9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUsIG1lbW8pIHtcbiAgICAgICAgaWYgKG1lbW8uaGFzKGRlZ3JlZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBtZW1vLmdldChkZWdyZWUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRlZ3JlZSA9PT0gMCkge1xuICAgICAgICAgICAgbWVtby5zZXQoZGVncmVlLCAwKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkZWdyZWUgPT09IDEpIHtcbiAgICAgICAgICAgIG1lbW8uc2V0KGRlZ3JlZSwgeCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtZW1vLnNldChkZWdyZWUsIDIgKiB4ICogdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgZGVncmVlIC0gMSwgbWVtbykgLSB0aGlzLl9nZXRDb2VmZmljaWVudCh4LCBkZWdyZWUgLSAyLCBtZW1vKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW8uZ2V0KGRlZ3JlZSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBvcmRlciBvZiB0aGUgQ2hlYnlzaGV2IHBvbHlub21pYWwgd2hpY2ggY3JlYXRlcyB0aGUgZXF1YXRpb24gd2hpY2ggaXMgYXBwbGllZCB0byB0aGUgaW5jb21pbmdcbiAgICAgKiBzaWduYWwgdGhyb3VnaCBhIFRvbmUuV2F2ZVNoYXBlci4gVGhlIGVxdWF0aW9ucyBhcmUgaW4gdGhlIGZvcm06XG4gICAgICogYGBgXG4gICAgICogb3JkZXIgMjogMnheMiArIDFcbiAgICAgKiBvcmRlciAzOiA0eF4zICsgM3hcbiAgICAgKiBgYGBcbiAgICAgKiBAbWluIDFcbiAgICAgKiBAbWF4IDEwMFxuICAgICAqL1xuICAgIGdldCBvcmRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX29yZGVyO1xuICAgIH1cbiAgICBzZXQgb3JkZXIob3JkZXIpIHtcbiAgICAgICAgdGhpcy5fb3JkZXIgPSBvcmRlcjtcbiAgICAgICAgdGhpcy5fc2hhcGVyLnNldE1hcCgoeCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Q29lZmZpY2llbnQoeCwgb3JkZXIsIG5ldyBNYXAoKSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG92ZXJzYW1wbGluZyBvZiB0aGUgZWZmZWN0LiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaGVieXNoZXYuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIFNwbGl0IHNwbGl0cyBhbiBpbmNvbWluZyBzaWduYWwgaW50byB0aGUgbnVtYmVyIG9mIGdpdmVuIGNoYW5uZWxzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBzcGxpdCA9IG5ldyBUb25lLlNwbGl0KCk7XG4gKiAvLyBzdGVyZW9TaWduYWwuY29ubmVjdChzcGxpdCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiU3BsaXRcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiY2hhbm5lbHNcIl0pO1xuICAgICAgICB0aGlzLl9zcGxpdHRlciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IHRoaXMuY29udGV4dC5jcmVhdGVDaGFubmVsU3BsaXR0ZXIob3B0aW9ucy5jaGFubmVscyk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fc3BsaXR0ZXJdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgY2hhbm5lbHM6IDIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG4vKipcbiAqIE1lcmdlIGJyaW5ncyBtdWx0aXBsZSBtb25vIGlucHV0IGNoYW5uZWxzIGludG8gYSBzaW5nbGUgbXVsdGljaGFubmVsIG91dHB1dCBjaGFubmVsLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBtZXJnZSA9IG5ldyBUb25lLk1lcmdlKCkudG9EZXN0aW5hdGlvbigpO1xuICogLy8gcm91dGluZyBhIHNpbmUgdG9uZSBpbiB0aGUgbGVmdCBjaGFubmVsXG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChtZXJnZSwgMCwgMCkuc3RhcnQoKTtcbiAqIC8vIGFuZCBub2lzZSBpbiB0aGUgcmlnaHQgY2hhbm5lbFxuICogY29uc3Qgbm9pc2UgPSBuZXcgVG9uZS5Ob2lzZSgpLmNvbm5lY3QobWVyZ2UsIDAsIDEpLnN0YXJ0KCk7O1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWVyZ2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJjaGFubmVsc1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1lcmdlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNZXJnZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImNoYW5uZWxzXCJdKTtcbiAgICAgICAgdGhpcy5fbWVyZ2VyID0gdGhpcy5vdXRwdXQgPSB0aGlzLmlucHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNoYW5uZWxNZXJnZXIob3B0aW9ucy5jaGFubmVscyk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2VyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWVyZ2UuanMubWFwIiwiaW1wb3J0IHsgY29ubmVjdCwgY29ubmVjdFNlcmllcywgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIFN0ZXJlbyBlZmZlY3RzLlxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvRWZmZWN0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTdGVyZW9FZmZlY3RcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBmb3JjZSBtb25vIHNvdXJjZXMgdG8gYmUgc3RlcmVvXG4gICAgICAgIHRoaXMuaW5wdXQuY2hhbm5lbENvdW50ID0gMjtcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFubmVsQ291bnRNb2RlID0gXCJleHBsaWNpdFwiO1xuICAgICAgICB0aGlzLl9kcnlXZXQgPSB0aGlzLm91dHB1dCA9IG5ldyBDcm9zc0ZhZGUoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZmFkZTogb3B0aW9ucy53ZXRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMud2V0ID0gdGhpcy5fZHJ5V2V0LmZhZGU7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gbmV3IFNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSBuZXcgTWVyZ2UoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQsIGNoYW5uZWxzOiAyIH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fc3BsaXQpO1xuICAgICAgICAvLyBkcnkgd2V0IGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9kcnlXZXQuYSk7XG4gICAgICAgIHRoaXMuX21lcmdlLmNvbm5lY3QodGhpcy5fZHJ5V2V0LmIpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJ3ZXRcIl0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBsZWZ0IHBhcnQgb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RMZWZ0KC4uLm5vZGVzKSB7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3Qobm9kZXNbMF0sIDAsIDApO1xuICAgICAgICBjb25uZWN0U2VyaWVzKC4uLm5vZGVzKTtcbiAgICAgICAgY29ubmVjdChub2Rlc1tub2Rlcy5sZW5ndGggLSAxXSwgdGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSByaWdodCBwYXJ0IG9mIHRoZSBlZmZlY3RcbiAgICAgKi9cbiAgICBjb25uZWN0RWZmZWN0UmlnaHQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdChub2Rlc1swXSwgMSwgMCk7XG4gICAgICAgIGNvbm5lY3RTZXJpZXMoLi4ubm9kZXMpO1xuICAgICAgICBjb25uZWN0KG5vZGVzW25vZGVzLmxlbmd0aCAtIDFdLCB0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB3ZXQ6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RyeVdldC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9FZmZlY3QuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL01lcmdlXCI7XG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIHN0ZXJlbyBmZWVkYmFjayBlZmZlY3RzIHdoZXJlIHRoZSBlZmZlY3RSZXR1cm4gaXMgZmVkIGJhY2sgaW50byB0aGUgc2FtZSBjaGFubmVsLlxuICovXG5leHBvcnQgY2xhc3MgU3RlcmVvRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZlZWRiYWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUiA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0ID0gbmV3IFNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0LCBjaGFubmVsczogMiB9KTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCwgY2hhbm5lbHM6IDIgfSk7XG4gICAgICAgIHRoaXMuX21lcmdlLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tTcGxpdCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTWVyZ2UuY29ubmVjdCh0aGlzLl9zcGxpdCk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIGxlZnQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTCwgMCwgMCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDApO1xuICAgICAgICAvLyB0aGUgcmlnaHQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tTcGxpdC5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrUiwgMSwgMCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDEpO1xuICAgICAgICAvLyB0aGUgZmVlZGJhY2sgY29udHJvbFxuICAgICAgICB0aGlzLmZlZWRiYWNrLmZhbih0aGlzLl9mZWVkYmFja0wuZ2FpbiwgdGhpcy5fZmVlZGJhY2tSLmdhaW4pO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmZWVkYmFja1wiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZlZWRiYWNrOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja1NwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVN0ZXJlb0ZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0ZlZWRiYWNrRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9TdGVyZW9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ2hvcnVzIGlzIGEgc3RlcmVvIGNob3J1cyBlZmZlY3QgY29tcG9zZWQgb2YgYSBsZWZ0IGFuZCByaWdodCBkZWxheSB3aXRoIGFuIFtbTEZPXV0gYXBwbGllZCB0byB0aGUgZGVsYXlUaW1lIG9mIGVhY2ggY2hhbm5lbC5cbiAqIFdoZW4gW1tmZWVkYmFja11dIGlzIHNldCB0byBhIHZhbHVlIGxhcmdlciB0aGFuIDAsIHlvdSBhbHNvIGdldCBGbGFuZ2VyLXR5cGUgZWZmZWN0cy5cbiAqIEluc3BpcmF0aW9uIGZyb20gW1R1bmEuanNdKGh0dHBzOi8vZ2l0aHViLmNvbS9EaW5haG1vZS90dW5hL2Jsb2IvbWFzdGVyL3R1bmEuanMpLlxuICogUmVhZCBtb3JlIG9uIHRoZSBjaG9ydXMgZWZmZWN0IG9uIFtTb3VuZE9uU291bmRdKGh0dHA6Ly93d3cuc291bmRvbnNvdW5kLmNvbS9zb3MvanVuMDQvYXJ0aWNsZXMvc3ludGhzZWNyZXRzLmh0bSkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNob3J1cyA9IG5ldyBUb25lLkNob3J1cyg0LCAyLjUsIDAuNSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlBvbHlTeW50aCgpLmNvbm5lY3QoY2hvcnVzKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFtcIkMzXCIsIFwiRTNcIiwgXCJHM1wiXSwgXCI4blwiKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBDaG9ydXMgZXh0ZW5kcyBTdGVyZW9GZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENob3J1cy5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlbGF5VGltZVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hvcnVzXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDaG9ydXMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJkZWxheVRpbWVcIiwgXCJkZXB0aFwiXSk7XG4gICAgICAgIHRoaXMuX2RlcHRoID0gb3B0aW9ucy5kZXB0aDtcbiAgICAgICAgdGhpcy5fZGVsYXlUaW1lID0gb3B0aW9ucy5kZWxheVRpbWUgLyAxMDAwO1xuICAgICAgICB0aGlzLl9sZm9MID0gbmV3IExGTyh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IG9wdGlvbnMuZnJlcXVlbmN5LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZnJlcXVlbmN5OiBvcHRpb25zLmZyZXF1ZW5jeSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMSxcbiAgICAgICAgICAgIHBoYXNlOiAxODBcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwgPSBuZXcgRGVsYXkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZVIgPSBuZXcgRGVsYXkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gdGhpcy5fbGZvTC5mcmVxdWVuY3k7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIC8vIGhhdmUgb25lIExGTyBmcmVxdWVuY3kgY29udHJvbCB0aGUgb3RoZXJcbiAgICAgICAgdGhpcy5fbGZvTC5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQodGhpcy5fZGVsYXlOb2RlTCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFJpZ2h0KHRoaXMuX2RlbGF5Tm9kZVIpO1xuICAgICAgICAvLyBsZm8gc2V0dXBcbiAgICAgICAgdGhpcy5fbGZvTC5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZUwuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5jb25uZWN0KHRoaXMuX2RlbGF5Tm9kZVIuZGVsYXlUaW1lKTtcbiAgICAgICAgLy8gc2V0IHRoZSBpbml0aWFsIHZhbHVlc1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fZGVwdGg7XG4gICAgICAgIHRoaXMudHlwZSA9IG9wdGlvbnMudHlwZTtcbiAgICAgICAgdGhpcy5zcHJlYWQgPSBvcHRpb25zLnNwcmVhZDtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9GZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmcmVxdWVuY3k6IDEuNSxcbiAgICAgICAgICAgIGRlbGF5VGltZTogMy41LFxuICAgICAgICAgICAgZGVwdGg6IDAuNyxcbiAgICAgICAgICAgIHR5cGU6IFwic2luZVwiLFxuICAgICAgICAgICAgc3ByZWFkOiAxODAsXG4gICAgICAgICAgICBmZWVkYmFjazogMCxcbiAgICAgICAgICAgIHdldDogMC41LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRlcHRoIG9mIHRoZSBlZmZlY3QuIEEgZGVwdGggb2YgMSBtYWtlcyB0aGUgZGVsYXlUaW1lXG4gICAgICogbW9kdWxhdGUgYmV0d2VlbiAwIGFuZCAyKmRlbGF5VGltZSAoY2VudGVyZWQgYXJvdW5kIHRoZSBkZWxheVRpbWUpLlxuICAgICAqL1xuICAgIGdldCBkZXB0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlcHRoO1xuICAgIH1cbiAgICBzZXQgZGVwdGgoZGVwdGgpIHtcbiAgICAgICAgdGhpcy5fZGVwdGggPSBkZXB0aDtcbiAgICAgICAgY29uc3QgZGV2aWF0aW9uID0gdGhpcy5fZGVsYXlUaW1lICogZGVwdGg7XG4gICAgICAgIHRoaXMuX2xmb0wubWluID0gTWF0aC5tYXgodGhpcy5fZGVsYXlUaW1lIC0gZGV2aWF0aW9uLCAwKTtcbiAgICAgICAgdGhpcy5fbGZvTC5tYXggPSB0aGlzLl9kZWxheVRpbWUgKyBkZXZpYXRpb247XG4gICAgICAgIHRoaXMuX2xmb1IubWluID0gTWF0aC5tYXgodGhpcy5fZGVsYXlUaW1lIC0gZGV2aWF0aW9uLCAwKTtcbiAgICAgICAgdGhpcy5fbGZvUi5tYXggPSB0aGlzLl9kZWxheVRpbWUgKyBkZXZpYXRpb247XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBkZWxheVRpbWUgaW4gbWlsbGlzZWNvbmRzIG9mIHRoZSBjaG9ydXMuIEEgbGFyZ2VyIGRlbGF5VGltZVxuICAgICAqIHdpbGwgZ2l2ZSBhIG1vcmUgcHJvbm91bmNlZCBlZmZlY3QuIE5vbWluYWwgcmFuZ2UgYSBkZWxheVRpbWVcbiAgICAgKiBpcyBiZXR3ZWVuIDIgYW5kIDIwbXMuXG4gICAgICovXG4gICAgZ2V0IGRlbGF5VGltZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlbGF5VGltZSAqIDEwMDA7XG4gICAgfVxuICAgIHNldCBkZWxheVRpbWUoZGVsYXlUaW1lKSB7XG4gICAgICAgIHRoaXMuX2RlbGF5VGltZSA9IGRlbGF5VGltZSAvIDEwMDA7XG4gICAgICAgIHRoaXMuZGVwdGggPSB0aGlzLl9kZXB0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG9zY2lsbGF0b3IgdHlwZSBvZiB0aGUgTEZPLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvTC50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cbiAgICAgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTtcbiAgICB9XG4gICAgc2V0IHNwcmVhZChzcHJlYWQpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5waGFzZSA9IDkwIC0gKHNwcmVhZCAvIDIpO1xuICAgICAgICB0aGlzLl9sZm9SLnBoYXNlID0gKHNwcmVhZCAvIDIpICsgOTA7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSBlZmZlY3QuXG4gICAgICovXG4gICAgc3RhcnQodGltZSkge1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KHRpbWUpO1xuICAgICAgICB0aGlzLl9sZm9SLnN0YXJ0KHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgbGZvXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZmlsdGVyIHRvIHRoZSB0cmFuc3BvcnQuIFNlZSBbW0xGTy5zeW5jXV1cbiAgICAgKi9cbiAgICBzeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnN5bmMoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zeW5jKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVbnN5bmMgdGhlIGZpbHRlciBmcm9tIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnVuc3luYygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Tm9kZUwuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGVSLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1DaG9ydXMuanMubWFwIiwiaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBXYXZlU2hhcGVyIH0gZnJvbSBcIi4uL3NpZ25hbC9XYXZlU2hhcGVyXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbi8qKlxuICogQSBzaW1wbGUgZGlzdG9ydGlvbiBlZmZlY3QgdXNpbmcgVG9uZS5XYXZlU2hhcGVyLlxuICogQWxnb3JpdGhtIGZyb20gW3RoaXMgc3RhY2tvdmVyZmxvdyBhbnN3ZXJdKGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIyMzEzNDA4KS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZGlzdCA9IG5ldyBUb25lLkRpc3RvcnRpb24oMC44KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBmbSA9IG5ldyBUb25lLkZNU3ludGgoKS5jb25uZWN0KGRpc3QpO1xuICogZm0udHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBMVwiLCBcIjhuXCIpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRGlzdG9ydGlvbiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKERpc3RvcnRpb24uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkaXN0b3J0aW9uXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRGlzdG9ydGlvblwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRGlzdG9ydGlvbi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRpc3RvcnRpb25cIl0pO1xuICAgICAgICB0aGlzLl9zaGFwZXIgPSBuZXcgV2F2ZVNoYXBlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsZW5ndGg6IDQwOTYsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gb3B0aW9ucy5kaXN0b3J0aW9uO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3QodGhpcy5fc2hhcGVyKTtcbiAgICAgICAgdGhpcy5kaXN0b3J0aW9uID0gb3B0aW9ucy5kaXN0b3J0aW9uO1xuICAgICAgICB0aGlzLm92ZXJzYW1wbGUgPSBvcHRpb25zLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGRpc3RvcnRpb246IDAuNCxcbiAgICAgICAgICAgIG92ZXJzYW1wbGU6IFwibm9uZVwiLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiBkaXN0b3J0aW9uLiBOb21pbmFsIHJhbmdlIGlzIGJldHdlZW4gMCBhbmQgMS5cbiAgICAgKi9cbiAgICBnZXQgZGlzdG9ydGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Rpc3RvcnRpb247XG4gICAgfVxuICAgIHNldCBkaXN0b3J0aW9uKGFtb3VudCkge1xuICAgICAgICB0aGlzLl9kaXN0b3J0aW9uID0gYW1vdW50O1xuICAgICAgICBjb25zdCBrID0gYW1vdW50ICogMTAwO1xuICAgICAgICBjb25zdCBkZWcgPSBNYXRoLlBJIC8gMTgwO1xuICAgICAgICB0aGlzLl9zaGFwZXIuc2V0TWFwKCh4KSA9PiB7XG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoeCkgPCAwLjAwMSkge1xuICAgICAgICAgICAgICAgIC8vIHNob3VsZCBvdXRwdXQgMCB3aGVuIGlucHV0IGlzIDBcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAoMyArIGspICogeCAqIDIwICogZGVnIC8gKE1hdGguUEkgKyBrICogTWF0aC5hYnMoeCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG92ZXJzYW1wbGluZyBvZiB0aGUgZWZmZWN0LiBDYW4gZWl0aGVyIGJlIFwibm9uZVwiLCBcIjJ4XCIgb3IgXCI0eFwiLlxuICAgICAqL1xuICAgIGdldCBvdmVyc2FtcGxlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2hhcGVyLm92ZXJzYW1wbGU7XG4gICAgfVxuICAgIHNldCBvdmVyc2FtcGxlKG92ZXJzYW1wbGluZykge1xuICAgICAgICB0aGlzLl9zaGFwZXIub3ZlcnNhbXBsZSA9IG92ZXJzYW1wbGluZztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaGFwZXIuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EaXN0b3J0aW9uLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuLyoqXG4gKiBGZWVkYmFja0VmZmVjdCBwcm92aWRlcyBhIGxvb3AgYmV0d2VlbiBhbiBhdWRpbyBzb3VyY2UgYW5kIGl0cyBvd24gb3V0cHV0LlxuICogVGhpcyBpcyBhIGJhc2UtY2xhc3MgZm9yIGZlZWRiYWNrIGVmZmVjdHMuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0VmZmVjdCBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0VmZmVjdFwiO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0dhaW4gPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBnYWluOiBvcHRpb25zLmZlZWRiYWNrLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2sgPSB0aGlzLl9mZWVkYmFja0dhaW4uZ2FpbjtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJmZWVkYmFja1wiKTtcbiAgICAgICAgLy8gdGhlIGZlZWRiYWNrIGxvb3BcbiAgICAgICAgdGhpcy5lZmZlY3RSZXR1cm4uY2hhaW4odGhpcy5fZmVlZGJhY2tHYWluLCB0aGlzLmVmZmVjdFNlbmQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBmZWVkYmFjazogMC4xMjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZmVlZGJhY2suZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0VmZmVjdC5qcy5tYXAiLCJpbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9GZWVkYmFja0VmZmVjdFwiO1xuLyoqXG4gKiBGZWVkYmFja0RlbGF5IGlzIGEgRGVsYXlOb2RlIGluIHdoaWNoIHBhcnQgb2Ygb3V0cHV0IHNpZ25hbCBpcyBmZWQgYmFjayBpbnRvIHRoZSBkZWxheS5cbiAqXG4gKiBAcGFyYW0gZGVsYXlUaW1lIFRoZSBkZWxheSBhcHBsaWVkIHRvIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBAcGFyYW0gZmVlZGJhY2sgVGhlIGFtb3VudCBvZiB0aGUgZWZmZWN0ZWQgc2lnbmFsIHdoaWNoIGlzIGZlZCBiYWNrIHRocm91Z2ggdGhlIGRlbGF5LlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGZlZWRiYWNrRGVsYXkgPSBuZXcgVG9uZS5GZWVkYmFja0RlbGF5KFwiOG5cIiwgMC41KS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCB0b20gPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKHtcbiAqIFx0b2N0YXZlczogNCxcbiAqIFx0cGl0Y2hEZWNheTogMC4xXG4gKiB9KS5jb25uZWN0KGZlZWRiYWNrRGVsYXkpO1xuICogdG9tLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQTJcIiwgXCIzMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGZWVkYmFja0RlbGF5IGV4dGVuZHMgRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJGZWVkYmFja0RlbGF5XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhGZWVkYmFja0RlbGF5LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZGVsYXlUaW1lXCIsIFwiZmVlZGJhY2tcIl0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSB0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lO1xuICAgICAgICAvLyBjb25uZWN0IGl0IHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9kZWxheU5vZGUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMjUsXG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZGVsYXlOb2RlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1GZWVkYmFja0RlbGF5LmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGNvbm5lY3RTZXJpZXMsIFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbi8qKlxuICogUGhhc2VTaGlmdEFsbHBhc3MgaXMgYW4gdmVyeSBlZmZpY2llbnQgaW1wbGVtZW50YXRpb24gb2YgYSBIaWxiZXJ0IFRyYW5zZm9ybVxuICogdXNpbmcgdHdvIEFsbHBhc3MgZmlsdGVyIGJhbmtzIHdob3NlIG91dHB1dHMgaGF2ZSBhIHBoYXNlIGRpZmZlcmVuY2Ugb2YgOTDCsC5cbiAqIEhlcmUgdGhlIGBvZmZzZXQ5MGAgcGhhc2UgaXMgb2Zmc2V0IGJ5ICs5MMKwIGluIHJlbGF0aW9uIHRvIGBvdXRwdXRgLlxuICogQ29lZmZpY2llbnRzIGFuZCBzdHJ1Y3R1cmUgd2FzIGRldmVsb3BlZCBieSBPbGxpIE5pZW1pdGFsby5cbiAqIEZvciBtb3JlIGRldGFpbHMgc2VlOiBodHRwOi8veWVoYXIuY29tL2Jsb2cvP3A9MzY4XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQaGFzZVNoaWZ0QWxscGFzcyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGhhc2VTaGlmdEFsbHBhc3NcIjtcbiAgICAgICAgdGhpcy5pbnB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBoYXNlIHNoaWZ0ZWQgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIFBoYXNlU2hpZnRlZCBhbGxwYXNzIG91dHB1dFxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5vZmZzZXQ5MCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICBjb25zdCBhbGxwYXNzQmFuazFWYWx1ZXMgPSBbMC42OTIzODc4LCAwLjkzNjA2NTQzMjI5NTksIDAuOTg4MjI5NTIyNjg2MCwgMC45OTg3NDg4NDUyNzM3XTtcbiAgICAgICAgY29uc3QgYWxscGFzc0JhbmsyVmFsdWVzID0gWzAuNDAyMTkyMTE2MjQyNiwgMC44NTYxNzEwODgyNDIwLCAwLjk3MjI5MDk1NDU2NTEsIDAuOTk1Mjg4NDc5MTI3OF07XG4gICAgICAgIHRoaXMuX2JhbmswID0gdGhpcy5fY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYWxscGFzc0JhbmsxVmFsdWVzKTtcbiAgICAgICAgdGhpcy5fYmFuazEgPSB0aGlzLl9jcmVhdGVBbGxQYXNzRmlsdGVyQmFuayhhbGxwYXNzQmFuazJWYWx1ZXMpO1xuICAgICAgICB0aGlzLl9vbmVTYW1wbGVEZWxheSA9IHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoWzAuMCwgMS4wXSwgWzEuMCwgMC4wXSk7XG4gICAgICAgIC8vIGNvbm5lY3QgQWxscGFzcyBmaWx0ZXIgYmFua3NcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9iYW5rMCwgdGhpcy5fb25lU2FtcGxlRGVsYXksIHRoaXMub3V0cHV0KTtcbiAgICAgICAgY29ubmVjdFNlcmllcyh0aGlzLmlucHV0LCAuLi50aGlzLl9iYW5rMSwgdGhpcy5vZmZzZXQ5MCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhbGwgb2YgdGhlIElJUiBmaWx0ZXJzIGZyb20gYW4gYXJyYXkgb2YgdmFsdWVzIHVzaW5nIHRoZSBjb2VmZmljaWVudCBjYWxjdWxhdGlvbi5cbiAgICAgKi9cbiAgICBfY3JlYXRlQWxsUGFzc0ZpbHRlckJhbmsoYmFua1ZhbHVlcykge1xuICAgICAgICBjb25zdCBub2RlcyA9IGJhbmtWYWx1ZXMubWFwKHZhbHVlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvZWZmaWNpZW50cyA9IFtbdmFsdWUgKiB2YWx1ZSwgMCwgLTFdLCBbMSwgMCwgLSh2YWx1ZSAqIHZhbHVlKV1dO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jcmVhdGVJSVJGaWx0ZXIoY29lZmZpY2llbnRzWzBdLCBjb2VmZmljaWVudHNbMV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm91dHB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub2Zmc2V0OTAuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9iYW5rMC5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9iYW5rMS5mb3JFYWNoKGYgPT4gZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9vbmVTYW1wbGVEZWxheS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBoYXNlU2hpZnRBbGxwYXNzLmpzLm1hcCIsImltcG9ydCB7IFBoYXNlU2hpZnRBbGxwYXNzIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9maWx0ZXIvUGhhc2VTaGlmdEFsbHBhc3NcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcIi4uL2VmZmVjdC9FZmZlY3RcIjtcbmltcG9ydCB7IEFkZCB9IGZyb20gXCIuLi9zaWduYWwvQWRkXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IE5lZ2F0ZSB9IGZyb20gXCIuLi9zaWduYWwvTmVnYXRlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgT3NjaWxsYXRvciB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9Pc2NpbGxhdG9yXCI7XG5pbXBvcnQgeyBUb25lT3NjaWxsYXRvck5vZGUgfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvVG9uZU9zY2lsbGF0b3JOb2RlXCI7XG4vKipcbiAqIEZyZXF1ZW5jeVNoaWZ0ZXIgY2FuIGJlIHVzZWQgdG8gc2hpZnQgYWxsIGZyZXF1ZW5jaWVzIG9mIGEgc2lnbmFsIGJ5IGEgZml4ZWQgYW1vdW50LlxuICogVGhlIGFtb3VudCBjYW4gYmUgY2hhbmdlZCBhdCBhdWRpbyByYXRlIGFuZCB0aGUgZWZmZWN0IGlzIGFwcGxpZWQgaW4gcmVhbCB0aW1lLlxuICogVGhlIGZyZXF1ZW5jeSBzaGlmdGluZyBpcyBpbXBsZW1lbnRlZCB3aXRoIGEgdGVjaG5pcXVlIGNhbGxlZCBzaW5nbGUgc2lkZSBiYW5kIG1vZHVsYXRpb24gdXNpbmcgYSByaW5nIG1vZHVsYXRvci5cbiAqIE5vdGU6IENvbnRyYXJ5IHRvIHBpdGNoIHNoaWZ0aW5nLCBhbGwgZnJlcXVlbmNpZXMgYXJlIHNoaWZ0ZWQgYnkgdGhlIHNhbWUgYW1vdW50LFxuICogZGVzdHJveWluZyB0aGUgaGFybW9uaWMgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlbS4gVGhpcyBsZWFkcyB0byB0aGUgY2xhc3NpYyByaW5nIG1vZHVsYXRvciB0aW1icmUgZGlzdG9ydGlvbi5cbiAqIFRoZSBhbGdvcml0aG0gd2lsbCBwcm9kdWNlcyBzb21lIGFsaWFzaW5nIHRvd2FyZHMgdGhlIGhpZ2ggZW5kLCBlc3BlY2lhbGx5IGlmIHlvdXIgc291cmNlIG1hdGVyaWFsXG4gKiBjb250YWlucyBhIGxvdCBvZiBoaWdoIGZyZXF1ZW5jaWVzLiBVbmZvcnR1bmF0ZWxseSB0aGUgd2ViYXVkaW8gQVBJIGRvZXMgbm90IHN1cHBvcnQgcmVzYW1wbGluZ1xuICogYnVmZmVycyBpbiByZWFsIHRpbWUsIHNvIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBmaXggaXQgcHJvcGVybHkuIERlcGVuZGluZyBvbiB0aGUgdXNlIGNhc2UgaXQgbWlnaHRcbiAqIGJlIGFuIG9wdGlvbiB0byBsb3cgcGFzcyBmaWx0ZXIgeW91ciBpbnB1dCBiZWZvcmUgZnJlcXVlbmN5IHNoaWZ0aW5nIGl0IHRvIGdldCByaWRlIG9mIHRoZSBhbGlhc2luZy5cbiAqIFlvdSBjYW4gZmluZCBhIHZlcnkgZGV0YWlsZWQgZGVzY3JpcHRpb24gb2YgdGhlIGFsZ29yaXRobSBoZXJlOiBodHRwczovL2xhcnplaXRsaW4uZ2l0aHViLmlvL1JNRlMvXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGlucHV0ID0gbmV3IFRvbmUuT3NjaWxsYXRvcigyMzAsIFwic2F3dG9vdGhcIikuc3RhcnQoKTtcbiAqIGNvbnN0IHNoaWZ0ID0gbmV3IFRvbmUuRnJlcXVlbmN5U2hpZnRlcig0MikudG9EZXN0aW5hdGlvbigpO1xuICogaW5wdXQuY29ubmVjdChzaGlmdCk7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBGcmVxdWVuY3lTaGlmdGVyIGV4dGVuZHMgRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRnJlcXVlbmN5U2hpZnRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZyZXF1ZW5jeVNoaWZ0ZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZXF1ZW5jeVNoaWZ0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW5WYWx1ZTogLXRoaXMuY29udGV4dC5zYW1wbGVSYXRlIC8gMixcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLmNvbnRleHQuc2FtcGxlUmF0ZSAvIDIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zaW5lID0gbmV3IFRvbmVPc2NpbGxhdG9yTm9kZSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZSA9IG5ldyBPc2NpbGxhdG9yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBoYXNlOiAtOTAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseSA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fY29zaW5lTXVsdGlwbHkgPSBuZXcgTXVsdGlwbHkoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX25lZ2F0ZSA9IG5ldyBOZWdhdGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2FkZCA9IG5ldyBBZGQoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3BoYXNlU2hpZnRlciA9IG5ldyBQaGFzZVNoaWZ0QWxscGFzcyh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNvbm5lY3QodGhpcy5fcGhhc2VTaGlmdGVyKTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGUgY2FycmllciBmcmVxdWVuY3kgc2lnbmFsIHRvIHRoZSB0d28gb3NjaWxsYXRvcnNcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZmFuKHRoaXMuX3NpbmUuZnJlcXVlbmN5LCB0aGlzLl9jb3NpbmUuZnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLm9mZnNldDkwLmNvbm5lY3QodGhpcy5fY29zaW5lTXVsdGlwbHkpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuY29ubmVjdCh0aGlzLl9jb3NpbmVNdWx0aXBseS5mYWN0b3IpO1xuICAgICAgICB0aGlzLl9waGFzZVNoaWZ0ZXIuY29ubmVjdCh0aGlzLl9zaW5lTXVsdGlwbHkpO1xuICAgICAgICB0aGlzLl9zaW5lLmNvbm5lY3QodGhpcy5fc2luZU11bHRpcGx5LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseS5jb25uZWN0KHRoaXMuX25lZ2F0ZSk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5LmNvbm5lY3QodGhpcy5fYWRkKTtcbiAgICAgICAgdGhpcy5fbmVnYXRlLmNvbm5lY3QodGhpcy5fYWRkLmFkZGVuZCk7XG4gICAgICAgIHRoaXMuX2FkZC5jb25uZWN0KHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIG9zY2lsbGF0b3JzIGF0IHRoZSBzYW1lIHRpbWVcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5pbW1lZGlhdGUoKTtcbiAgICAgICAgdGhpcy5fc2luZS5zdGFydChub3cpO1xuICAgICAgICB0aGlzLl9jb3NpbmUuc3RhcnQobm93KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgZnJlcXVlbmN5OiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FkZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nvc2luZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2Nvc2luZU11bHRpcGx5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbmVnYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGhhc2VTaGlmdGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2luZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpbmVNdWx0aXBseS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUZyZXF1ZW5jeVNoaWZ0ZXIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBMb3dwYXNzQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0xvd3Bhc3NDb21iRmlsdGVyXCI7XG4vKipcbiAqIEFuIGFycmF5IG9mIGNvbWIgZmlsdGVyIGRlbGF5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJUdW5pbmdzID0gWzE1NTcgLyA0NDEwMCwgMTYxNyAvIDQ0MTAwLCAxNDkxIC8gNDQxMDAsIDE0MjIgLyA0NDEwMCwgMTI3NyAvIDQ0MTAwLCAxMzU2IC8gNDQxMDAsIDExODggLyA0NDEwMCwgMTExNiAvIDQ0MTAwXTtcbi8qKlxuICogQW4gYXJyYXkgb2YgYWxscGFzcyBmaWx0ZXIgZnJlcXVlbmN5IHZhbHVlcyBmcm9tIEZyZWV2ZXJiIGltcGxlbWVudGF0aW9uXG4gKi9cbmNvbnN0IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcyA9IFsyMjUsIDU1NiwgNDQxLCAzNDFdO1xuLyoqXG4gKiBGcmVldmVyYiBpcyBhIHJldmVyYiBiYXNlZCBvbiBbRnJlZXZlcmJdKGh0dHBzOi8vY2NybWEuc3RhbmZvcmQuZWR1L35qb3MvcGFzcC9GcmVldmVyYi5odG1sKS5cbiAqIFJlYWQgbW9yZSBvbiByZXZlcmIgb24gW1NvdW5kIE9uIFNvdW5kXShodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNjA0MDQwODM5MDIvaHR0cDovL3d3dy5zb3VuZG9uc291bmQuY29tOjgwL3Nvcy9mZWIwMS9hcnRpY2xlcy9zeW50aHNlY3JldHMuYXNwKS5cbiAqIEZyZWV2ZXJiIGlzIG5vdyBpbXBsZW1lbnRlZCB3aXRoIGFuIEF1ZGlvV29ya2xldE5vZGUgd2hpY2ggbWF5IHJlc3VsdCBvbiBwZXJmb3JtYW5jZSBkZWdyYWRhdGlvbiBvbiBzb21lIHBsYXRmb3Jtcy4gQ29uc2lkZXIgdXNpbmcgW1tSZXZlcmJdXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBmcmVldmVyYiA9IG5ldyBUb25lLkZyZWV2ZXJiKCkudG9EZXN0aW5hdGlvbigpO1xuICogZnJlZXZlcmIuZGFtcGVuaW5nID0gMTAwMDtcbiAqIC8vIHJvdXRpbmcgc3ludGggdGhyb3VnaCB0aGUgcmV2ZXJiXG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLk5vaXNlU3ludGgoKS5jb25uZWN0KGZyZWV2ZXJiKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKDAuMDUpO1xuICogQGNhdGVnb3J5IEVmZmVjdFxuICovXG5leHBvcnQgY2xhc3MgRnJlZXZlcmIgZXh0ZW5kcyBTdGVyZW9FZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhGcmVldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInJvb21TaXplXCIsIFwiZGFtcGVuaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRnJlZXZlcmJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBjb21iIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbWJGaWx0ZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgYWxscGFzcyBmaWx0ZXJzIG9uIHRoZSBsZWZ0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc0wgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVyc1IgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEZyZWV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIiwgXCJkYW1wZW5pbmdcIl0pO1xuICAgICAgICB0aGlzLnJvb21TaXplID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yb29tU2l6ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIHJpZ2h0XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzTCA9IGFsbHBhc3NGaWx0ZXJGcmVxdWVuY2llcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzTCA9IHRoaXMuY29udGV4dC5jcmVhdGVCaXF1YWRGaWx0ZXIoKTtcbiAgICAgICAgICAgIGFsbHBhc3NMLnR5cGUgPSBcImFsbHBhc3NcIjtcbiAgICAgICAgICAgIGFsbHBhc3NMLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzc0w7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBtYWtlIHRoZSBhbGxwYXNzIGZpbHRlcnMgb24gdGhlIGxlZnRcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSID0gYWxscGFzc0ZpbHRlckZyZXF1ZW5jaWVzLm1hcChmcmVxID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFsbHBhc3NSID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzc1IudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgYWxscGFzc1IuZnJlcXVlbmN5LnZhbHVlID0gZnJlcTtcbiAgICAgICAgICAgIHJldHVybiBhbGxwYXNzUjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGNvbWIgZmlsdGVyc1xuICAgICAgICB0aGlzLl9jb21iRmlsdGVycyA9IGNvbWJGaWx0ZXJUdW5pbmdzLm1hcCgoZGVsYXlUaW1lLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGZwZiA9IG5ldyBMb3dwYXNzQ29tYkZpbHRlcih7XG4gICAgICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgICAgIGRhbXBlbmluZzogb3B0aW9ucy5kYW1wZW5pbmcsXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBjb21iRmlsdGVyVHVuaW5ncy5sZW5ndGggLyAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdChsZnBmLCAuLi50aGlzLl9hbGxwYXNzRmlsdGVyc0wpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQobGZwZiwgLi4udGhpcy5fYWxscGFzc0ZpbHRlcnNSKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucm9vbVNpemUuY29ubmVjdChsZnBmLnJlc29uYW5jZSk7XG4gICAgICAgICAgICByZXR1cm4gbGZwZjtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcInJvb21TaXplXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihTdGVyZW9FZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcm9vbVNpemU6IDAuNyxcbiAgICAgICAgICAgIGRhbXBlbmluZzogMzAwMFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFtb3VudCBvZiBkYW1wZW5pbmcgb2YgdGhlIHJldmVyYmVyYW50IHNpZ25hbC5cbiAgICAgKi9cbiAgICBnZXQgZGFtcGVuaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29tYkZpbHRlcnNbMF0uZGFtcGVuaW5nO1xuICAgIH1cbiAgICBzZXQgZGFtcGVuaW5nKGQpIHtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMuZm9yRWFjaChjID0+IGMuZGFtcGVuaW5nID0gZCk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNMLmZvckVhY2goYWwgPT4gYWwuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fYWxscGFzc0ZpbHRlcnNSLmZvckVhY2goYXIgPT4gYXIuZGlzY29ubmVjdCgpKTtcbiAgICAgICAgdGhpcy5fY29tYkZpbHRlcnMuZm9yRWFjaChjZiA9PiBjZi5kaXNwb3NlKCkpO1xuICAgICAgICB0aGlzLnJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RnJlZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNjYWxlIH0gZnJvbSBcIi4uL3NpZ25hbC9TY2FsZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IEZlZWRiYWNrQ29tYkZpbHRlciB9IGZyb20gXCIuLi9jb21wb25lbnQvZmlsdGVyL0ZlZWRiYWNrQ29tYkZpbHRlclwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBhbiBhcnJheSBvZiB0aGUgY29tYiBmaWx0ZXIgZGVsYXkgdGltZSB2YWx1ZXNcbiAqL1xuY29uc3QgY29tYkZpbHRlckRlbGF5VGltZXMgPSBbMTY4NyAvIDI1MDAwLCAxNjAxIC8gMjUwMDAsIDIwNTMgLyAyNTAwMCwgMjI1MSAvIDI1MDAwXTtcbi8qKlxuICogdGhlIHJlc29uYW5jZXMgb2YgZWFjaCBvZiB0aGUgY29tYiBmaWx0ZXJzXG4gKi9cbmNvbnN0IGNvbWJGaWx0ZXJSZXNvbmFuY2VzID0gWzAuNzczLCAwLjgwMiwgMC43NTMsIDAuNzMzXTtcbi8qKlxuICogdGhlIGFsbHBhc3MgZmlsdGVyIGZyZXF1ZW5jaWVzXG4gKi9cbmNvbnN0IGFsbHBhc3NGaWx0ZXJGcmVxcyA9IFszNDcsIDExMywgMzddO1xuLyoqXG4gKiBKQ1JldmVyYiBpcyBhIHNpbXBsZSBbU2Nocm9lZGVyIFJldmVyYmVyYXRvcl0oaHR0cHM6Ly9jY3JtYS5zdGFuZm9yZC5lZHUvfmpvcy9wYXNwL1NjaHJvZWRlcl9SZXZlcmJlcmF0b3JzLmh0bWwpXG4gKiB0dW5lZCBieSBKb2huIENob3duaW5nIGluIDE5NzAuXG4gKiBJdCBpcyBtYWRlIHVwIG9mIHRocmVlIGFsbHBhc3MgZmlsdGVycyBhbmQgZm91ciBbW0ZlZWRiYWNrQ29tYkZpbHRlcl1dLlxuICogSkNSZXZlcmIgaXMgbm93IGltcGxlbWVudGVkIHdpdGggYW4gQXVkaW9Xb3JrbGV0Tm9kZSB3aGljaCBtYXkgcmVzdWx0IG9uIHBlcmZvcm1hbmNlIGRlZ3JhZGF0aW9uIG9uIHNvbWUgcGxhdGZvcm1zLiBDb25zaWRlciB1c2luZyBbW1JldmVyYl1dLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHJldmVyYiA9IG5ldyBUb25lLkpDUmV2ZXJiKDAuNCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgZGVsYXkgPSBuZXcgVG9uZS5GZWVkYmFja0RlbGF5KDAuNSk7XG4gKiAvLyBjb25uZWN0aW5nIHRoZSBzeW50aCB0byByZXZlcmIgdGhyb3VnaCBkZWxheVxuICogY29uc3Qgc3ludGggPSBuZXcgVG9uZS5EdW9TeW50aCgpLmNoYWluKGRlbGF5LCByZXZlcmIpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJBNFwiLCBcIjhuXCIpO1xuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIEpDUmV2ZXJiIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoSkNSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJyb29tU2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkpDUmV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBhIHNlcmllcyBvZiBhbGxwYXNzIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBwYXJhbGxlbCBmZWVkYmFjayBjb21iIGZpbHRlcnNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEpDUmV2ZXJiLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicm9vbVNpemVcIl0pO1xuICAgICAgICB0aGlzLnJvb21TaXplID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yb29tU2l6ZSxcbiAgICAgICAgICAgIHVuaXRzOiBcIm5vcm1hbFJhbmdlXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplID0gbmV3IFNjYWxlKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogLTAuNzMzLFxuICAgICAgICAgICAgbWF4OiAwLjE5NyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIG1ha2UgdGhlIGFsbHBhc3MgZmlsdGVyc1xuICAgICAgICB0aGlzLl9hbGxwYXNzRmlsdGVycyA9IGFsbHBhc3NGaWx0ZXJGcmVxcy5tYXAoZnJlcSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbGxwYXNzID0gdGhpcy5jb250ZXh0LmNyZWF0ZUJpcXVhZEZpbHRlcigpO1xuICAgICAgICAgICAgYWxscGFzcy50eXBlID0gXCJhbGxwYXNzXCI7XG4gICAgICAgICAgICBhbGxwYXNzLmZyZXF1ZW5jeS52YWx1ZSA9IGZyZXE7XG4gICAgICAgICAgICByZXR1cm4gYWxscGFzcztcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGFuZCB0aGUgY29tYiBmaWx0ZXJzXG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrQ29tYkZpbHRlcnMgPSBjb21iRmlsdGVyRGVsYXlUaW1lcy5tYXAoKGRlbGF5VGltZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZiY2YgPSBuZXcgRmVlZGJhY2tDb21iRmlsdGVyKHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICAgICAgZGVsYXlUaW1lLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmNvbm5lY3QoZmJjZi5yZXNvbmFuY2UpO1xuICAgICAgICAgICAgZmJjZi5yZXNvbmFuY2UudmFsdWUgPSBjb21iRmlsdGVyUmVzb25hbmNlc1tpbmRleF07XG4gICAgICAgICAgICBpZiAoaW5kZXggPCBjb21iRmlsdGVyRGVsYXlUaW1lcy5sZW5ndGggLyAyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCguLi50aGlzLl9hbGxwYXNzRmlsdGVycywgZmJjZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCguLi50aGlzLl9hbGxwYXNzRmlsdGVycywgZmJjZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmJjZjtcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNoYWluIHRoZSBhbGxwYXNzIGZpbHRlcnMgdG9nZXRoZXJcbiAgICAgICAgdGhpcy5yb29tU2l6ZS5jb25uZWN0KHRoaXMuX3NjYWxlUm9vbVNpemUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJyb29tU2l6ZVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHJvb21TaXplOiAwLjUsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FsbHBhc3NGaWx0ZXJzLmZvckVhY2goYXBmID0+IGFwZi5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0NvbWJGaWx0ZXJzLmZvckVhY2goZmJjZiA9PiBmYmNmLmRpc3Bvc2UoKSk7XG4gICAgICAgIHRoaXMucm9vbVNpemUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zY2FsZVJvb21TaXplLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SkNSZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRmVlZGJhY2tFZmZlY3QgfSBmcm9tIFwiLi9TdGVyZW9GZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBKdXN0IGxpa2UgYSBbW1N0ZXJlb0ZlZWRiYWNrRWZmZWN0XV0sIGJ1dCB0aGUgZmVlZGJhY2sgaXMgcm91dGVkIGZyb20gbGVmdCB0byByaWdodFxuICogYW5kIHJpZ2h0IHRvIGxlZnQgaW5zdGVhZCBvZiBvbiB0aGUgc2FtZSBjaGFubmVsLlxuICogYGBgXG4gKiArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rIGZlZWRiYWNrTCA8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiArLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tLS0+ICAgICAgICArLS0tLT4gICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLStcbiAqICAgICAgZmVlZGJhY2tNZXJnZSArLS0+IHNwbGl0ICAgICAgICAoRUZGRUNUKSAgICAgICBtZXJnZSArLS0+IGZlZWRiYWNrU3BsaXQgICAgIHwgfFxuICogKy0tPiAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tPiAgICAgICAgKy0tLS0+ICAgICAgICAgICAgICAgICAgICAgICAgICArLS0tKyB8XG4gKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsgZmVlZGJhY2tSIDwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9YRmVlZGJhY2tFZmZlY3QgZXh0ZW5kcyBTdGVyZW9GZWVkYmFja0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgICAgICBzdXBlcihvcHRpb25zKTtcbiAgICAgICAgLy8gdGhlIGxlZnQgb3V0cHV0IGNvbm5lY3RlZCB0byB0aGUgcmlnaHQgaW5wdXRcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tMLmNvbm5lY3QodGhpcy5fZmVlZGJhY2tNZXJnZSwgMCwgMSk7XG4gICAgICAgIC8vIHRoZSBsZWZ0IG91dHB1dCBjb25uZWN0ZWQgdG8gdGhlIHJpZ2h0IGlucHV0XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrUi5jb25uZWN0KHRoaXMuX2ZlZWRiYWNrTWVyZ2UsIDAsIDApO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJmZWVkYmFja1wiXSk7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9U3RlcmVvWEZlZWRiYWNrRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb1hGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb1hGZWVkYmFja0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBpbmdQb25nRGVsYXkgaXMgYSBmZWVkYmFjayBkZWxheSBlZmZlY3Qgd2hlcmUgdGhlIGVjaG8gaXMgaGVhcmRcbiAqIGZpcnN0IGluIG9uZSBjaGFubmVsIGFuZCBuZXh0IGluIHRoZSBvcHBvc2l0ZSBjaGFubmVsLiBJbiBhIHN0ZXJlb1xuICogc3lzdGVtIHRoZXNlIGFyZSB0aGUgcmlnaHQgYW5kIGxlZnQgY2hhbm5lbHMuXG4gKiBQaW5nUG9uZ0RlbGF5IGluIG1vcmUgc2ltcGxpZmllZCB0ZXJtcyBpcyB0d28gVG9uZS5GZWVkYmFja0RlbGF5c1xuICogd2l0aCBpbmRlcGVuZGVudCBkZWxheSB2YWx1ZXMuIEVhY2ggZGVsYXkgaXMgcm91dGVkIHRvIG9uZSBjaGFubmVsXG4gKiAobGVmdCBvciByaWdodCksIGFuZCB0aGUgY2hhbm5lbCB0cmlnZ2VyZWQgc2Vjb25kIHdpbGwgYWx3YXlzXG4gKiB0cmlnZ2VyIGF0IHRoZSBzYW1lIGludGVydmFsIGFmdGVyIHRoZSBmaXJzdC5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCBwaW5nUG9uZyA9IG5ldyBUb25lLlBpbmdQb25nRGVsYXkoXCI0blwiLCAwLjIpLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IGRydW0gPSBuZXcgVG9uZS5NZW1icmFuZVN5bnRoKCkuY29ubmVjdChwaW5nUG9uZyk7XG4gKiBkcnVtLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiQzRcIiwgXCIzMm5cIik7XG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaW5nUG9uZ0RlbGF5IGV4dGVuZHMgU3RlcmVvWEZlZWRiYWNrRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGluZ1BvbmdEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGluZ1BvbmdEZWxheVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoUGluZ1BvbmdEZWxheS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlbGF5VGltZVwiLCBcImZlZWRiYWNrXCJdKTtcbiAgICAgICAgdGhpcy5fbGVmdERlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1heERlbGF5OiBvcHRpb25zLm1heERlbGF5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHREZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheSA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBtYXhEZWxheTogb3B0aW9ucy5tYXhEZWxheVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUgPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHVuaXRzOiBcInRpbWVcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlbGF5VGltZSxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9sZWZ0RGVsYXkpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCh0aGlzLl9yaWdodFByZURlbGF5LCB0aGlzLl9yaWdodERlbGF5KTtcbiAgICAgICAgdGhpcy5kZWxheVRpbWUuZmFuKHRoaXMuX2xlZnREZWxheS5kZWxheVRpbWUsIHRoaXMuX3JpZ2h0RGVsYXkuZGVsYXlUaW1lLCB0aGlzLl9yaWdodFByZURlbGF5LmRlbGF5VGltZSk7XG4gICAgICAgIC8vIHJlYXJyYW5nZWQgdGhlIGZlZWRiYWNrIHRvIGJlIGFmdGVyIHRoZSByaWdodFByZURlbGF5XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5kaXNjb25uZWN0KCk7XG4gICAgICAgIHRoaXMuX2ZlZWRiYWNrTC5jb25uZWN0KHRoaXMuX3JpZ2h0RGVsYXkpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJkZWxheVRpbWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFN0ZXJlb1hGZWVkYmFja0VmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWxheVRpbWU6IDAuMjUsXG4gICAgICAgICAgICBtYXhEZWxheTogMVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0RGVsYXkuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodERlbGF5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcmlnaHRQcmVEZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGluZ1BvbmdEZWxheS5qcy5tYXAiLCJpbXBvcnQgeyBGZWVkYmFja0VmZmVjdCB9IGZyb20gXCIuL0ZlZWRiYWNrRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IERlbGF5IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9EZWxheVwiO1xuaW1wb3J0IHsgQ3Jvc3NGYWRlIH0gZnJvbSBcIi4uL2NvbXBvbmVudC9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IGludGVydmFsVG9GcmVxdWVuY3lSYXRpbyB9IGZyb20gXCIuLi9jb3JlL3R5cGUvQ29udmVyc2lvbnNcIjtcbi8qKlxuICogUGl0Y2hTaGlmdCBkb2VzIG5lYXItcmVhbHRpbWUgcGl0Y2ggc2hpZnRpbmcgdG8gdGhlIGluY29taW5nIHNpZ25hbC5cbiAqIFRoZSBlZmZlY3QgaXMgYWNoaWV2ZWQgYnkgc3BlZWRpbmcgdXAgb3Igc2xvd2luZyBkb3duIHRoZSBkZWxheVRpbWVcbiAqIG9mIGEgRGVsYXlOb2RlIHVzaW5nIGEgc2F3dG9vdGggd2F2ZS5cbiAqIEFsZ29yaXRobSBmb3VuZCBpbiBbdGhpcyBwZGZdKGh0dHA6Ly9kc3AtYm9vay5uYXJvZC5ydS9zb3VuZHByb2MucGRmKS5cbiAqIEFkZGl0aW9uYWwgcmVmZXJlbmNlIGJ5IFtNaWxsZXIgUHVja2V0XShodHRwOi8vbXNwLnVjc2QuZWR1L3RlY2huaXF1ZXMvdjAuMTEvYm9vay1odG1sL25vZGUxMTUuaHRtbCkuXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBQaXRjaFNoaWZ0IGV4dGVuZHMgRmVlZGJhY2tFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhQaXRjaFNoaWZ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGl0Y2hcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJQaXRjaFNoaWZ0XCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaXRjaFNoaWZ0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGl0Y2hcIl0pO1xuICAgICAgICB0aGlzLl9mcmVxdWVuY3kgPSBuZXcgU2lnbmFsKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9kZWxheUEgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgbWF4RGVsYXk6IDEsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb0EgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzYXd0b290aFwiXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fZGVsYXlBLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2RlbGF5QiA9IG5ldyBEZWxheSh7XG4gICAgICAgICAgICBtYXhEZWxheTogMSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvQiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAwLjEsXG4gICAgICAgICAgICB0eXBlOiBcInNhd3Rvb3RoXCIsXG4gICAgICAgICAgICBwaGFzZTogMTgwXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fZGVsYXlCLmRlbGF5VGltZSk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZSA9IG5ldyBDcm9zc0ZhZGUoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2Nyb3NzRmFkZUxGTyA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgbWluOiAwLFxuICAgICAgICAgICAgbWF4OiAxLFxuICAgICAgICAgICAgdHlwZTogXCJ0cmlhbmdsZVwiLFxuICAgICAgICAgICAgcGhhc2U6IDkwXG4gICAgICAgIH0pLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmZhZGUpO1xuICAgICAgICB0aGlzLl9mZWVkYmFja0RlbGF5ID0gbmV3IERlbGF5KHtcbiAgICAgICAgICAgIGRlbGF5VGltZTogb3B0aW9ucy5kZWxheVRpbWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRlbGF5VGltZSA9IHRoaXMuX2ZlZWRiYWNrRGVsYXkuZGVsYXlUaW1lO1xuICAgICAgICByZWFkT25seSh0aGlzLCBcImRlbGF5VGltZVwiKTtcbiAgICAgICAgdGhpcy5fcGl0Y2ggPSBvcHRpb25zLnBpdGNoO1xuICAgICAgICB0aGlzLl93aW5kb3dTaXplID0gb3B0aW9ucy53aW5kb3dTaXplO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSB0d28gZGVsYXkgbGluZXMgdXBcbiAgICAgICAgdGhpcy5fZGVsYXlBLmNvbm5lY3QodGhpcy5fY3Jvc3NGYWRlLmEpO1xuICAgICAgICB0aGlzLl9kZWxheUIuY29ubmVjdCh0aGlzLl9jcm9zc0ZhZGUuYik7XG4gICAgICAgIC8vIGNvbm5lY3QgdGhlIGZyZXF1ZW5jeVxuICAgICAgICB0aGlzLl9mcmVxdWVuY3kuZmFuKHRoaXMuX2xmb0EuZnJlcXVlbmN5LCB0aGlzLl9sZm9CLmZyZXF1ZW5jeSwgdGhpcy5fY3Jvc3NGYWRlTEZPLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHJvdXRlIHRoZSBpbnB1dFxuICAgICAgICB0aGlzLmVmZmVjdFNlbmQuZmFuKHRoaXMuX2RlbGF5QSwgdGhpcy5fZGVsYXlCKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlLmNoYWluKHRoaXMuX2ZlZWRiYWNrRGVsYXksIHRoaXMuZWZmZWN0UmV0dXJuKTtcbiAgICAgICAgLy8gc3RhcnQgdGhlIExGT3MgYXQgdGhlIHNhbWUgdGltZVxuICAgICAgICBjb25zdCBub3cgPSB0aGlzLm5vdygpO1xuICAgICAgICB0aGlzLl9sZm9BLnN0YXJ0KG5vdyk7XG4gICAgICAgIHRoaXMuX2xmb0Iuc3RhcnQobm93KTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPLnN0YXJ0KG5vdyk7XG4gICAgICAgIC8vIHNldCB0aGUgaW5pdGlhbCB2YWx1ZVxuICAgICAgICB0aGlzLndpbmRvd1NpemUgPSB0aGlzLl93aW5kb3dTaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEZlZWRiYWNrRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHBpdGNoOiAwLFxuICAgICAgICAgICAgd2luZG93U2l6ZTogMC4xLFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgZmVlZGJhY2s6IDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJlcGl0Y2ggdGhlIGluY29taW5nIHNpZ25hbCBieSBzb21lIGludGVydmFsIChtZWFzdXJlZCBpbiBzZW1pLXRvbmVzKS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGNvbnN0IHBpdGNoU2hpZnQgPSBuZXcgVG9uZS5QaXRjaFNoaWZ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIGNvbnN0IG9zYyA9IG5ldyBUb25lLk9zY2lsbGF0b3IoKS5jb25uZWN0KHBpdGNoU2hpZnQpLnN0YXJ0KCkudG9EZXN0aW5hdGlvbigpO1xuICAgICAqIHBpdGNoU2hpZnQucGl0Y2ggPSAtMTI7IC8vIGRvd24gb25lIG9jdGF2ZVxuICAgICAqIHBpdGNoU2hpZnQucGl0Y2ggPSA3OyAvLyB1cCBhIGZpZnRoXG4gICAgICovXG4gICAgZ2V0IHBpdGNoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGl0Y2g7XG4gICAgfVxuICAgIHNldCBwaXRjaChpbnRlcnZhbCkge1xuICAgICAgICB0aGlzLl9waXRjaCA9IGludGVydmFsO1xuICAgICAgICBsZXQgZmFjdG9yID0gMDtcbiAgICAgICAgaWYgKGludGVydmFsIDwgMCkge1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5taW4gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5tYXggPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5taW4gPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5tYXggPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgZmFjdG9yID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsIC0gMSkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5taW4gPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQS5tYXggPSAwO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5taW4gPSB0aGlzLl93aW5kb3dTaXplO1xuICAgICAgICAgICAgdGhpcy5fbGZvQi5tYXggPSAwO1xuICAgICAgICAgICAgZmFjdG9yID0gaW50ZXJ2YWxUb0ZyZXF1ZW5jeVJhdGlvKGludGVydmFsKSAtIDE7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fZnJlcXVlbmN5LnZhbHVlID0gZmFjdG9yICogKDEuMiAvIHRoaXMuX3dpbmRvd1NpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgd2luZG93IHNpemUgY29ycmVzcG9uZHMgcm91Z2hseSB0byB0aGUgc2FtcGxlIGxlbmd0aCBpbiBhIGxvb3Bpbmcgc2FtcGxlci5cbiAgICAgKiBTbWFsbGVyIHZhbHVlcyBhcmUgZGVzaXJhYmxlIGZvciBhIGxlc3Mgbm90aWNlYWJsZSBkZWxheSB0aW1lIG9mIHRoZSBwaXRjaCBzaGlmdGVkXG4gICAgICogc2lnbmFsLCBidXQgbGFyZ2VyIHZhbHVlcyB3aWxsIHJlc3VsdCBpbiBzbW9vdGhlciBwaXRjaCBzaGlmdGluZyBmb3IgbGFyZ2VyIGludGVydmFscy5cbiAgICAgKiBBIG5vbWluYWwgcmFuZ2Ugb2YgMC4wMyB0byAwLjEgaXMgcmVjb21tZW5kZWQuXG4gICAgICovXG4gICAgZ2V0IHdpbmRvd1NpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl93aW5kb3dTaXplO1xuICAgIH1cbiAgICBzZXQgd2luZG93U2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX3dpbmRvd1NpemUgPSB0aGlzLnRvU2Vjb25kcyhzaXplKTtcbiAgICAgICAgdGhpcy5waXRjaCA9IHRoaXMuX3BpdGNoO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5QS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2RlbGF5Qi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0EuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9CLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fY3Jvc3NGYWRlTEZPLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZmVlZGJhY2tEZWxheS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVBpdGNoU2hpZnQuanMubWFwIiwiaW1wb3J0IHsgU3RlcmVvRWZmZWN0IH0gZnJvbSBcIi4vU3RlcmVvRWZmZWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IExGTyB9IGZyb20gXCIuLi9zb3VyY2Uvb3NjaWxsYXRvci9MRk9cIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIFBoYXNlciBpcyBhIHBoYXNlciBlZmZlY3QuIFBoYXNlcnMgd29yayBieSBjaGFuZ2luZyB0aGUgcGhhc2VcbiAqIG9mIGRpZmZlcmVudCBmcmVxdWVuY3kgY29tcG9uZW50cyBvZiBhbiBpbmNvbWluZyBzaWduYWwuIFJlYWQgbW9yZSBvblxuICogW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUGhhc2VyXyhlZmZlY3QpKS5cbiAqIEluc3BpcmF0aW9uIGZvciB0aGlzIHBoYXNlciBjb21lcyBmcm9tIFtUdW5hLmpzXShodHRwczovL2dpdGh1Yi5jb20vRGluYWhtb2UvdHVuYS8pLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBoYXNlciA9IG5ldyBUb25lLlBoYXNlcih7XG4gKiBcdGZyZXF1ZW5jeTogMTUsXG4gKiBcdG9jdGF2ZXM6IDUsXG4gKiBcdGJhc2VGcmVxdWVuY3k6IDEwMDBcbiAqIH0pLnRvRGVzdGluYXRpb24oKTtcbiAqIGNvbnN0IHN5bnRoID0gbmV3IFRvbmUuRk1TeW50aCgpLmNvbm5lY3QocGhhc2VyKTtcbiAqIHN5bnRoLnRyaWdnZXJBdHRhY2tSZWxlYXNlKFwiRTNcIiwgXCIyblwiKTtcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFBoYXNlciBleHRlbmRzIFN0ZXJlb0VmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBoYXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcIm9jdGF2ZXNcIiwgXCJiYXNlRnJlcXVlbmN5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGhhc2VyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQaGFzZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJmcmVxdWVuY3lcIiwgXCJvY3RhdmVzXCIsIFwiYmFzZUZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX2xmb0wgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDFcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2xmb1IgPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgICBtYXg6IDEsXG4gICAgICAgICAgICBwaGFzZTogMTgwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYmFzZUZyZXF1ZW5jeSA9IHRoaXMudG9GcmVxdWVuY3kob3B0aW9ucy5iYXNlRnJlcXVlbmN5KTtcbiAgICAgICAgdGhpcy5fb2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5RLFxuICAgICAgICAgICAgdW5pdHM6IFwicG9zaXRpdmVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNMID0gdGhpcy5fbWFrZUZpbHRlcnMob3B0aW9ucy5zdGFnZXMsIHRoaXMuX2xmb0wpO1xuICAgICAgICB0aGlzLl9maWx0ZXJzUiA9IHRoaXMuX21ha2VGaWx0ZXJzKG9wdGlvbnMuc3RhZ2VzLCB0aGlzLl9sZm9SKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm9MLmZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kudmFsdWUgPSBvcHRpb25zLmZyZXF1ZW5jeTtcbiAgICAgICAgLy8gY29ubmVjdCB0aGVtIHVwXG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdExlZnQoLi4udGhpcy5fZmlsdGVyc0wpO1xuICAgICAgICB0aGlzLmNvbm5lY3RFZmZlY3RSaWdodCguLi50aGlzLl9maWx0ZXJzUik7XG4gICAgICAgIC8vIGNvbnRyb2wgdGhlIGZyZXF1ZW5jeSB3aXRoIG9uZSBMRk9cbiAgICAgICAgdGhpcy5fbGZvTC5mcmVxdWVuY3kuY29ubmVjdCh0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHNldCB0aGUgb3B0aW9uc1xuICAgICAgICB0aGlzLmJhc2VGcmVxdWVuY3kgPSBvcHRpb25zLmJhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMub2N0YXZlcyA9IG9wdGlvbnMub2N0YXZlcztcbiAgICAgICAgLy8gc3RhcnQgdGhlIGxmb1xuICAgICAgICB0aGlzLl9sZm9MLnN0YXJ0KCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3RhcnQoKTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiZnJlcXVlbmN5XCIsIFwiUVwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMC41LFxuICAgICAgICAgICAgb2N0YXZlczogMyxcbiAgICAgICAgICAgIHN0YWdlczogMTAsXG4gICAgICAgICAgICBROiAxMCxcbiAgICAgICAgICAgIGJhc2VGcmVxdWVuY3k6IDM1MCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIF9tYWtlRmlsdGVycyhzdGFnZXMsIGNvbm5lY3RUb0ZyZXEpIHtcbiAgICAgICAgY29uc3QgZmlsdGVycyA9IFtdO1xuICAgICAgICAvLyBtYWtlIGFsbCB0aGUgZmlsdGVyc1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0YWdlczsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQmlxdWFkRmlsdGVyKCk7XG4gICAgICAgICAgICBmaWx0ZXIudHlwZSA9IFwiYWxscGFzc1wiO1xuICAgICAgICAgICAgdGhpcy5RLmNvbm5lY3QoZmlsdGVyLlEpO1xuICAgICAgICAgICAgY29ubmVjdFRvRnJlcS5jb25uZWN0KGZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICAgICAgZmlsdGVycy5wdXNoKGZpbHRlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbHRlcnM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygb2N0YXZlcyB0aGUgcGhhc2UgZ29lcyBhYm92ZSB0aGUgYmFzZUZyZXF1ZW5jeVxuICAgICAqL1xuICAgIGdldCBvY3RhdmVzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgc2V0IG9jdGF2ZXMob2N0YXZlcykge1xuICAgICAgICB0aGlzLl9vY3RhdmVzID0gb2N0YXZlcztcbiAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5fYmFzZUZyZXF1ZW5jeSAqIE1hdGgucG93KDIsIG9jdGF2ZXMpO1xuICAgICAgICB0aGlzLl9sZm9MLm1heCA9IG1heDtcbiAgICAgICAgdGhpcy5fbGZvUi5tYXggPSBtYXg7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aGUgYmFzZSBmcmVxdWVuY3kgb2YgdGhlIGZpbHRlcnMuXG4gICAgICovXG4gICAgZ2V0IGJhc2VGcmVxdWVuY3koKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9iYXNlRnJlcXVlbmN5O1xuICAgIH1cbiAgICBzZXQgYmFzZUZyZXF1ZW5jeShmcmVxKSB7XG4gICAgICAgIHRoaXMuX2Jhc2VGcmVxdWVuY3kgPSB0aGlzLnRvRnJlcXVlbmN5KGZyZXEpO1xuICAgICAgICB0aGlzLl9sZm9MLm1pbiA9IHRoaXMuX2Jhc2VGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuX2xmb1IubWluID0gdGhpcy5fYmFzZUZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vY3RhdmVzID0gdGhpcy5fb2N0YXZlcztcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9MLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbGZvUi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNMLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuX2ZpbHRlcnNSLmZvckVhY2goZiA9PiBmLmRpc2Nvbm5lY3QoKSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9UGhhc2VyLmpzLm1hcCIsImltcG9ydCB7IF9fYXdhaXRlciB9IGZyb20gXCJ0c2xpYlwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi4vY29tcG9uZW50L2NoYW5uZWwvTWVyZ2VcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTm9pc2UgfSBmcm9tIFwiLi4vc291cmNlL05vaXNlXCI7XG5pbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IE9mZmxpbmVDb250ZXh0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9PZmZsaW5lQ29udGV4dFwiO1xuaW1wb3J0IHsgbm9PcCB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBhc3NlcnRSYW5nZSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvRGVidWdcIjtcbi8qKlxuICogU2ltcGxlIGNvbnZvbHV0aW9uIGNyZWF0ZWQgd2l0aCBkZWNheWluZyBub2lzZS5cbiAqIEdlbmVyYXRlcyBhbiBJbXB1bHNlIFJlc3BvbnNlIEJ1ZmZlclxuICogd2l0aCBUb25lLk9mZmxpbmUgdGhlbiBmZWVkcyB0aGUgSVIgaW50byBDb252b2x2ZXJOb2RlLlxuICogVGhlIGltcHVsc2UgcmVzcG9uc2UgZ2VuZXJhdGlvbiBpcyBhc3luYywgc28geW91IGhhdmVcbiAqIHRvIHdhaXQgdW50aWwgW1tyZWFkeV1dIHJlc29sdmVzIGJlZm9yZSBpdCB3aWxsIG1ha2UgYSBzb3VuZC5cbiAqXG4gKiBJbnNwaXJhdGlvbiBmcm9tIFtSZXZlcmJHZW5dKGh0dHBzOi8vZ2l0aHViLmNvbS9hZGVsZXNwaW5hc3NlL3JldmVyYkdlbikuXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgQWxhbiBkZUxlc3BpbmFzc2UgQXBhY2hlIDIuMCBMaWNlbnNlLlxuICpcbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFJldmVyYiBleHRlbmRzIEVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFJldmVyYi5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImRlY2F5XCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUmV2ZXJiXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb252b2x2ZXIgbm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICAvKipcbiAgICAgICAgICogUmVzb2x2ZXMgd2hlbiB0aGUgcmV2ZXJiIGJ1ZmZlciBpcyBnZW5lcmF0ZWQuIFdoZW5ldmVyIGVpdGhlciBbW2RlY2F5XV1cbiAgICAgICAgICogb3IgW1twcmVEZWxheV1dIGFyZSBzZXQsIHlvdSBoYXZlIHRvIHdhaXQgdW50aWwgW1tyZWFkeV1dIHJlc29sdmVzXG4gICAgICAgICAqIGJlZm9yZSB0aGUgSVIgaXMgZ2VuZXJhdGVkIHdpdGggdGhlIGxhdGVzdCB2YWx1ZXMuXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlYWR5ID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhSZXZlcmIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJkZWNheVwiXSk7XG4gICAgICAgIHRoaXMuX2RlY2F5ID0gb3B0aW9ucy5kZWNheTtcbiAgICAgICAgdGhpcy5fcHJlRGVsYXkgPSBvcHRpb25zLnByZURlbGF5O1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdCh0aGlzLl9jb252b2x2ZXIpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBkZWNheTogMS41LFxuICAgICAgICAgICAgcHJlRGVsYXk6IDAuMDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgZHVyYXRpb24gb2YgdGhlIHJldmVyYi5cbiAgICAgKi9cbiAgICBnZXQgZGVjYXkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNheTtcbiAgICB9XG4gICAgc2V0IGRlY2F5KHRpbWUpIHtcbiAgICAgICAgdGltZSA9IHRoaXMudG9TZWNvbmRzKHRpbWUpO1xuICAgICAgICBhc3NlcnRSYW5nZSh0aW1lLCAwLjAwMSk7XG4gICAgICAgIHRoaXMuX2RlY2F5ID0gdGltZTtcbiAgICAgICAgdGhpcy5nZW5lcmF0ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgYW1vdW50IG9mIHRpbWUgYmVmb3JlIHRoZSByZXZlcmIgaXMgZnVsbHkgcmFtcGVkIGluLlxuICAgICAqL1xuICAgIGdldCBwcmVEZWxheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ByZURlbGF5O1xuICAgIH1cbiAgICBzZXQgcHJlRGVsYXkodGltZSkge1xuICAgICAgICB0aW1lID0gdGhpcy50b1NlY29uZHModGltZSk7XG4gICAgICAgIGFzc2VydFJhbmdlKHRpbWUsIDApO1xuICAgICAgICB0aGlzLl9wcmVEZWxheSA9IHRpbWU7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgdGhlIEltcHVsc2UgUmVzcG9uc2UuIFJldHVybnMgYSBwcm9taXNlIHdoaWxlIHRoZSBJUiBpcyBiZWluZyBnZW5lcmF0ZWQuXG4gICAgICogQHJldHVybiBQcm9taXNlIHdoaWNoIHJldHVybnMgdGhpcyBvYmplY3QuXG4gICAgICovXG4gICAgZ2VuZXJhdGUoKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c1JlYWR5ID0gdGhpcy5yZWFkeTtcbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIG5vaXNlIGJ1cnN0IHdoaWNoIGRlY2F5cyBvdmVyIHRoZSBkdXJhdGlvbiBpbiBlYWNoIGNoYW5uZWxcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgT2ZmbGluZUNvbnRleHQoMiwgdGhpcy5fZGVjYXkgKyB0aGlzLl9wcmVEZWxheSwgdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUpO1xuICAgICAgICAgICAgY29uc3Qgbm9pc2VMID0gbmV3IE5vaXNlKHsgY29udGV4dCB9KTtcbiAgICAgICAgICAgIGNvbnN0IG5vaXNlUiA9IG5ldyBOb2lzZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBjb25zdCBtZXJnZSA9IG5ldyBNZXJnZSh7IGNvbnRleHQgfSk7XG4gICAgICAgICAgICBub2lzZUwuY29ubmVjdChtZXJnZSwgMCwgMCk7XG4gICAgICAgICAgICBub2lzZVIuY29ubmVjdChtZXJnZSwgMCwgMSk7XG4gICAgICAgICAgICBjb25zdCBnYWluTm9kZSA9IG5ldyBHYWluKHsgY29udGV4dCB9KS50b0Rlc3RpbmF0aW9uKCk7XG4gICAgICAgICAgICBtZXJnZS5jb25uZWN0KGdhaW5Ob2RlKTtcbiAgICAgICAgICAgIG5vaXNlTC5zdGFydCgwKTtcbiAgICAgICAgICAgIG5vaXNlUi5zdGFydCgwKTtcbiAgICAgICAgICAgIC8vIHByZWRlbGF5XG4gICAgICAgICAgICBnYWluTm9kZS5nYWluLnNldFZhbHVlQXRUaW1lKDAsIDApO1xuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5zZXRWYWx1ZUF0VGltZSgxLCB0aGlzLl9wcmVEZWxheSk7XG4gICAgICAgICAgICAvLyBkZWNheVxuICAgICAgICAgICAgZ2Fpbk5vZGUuZ2Fpbi5leHBvbmVudGlhbEFwcHJvYWNoVmFsdWVBdFRpbWUoMCwgdGhpcy5fcHJlRGVsYXksIHRoaXMuZGVjYXkpO1xuICAgICAgICAgICAgLy8gcmVuZGVyIHRoZSBidWZmZXJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclByb21pc2UgPSBjb250ZXh0LnJlbmRlcigpO1xuICAgICAgICAgICAgdGhpcy5yZWFkeSA9IHJlbmRlclByb21pc2UudGhlbihub09wKTtcbiAgICAgICAgICAgIC8vIHdhaXQgZm9yIHRoZSBwcmV2aW91cyBgcmVhZHlgIHRvIHJlc29sdmVcbiAgICAgICAgICAgIHlpZWxkIHByZXZpb3VzUmVhZHk7XG4gICAgICAgICAgICAvLyBzZXQgdGhlIGJ1ZmZlclxuICAgICAgICAgICAgdGhpcy5fY29udm9sdmVyLmJ1ZmZlciA9ICh5aWVsZCByZW5kZXJQcm9taXNlKS5nZXQoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1SZXZlcmIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgU3BsaXQgfSBmcm9tIFwiLi9TcGxpdFwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWwgKHdoaWNoIGNvbWVzIG91dCBvZiBib3RoIHRoZSBsZWZ0IGFuZCB0aGUgcmlnaHQgY2hhbm5lbClcbiAqIGFuZCB0aGUgJ3NpZGUnICh3aGljaCBvbmx5IGNvbWVzIG91dCBvZiB0aGUgdGhlIHNpZGUgY2hhbm5lbHMpLlxuICogYGBgXG4gKiBNaWQgPSAoTGVmdCtSaWdodCkvc3FydCgyKTsgICAvLyBvYnRhaW4gbWlkLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBTaWRlID0gKExlZnQtUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIHNpZGUtc2lnbmFsIGZyb20gbGVmdCBhbmQgcmlnaHRcbiAqIGBgYFxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgTWlkU2lkZVNwbGl0IGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1pZFNpZGVTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNaWRTaWRlU3BsaXRcIjtcbiAgICAgICAgdGhpcy5fc3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IFNwbGl0KHtcbiAgICAgICAgICAgIGNoYW5uZWxzOiAyLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9taWRBZGQgPSBuZXcgQWRkKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0ID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLnNpZGUgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fbWlkQWRkLCAwKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9taWRBZGQuYWRkZW5kLCAxKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuY29ubmVjdCh0aGlzLl9zaWRlU3VidHJhY3QsIDApO1xuICAgICAgICB0aGlzLl9zcGxpdC5jb25uZWN0KHRoaXMuX3NpZGVTdWJ0cmFjdC5zdWJ0cmFoZW5kLCAxKTtcbiAgICAgICAgdGhpcy5fbWlkQWRkLmNvbm5lY3QodGhpcy5taWQpO1xuICAgICAgICB0aGlzLl9zaWRlU3VidHJhY3QuY29ubmVjdCh0aGlzLnNpZGUpO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkQWRkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc2lkZVN1YnRyYWN0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlU3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgTWVyZ2UgfSBmcm9tIFwiLi9NZXJnZVwiO1xuaW1wb3J0IHsgQWRkIH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9BZGRcIjtcbmltcG9ydCB7IE11bHRpcGx5IH0gZnJvbSBcIi4uLy4uL3NpZ25hbC9NdWx0aXBseVwiO1xuaW1wb3J0IHsgU3VidHJhY3QgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1N1YnRyYWN0XCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogTWlkU2lkZU1lcmdlIG1lcmdlcyB0aGUgbWlkIGFuZCBzaWRlIHNpZ25hbCBhZnRlciB0aGV5J3ZlIGJlZW4gc2VwYXJhdGVkIGJ5IFtbTWlkU2lkZVNwbGl0XV1cbiAqIGBgYFxuICogTWlkID0gKExlZnQrUmlnaHQpL3NxcnQoMik7ICAgLy8gb2J0YWluIG1pZC1zaWduYWwgZnJvbSBsZWZ0IGFuZCByaWdodFxuICogU2lkZSA9IChMZWZ0LVJpZ2h0KS9zcXJ0KDIpOyAgIC8vIG9idGFpbiBzaWRlLXNpZ25hbCBmcm9tIGxlZnQgYW5kIHJpZ2h0XG4gKiBgYGBcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVNZXJnZSBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlTWVyZ2UuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZU1lcmdlXCI7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuc2lkZSA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9sZWZ0ID0gbmV3IEFkZCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbGVmdE11bHQgPSBuZXcgTXVsdGlwbHkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdmFsdWU6IE1hdGguU1FSVDFfMlxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcmlnaHQgPSBuZXcgU3VidHJhY3QoeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogTWF0aC5TUVJUMV8yXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9tZXJnZSA9IHRoaXMub3V0cHV0ID0gbmV3IE1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZC5mYW4odGhpcy5fbGVmdCk7XG4gICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX2xlZnQuYWRkZW5kKTtcbiAgICAgICAgdGhpcy5taWQuY29ubmVjdCh0aGlzLl9yaWdodCk7XG4gICAgICAgIHRoaXMuc2lkZS5jb25uZWN0KHRoaXMuX3JpZ2h0LnN1YnRyYWhlbmQpO1xuICAgICAgICB0aGlzLl9sZWZ0LmNvbm5lY3QodGhpcy5fbGVmdE11bHQpO1xuICAgICAgICB0aGlzLl9yaWdodC5jb25uZWN0KHRoaXMuX3JpZ2h0TXVsdCk7XG4gICAgICAgIHRoaXMuX2xlZnRNdWx0LmNvbm5lY3QodGhpcy5fbWVyZ2UsIDAsIDApO1xuICAgICAgICB0aGlzLl9yaWdodE11bHQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnNpZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZWZ0TXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3JpZ2h0TXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xlZnQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9yaWdodC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1pZFNpZGVNZXJnZS5qcy5tYXAiLCJpbXBvcnQgeyBFZmZlY3QgfSBmcm9tIFwiLi9FZmZlY3RcIjtcbmltcG9ydCB7IE1pZFNpZGVTcGxpdCB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlU3BsaXRcIjtcbmltcG9ydCB7IE1pZFNpZGVNZXJnZSB9IGZyb20gXCIuLi9jb21wb25lbnQvY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbi8qKlxuICogTWlkL1NpZGUgcHJvY2Vzc2luZyBzZXBhcmF0ZXMgdGhlIHRoZSAnbWlkJyBzaWduYWxcbiAqICh3aGljaCBjb21lcyBvdXQgb2YgYm90aCB0aGUgbGVmdCBhbmQgdGhlIHJpZ2h0IGNoYW5uZWwpXG4gKiBhbmQgdGhlICdzaWRlJyAod2hpY2ggb25seSBjb21lcyBvdXQgb2YgdGhlIHRoZSBzaWRlIGNoYW5uZWxzKVxuICogYW5kIGVmZmVjdHMgdGhlbSBzZXBhcmF0ZWx5IGJlZm9yZSBiZWluZyByZWNvbWJpbmVkLlxuICogQXBwbGllcyBhIE1pZC9TaWRlIHNlcGVyYXRpb24gYW5kIHJlY29tYmluYXRpb24uXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW2t2cmF1ZGlvIGZvcnVtc10oaHR0cDovL3d3dy5rdnJhdWRpby5jb20vZm9ydW0vdmlld3RvcGljLnBocD90PTIxMjU4NykuXG4gKiBUaGlzIGlzIGEgYmFzZS1jbGFzcyBmb3IgTWlkL1NpZGUgRWZmZWN0cy5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVFZmZlY3QgZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIob3B0aW9ucyk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWlkU2lkZUVmZmVjdFwiO1xuICAgICAgICB0aGlzLl9taWRTaWRlTWVyZ2UgPSBuZXcgTWlkU2lkZU1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSBuZXcgTWlkU2lkZVNwbGl0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9taWRTZW5kID0gdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZDtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQgPSB0aGlzLl9taWRTaWRlU3BsaXQuc2lkZTtcbiAgICAgICAgdGhpcy5fbWlkUmV0dXJuID0gdGhpcy5fbWlkU2lkZU1lcmdlLm1pZDtcbiAgICAgICAgdGhpcy5fc2lkZVJldHVybiA9IHRoaXMuX21pZFNpZGVNZXJnZS5zaWRlO1xuICAgICAgICAvLyB0aGUgY29ubmVjdGlvbnNcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNvbm5lY3QodGhpcy5fbWlkU2lkZVNwbGl0KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmNvbm5lY3QodGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IHRoZSBtaWQgY2hhaW4gb2YgdGhlIGVmZmVjdFxuICAgICAqL1xuICAgIGNvbm5lY3RFZmZlY3RNaWQoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fbWlkU2VuZC5jaGFpbiguLi5ub2RlcywgdGhpcy5fbWlkUmV0dXJuKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29ubmVjdCB0aGUgc2lkZSBjaGFpbiBvZiB0aGUgZWZmZWN0XG4gICAgICovXG4gICAgY29ubmVjdEVmZmVjdFNpZGUoLi4ubm9kZXMpIHtcbiAgICAgICAgdGhpcy5fc2lkZVNlbmQuY2hhaW4oLi4ubm9kZXMsIHRoaXMuX3NpZGVSZXR1cm4pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVNZXJnZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFNlbmQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlU2VuZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZFJldHVybi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NpZGVSZXR1cm4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NaWRTaWRlRWZmZWN0LmpzLm1hcCIsImltcG9ydCB7IE1pZFNpZGVFZmZlY3QgfSBmcm9tIFwiLi4vZWZmZWN0L01pZFNpZGVFZmZlY3RcIjtcbmltcG9ydCB7IFNpZ25hbCB9IGZyb20gXCIuLi9zaWduYWwvU2lnbmFsXCI7XG5pbXBvcnQgeyBNdWx0aXBseSB9IGZyb20gXCIuLi9zaWduYWwvTXVsdGlwbHlcIjtcbmltcG9ydCB7IFN1YnRyYWN0IH0gZnJvbSBcIi4uL3NpZ25hbC9TdWJ0cmFjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBjb25uZWN0IH0gZnJvbSBcIi4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG4vKipcbiAqIEFwcGxpZXMgYSB3aWR0aCBmYWN0b3IgdG8gdGhlIG1pZC9zaWRlIHNlcGVyYXRpb24uXG4gKiAwIGlzIGFsbCBtaWQgYW5kIDEgaXMgYWxsIHNpZGUuXG4gKiBBbGdvcml0aG0gZm91bmQgaW4gW2t2cmF1ZGlvIGZvcnVtc10oaHR0cDovL3d3dy5rdnJhdWRpby5jb20vZm9ydW0vdmlld3RvcGljLnBocD90PTIxMjU4NykuXG4gKiBgYGBcbiAqIE1pZCAqPSAyKigxLXdpZHRoKTxicj5cbiAqIFNpZGUgKj0gMip3aWR0aFxuICogYGBgXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBTdGVyZW9XaWRlbmVyIGV4dGVuZHMgTWlkU2lkZUVmZmVjdCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFN0ZXJlb1dpZGVuZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ3aWR0aFwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIlN0ZXJlb1dpZGVuZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFN0ZXJlb1dpZGVuZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ3aWR0aFwiXSk7XG4gICAgICAgIHRoaXMud2lkdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLndpZHRoLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcIndpZHRoXCJdKTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZCA9IG5ldyBNdWx0aXBseSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogMixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhTaWRlID0gbmV3IE11bHRpcGx5KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiAyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkTXVsdCA9IG5ldyBNdWx0aXBseSh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fdHdvVGltZXNXaWR0aE1pZC5jb25uZWN0KHRoaXMuX21pZE11bHQuZmFjdG9yKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TWlkKHRoaXMuX21pZE11bHQpO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoID0gbmV3IFN1YnRyYWN0KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9vbmVNaW51c1dpZHRoLmNvbm5lY3QodGhpcy5fdHdvVGltZXNXaWR0aE1pZCk7XG4gICAgICAgIGNvbm5lY3QodGhpcy5jb250ZXh0LmdldENvbnN0YW50KDEpLCB0aGlzLl9vbmVNaW51c1dpZHRoKTtcbiAgICAgICAgdGhpcy53aWR0aC5jb25uZWN0KHRoaXMuX29uZU1pbnVzV2lkdGguc3VidHJhaGVuZCk7XG4gICAgICAgIHRoaXMuX3NpZGVNdWx0ID0gbmV3IE11bHRpcGx5KHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLndpZHRoLmNvbm5lY3QodGhpcy5fdHdvVGltZXNXaWR0aFNpZGUpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZS5jb25uZWN0KHRoaXMuX3NpZGVNdWx0LmZhY3Rvcik7XG4gICAgICAgIHRoaXMuY29ubmVjdEVmZmVjdFNpZGUodGhpcy5fc2lkZU11bHQpO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1pZFNpZGVFZmZlY3QuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgd2lkdGg6IDAuNSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy53aWR0aC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZE11bHQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9zaWRlTXVsdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3R3b1RpbWVzV2lkdGhNaWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl90d29UaW1lc1dpZHRoU2lkZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX29uZU1pbnVzV2lkdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1TdGVyZW9XaWRlbmVyLmpzLm1hcCIsImltcG9ydCB7IFN0ZXJlb0VmZmVjdCB9IGZyb20gXCIuL1N0ZXJlb0VmZmVjdFwiO1xuaW1wb3J0IHsgTEZPIH0gZnJvbSBcIi4uL3NvdXJjZS9vc2NpbGxhdG9yL0xGT1wiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgU2lnbmFsIH0gZnJvbSBcIi4uL3NpZ25hbC9TaWduYWxcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuLyoqXG4gKiBUcmVtb2xvIG1vZHVsYXRlcyB0aGUgYW1wbGl0dWRlIG9mIGFuIGluY29taW5nIHNpZ25hbCB1c2luZyBhbiBbW0xGT11dLlxuICogVGhlIGVmZmVjdCBpcyBhIHN0ZXJlbyBlZmZlY3Qgd2hlcmUgdGhlIG1vZHVsYXRpb24gcGhhc2UgaXMgaW52ZXJ0ZWQgaW4gZWFjaCBjaGFubmVsLlxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBjcmVhdGUgYSB0cmVtb2xvIGFuZCBzdGFydCBpdCdzIExGT1xuICogY29uc3QgdHJlbW9sbyA9IG5ldyBUb25lLlRyZW1vbG8oOSwgMC43NSkudG9EZXN0aW5hdGlvbigpLnN0YXJ0KCk7XG4gKiAvLyByb3V0ZSBhbiBvc2NpbGxhdG9yIHRocm91Z2ggdGhlIHRyZW1vbG8gYW5kIHN0YXJ0IGl0XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QodHJlbW9sbykuc3RhcnQoKTtcbiAqXG4gKiBAY2F0ZWdvcnkgRWZmZWN0XG4gKi9cbmV4cG9ydCBjbGFzcyBUcmVtb2xvIGV4dGVuZHMgU3RlcmVvRWZmZWN0IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJlbW9sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVHJlbW9sb1wiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoVHJlbW9sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5fbGZvTCA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbGZvUiA9IG5ldyBMRk8oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdHlwZTogb3B0aW9ucy50eXBlLFxuICAgICAgICAgICAgbWluOiAxLFxuICAgICAgICAgICAgbWF4OiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlTCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9hbXBsaXR1ZGVSID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuZnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGVwdGggPSBuZXcgU2lnbmFsKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmRlcHRoLFxuICAgICAgICAgICAgdW5pdHM6IFwibm9ybWFsUmFuZ2VcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0TGVmdCh0aGlzLl9hbXBsaXR1ZGVMKTtcbiAgICAgICAgdGhpcy5jb25uZWN0RWZmZWN0UmlnaHQodGhpcy5fYW1wbGl0dWRlUik7XG4gICAgICAgIHRoaXMuX2xmb0wuY29ubmVjdCh0aGlzLl9hbXBsaXR1ZGVMLmdhaW4pO1xuICAgICAgICB0aGlzLl9sZm9SLmNvbm5lY3QodGhpcy5fYW1wbGl0dWRlUi5nYWluKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kuZmFuKHRoaXMuX2xmb0wuZnJlcXVlbmN5LCB0aGlzLl9sZm9SLmZyZXF1ZW5jeSk7XG4gICAgICAgIHRoaXMuZGVwdGguZmFuKHRoaXMuX2xmb1IuYW1wbGl0dWRlLCB0aGlzLl9sZm9MLmFtcGxpdHVkZSk7XG4gICAgICAgIHRoaXMuc3ByZWFkID0gb3B0aW9ucy5zcHJlYWQ7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oU3RlcmVvRWZmZWN0LmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMTAsXG4gICAgICAgICAgICB0eXBlOiBcInNpbmVcIixcbiAgICAgICAgICAgIGRlcHRoOiAwLjUsXG4gICAgICAgICAgICBzcHJlYWQ6IDE4MCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXJ0IHRoZSB0cmVtb2xvLlxuICAgICAqL1xuICAgIHN0YXJ0KHRpbWUpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zdGFydCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdGFydCh0aW1lKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0b3AgdGhlIHRyZW1vbG8uXG4gICAgICovXG4gICAgc3RvcCh0aW1lKSB7XG4gICAgICAgIHRoaXMuX2xmb0wuc3RvcCh0aW1lKTtcbiAgICAgICAgdGhpcy5fbGZvUi5zdG9wKHRpbWUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3luYyB0aGUgZWZmZWN0IHRvIHRoZSB0cmFuc3BvcnQuXG4gICAgICovXG4gICAgc3luYygpIHtcbiAgICAgICAgdGhpcy5fbGZvTC5zeW5jKCk7XG4gICAgICAgIHRoaXMuX2xmb1Iuc3luYygpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnN5bmNTaWduYWwodGhpcy5mcmVxdWVuY3kpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5zeW5jIHRoZSBmaWx0ZXIgZnJvbSB0aGUgdHJhbnNwb3J0XG4gICAgICovXG4gICAgdW5zeW5jKCkge1xuICAgICAgICB0aGlzLl9sZm9MLnVuc3luYygpO1xuICAgICAgICB0aGlzLl9sZm9SLnVuc3luYygpO1xuICAgICAgICB0aGlzLmNvbnRleHQudHJhbnNwb3J0LnVuc3luY1NpZ25hbCh0aGlzLmZyZXF1ZW5jeSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgb3NjaWxsYXRvciB0eXBlLlxuICAgICAqL1xuICAgIGdldCB0eXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbGZvTC50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmb0wudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuX2xmb1IudHlwZSA9IHR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFtb3VudCBvZiBzdGVyZW8gc3ByZWFkLiBXaGVuIHNldCB0byAwLCBib3RoIExGTydzIHdpbGwgYmUgcGFubmVkIGNlbnRyYWxseS5cbiAgICAgKiBXaGVuIHNldCB0byAxODAsIExGTydzIHdpbGwgYmUgcGFubmVkIGhhcmQgbGVmdCBhbmQgcmlnaHQgcmVzcGVjdGl2ZWx5LlxuICAgICAqL1xuICAgIGdldCBzcHJlYWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9sZm9SLnBoYXNlIC0gdGhpcy5fbGZvTC5waGFzZTsgLy8gMTgwXG4gICAgfVxuICAgIHNldCBzcHJlYWQoc3ByZWFkKSB7XG4gICAgICAgIHRoaXMuX2xmb0wucGhhc2UgPSA5MCAtIChzcHJlYWQgLyAyKTtcbiAgICAgICAgdGhpcy5fbGZvUi5waGFzZSA9IChzcHJlYWQgLyAyKSArIDkwO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2xmb0wuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm9SLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fYW1wbGl0dWRlTC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FtcGxpdHVkZVIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1UcmVtb2xvLmpzLm1hcCIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCIuL0VmZmVjdFwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBMRk8gfSBmcm9tIFwiLi4vc291cmNlL29zY2lsbGF0b3IvTEZPXCI7XG5pbXBvcnQgeyBEZWxheSB9IGZyb20gXCIuLi9jb3JlL2NvbnRleHQvRGVsYXlcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQSBWaWJyYXRvIGVmZmVjdCBjb21wb3NlZCBvZiBhIFRvbmUuRGVsYXkgYW5kIGEgVG9uZS5MRk8uIFRoZSBMRk9cbiAqIG1vZHVsYXRlcyB0aGUgZGVsYXlUaW1lIG9mIHRoZSBkZWxheSwgY2F1c2luZyB0aGUgcGl0Y2ggdG8gcmlzZSBhbmQgZmFsbC5cbiAqIEBjYXRlZ29yeSBFZmZlY3RcbiAqL1xuZXhwb3J0IGNsYXNzIFZpYnJhdG8gZXh0ZW5kcyBFZmZlY3Qge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhWaWJyYXRvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJWaWJyYXRvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhWaWJyYXRvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wiZnJlcXVlbmN5XCIsIFwiZGVwdGhcIl0pO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUgPSBuZXcgRGVsYXkoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZGVsYXlUaW1lOiAwLFxuICAgICAgICAgICAgbWF4RGVsYXk6IG9wdGlvbnMubWF4RGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sZm8gPSBuZXcgTEZPKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHR5cGU6IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICAgIG1heDogb3B0aW9ucy5tYXhEZWxheSxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogb3B0aW9ucy5mcmVxdWVuY3ksXG4gICAgICAgICAgICBwaGFzZTogLTkwIC8vIG9mZnNlIHRoZSBwaGFzZSBzbyB0aGUgcmVzdGluZyBwb3NpdGlvbiBpcyBpbiB0aGUgY2VudGVyXG4gICAgICAgIH0pLnN0YXJ0KCkuY29ubmVjdCh0aGlzLl9kZWxheU5vZGUuZGVsYXlUaW1lKTtcbiAgICAgICAgdGhpcy5mcmVxdWVuY3kgPSB0aGlzLl9sZm8uZnJlcXVlbmN5O1xuICAgICAgICB0aGlzLmRlcHRoID0gdGhpcy5fbGZvLmFtcGxpdHVkZTtcbiAgICAgICAgdGhpcy5kZXB0aC52YWx1ZSA9IG9wdGlvbnMuZGVwdGg7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImZyZXF1ZW5jeVwiLCBcImRlcHRoXCJdKTtcbiAgICAgICAgdGhpcy5lZmZlY3RTZW5kLmNoYWluKHRoaXMuX2RlbGF5Tm9kZSwgdGhpcy5lZmZlY3RSZXR1cm4pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKEVmZmVjdC5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBtYXhEZWxheTogMC4wMDUsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDUsXG4gICAgICAgICAgICBkZXB0aDogMC4xLFxuICAgICAgICAgICAgdHlwZTogXCJzaW5lXCJcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFR5cGUgb2Ygb3NjaWxsYXRvciBhdHRhY2hlZCB0byB0aGUgVmlicmF0by5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xmby50eXBlO1xuICAgIH1cbiAgICBzZXQgdHlwZSh0eXBlKSB7XG4gICAgICAgIHRoaXMuX2xmby50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9kZWxheU5vZGUuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sZm8uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZyZXF1ZW5jeS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZGVwdGguZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1WaWJyYXRvLmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL0F1dG9GaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1dG9QYW5uZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0F1dG9XYWhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0JpdENydXNoZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL0NoZWJ5c2hldlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vQ2hvcnVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9EaXN0b3J0aW9uXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GZWVkYmFja0RlbGF5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GcmVxdWVuY3lTaGlmdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9GcmVldmVyYlwiO1xuZXhwb3J0ICogZnJvbSBcIi4vSkNSZXZlcmJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpbmdQb25nRGVsYXlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BpdGNoU2hpZnRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL1BoYXNlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUmV2ZXJiXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9TdGVyZW9XaWRlbmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9UcmVtb2xvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9WaWJyYXRvXCI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvU3BsaXRcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGFzc2VydCwgYXNzZXJ0UmFuZ2UgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG4vKipcbiAqIFdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgV2ViIEF1ZGlvJ3MgW0FuYWx5c2VyTm9kZV0oaHR0cDovL3dlYmF1ZGlvLmdpdGh1Yi5pby93ZWItYXVkaW8tYXBpLyNpZGwtZGVmLUFuYWx5c2VyTm9kZSkuXG4gKiBFeHRyYWN0cyBGRlQgb3IgV2F2ZWZvcm0gZGF0YSBmcm9tIHRoZSBpbmNvbWluZyBzaWduYWwuXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBBbmFseXNlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhBbmFseXNlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInR5cGVcIiwgXCJzaXplXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQW5hbHlzZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhbmFseXNlciBub2RlLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYnVmZmVyIHRoYXQgdGhlIEZGVCBkYXRhIGlzIHdyaXR0ZW4gdG9cbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2J1ZmZlcnMgPSBbXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKEFuYWx5c2VyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widHlwZVwiLCBcInNpemVcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9nYWluID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX3NwbGl0ID0gbmV3IFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNoYW5uZWxzOiBvcHRpb25zLmNoYW5uZWxzLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5pbnB1dC5jb25uZWN0KHRoaXMuX3NwbGl0KTtcbiAgICAgICAgYXNzZXJ0UmFuZ2Uob3B0aW9ucy5jaGFubmVscywgMSk7XG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgYW5hbHlzZXJzXG4gICAgICAgIGZvciAobGV0IGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgb3B0aW9ucy5jaGFubmVsczsgY2hhbm5lbCsrKSB7XG4gICAgICAgICAgICB0aGlzLl9hbmFseXNlcnNbY2hhbm5lbF0gPSB0aGlzLmNvbnRleHQuY3JlYXRlQW5hbHlzZXIoKTtcbiAgICAgICAgICAgIHRoaXMuX3NwbGl0LmNvbm5lY3QodGhpcy5fYW5hbHlzZXJzW2NoYW5uZWxdLCBjaGFubmVsLCAwKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzZXQgdGhlIHZhbHVlcyBpbml0aWFsbHlcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGU7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgICAgICB0eXBlOiBcImZmdFwiLFxuICAgICAgICAgICAgY2hhbm5lbHM6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSdW4gdGhlIGFuYWx5c2lzIGdpdmVuIHRoZSBjdXJyZW50IHNldHRpbmdzLiBJZiBbW2NoYW5uZWxzXV0gPSAxLFxuICAgICAqIGl0IHdpbGwgcmV0dXJuIGEgRmxvYXQzMkFycmF5LiBJZiBbW2NoYW5uZWxzXV0gPiAxLCBpdCB3aWxsXG4gICAgICogcmV0dXJuIGFuIGFycmF5IG9mIEZsb2F0MzJBcnJheXMgd2hlcmUgZWFjaCBpbmRleCBpbiB0aGUgYXJyYXlcbiAgICAgKiByZXByZXNlbnRzIHRoZSBhbmFseXNpcyBkb25lIG9uIGEgY2hhbm5lbC5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goKGFuYWx5c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5fYnVmZmVyc1tpbmRleF07XG4gICAgICAgICAgICBpZiAodGhpcy5fdHlwZSA9PT0gXCJmZnRcIikge1xuICAgICAgICAgICAgICAgIGFuYWx5c2VyLmdldEZsb2F0RnJlcXVlbmN5RGF0YShidWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodGhpcy5fdHlwZSA9PT0gXCJ3YXZlZm9ybVwiKSB7XG4gICAgICAgICAgICAgICAgYW5hbHlzZXIuZ2V0RmxvYXRUaW1lRG9tYWluRGF0YShidWZmZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMuY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9idWZmZXJzWzBdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcnM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlcnNbMF0uZnJlcXVlbmN5QmluQ291bnQ7XG4gICAgfVxuICAgIHNldCBzaXplKHNpemUpIHtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXJzLmZvckVhY2goKGFuYWx5c2VyLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgYW5hbHlzZXIuZmZ0U2l6ZSA9IHNpemUgKiAyO1xuICAgICAgICAgICAgdGhpcy5fYnVmZmVyc1tpbmRleF0gPSBuZXcgRmxvYXQzMkFycmF5KHNpemUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBjaGFubmVscyB0aGUgYW5hbHlzZXIgZG9lcyB0aGUgYW5hbHlzaXMgb24uIENoYW5uZWxcbiAgICAgKiBzZXBhcmF0aW9uIGlzIGRvbmUgdXNpbmcgW1tTcGxpdF1dXG4gICAgICovXG4gICAgZ2V0IGNoYW5uZWxzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXJzLmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuYWx5c2lzIGZ1bmN0aW9uIHJldHVybmVkIGJ5IGFuYWx5c2VyLmdldFZhbHVlKCksIGVpdGhlciBcImZmdFwiIG9yIFwid2F2ZWZvcm1cIi5cbiAgICAgKi9cbiAgICBnZXQgdHlwZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3R5cGU7XG4gICAgfVxuICAgIHNldCB0eXBlKHR5cGUpIHtcbiAgICAgICAgYXNzZXJ0KHR5cGUgPT09IFwid2F2ZWZvcm1cIiB8fCB0eXBlID09PSBcImZmdFwiLCBgQW5hbHlzZXI6IGludmFsaWQgdHlwZTogJHt0eXBlfWApO1xuICAgICAgICB0aGlzLl90eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogMCByZXByZXNlbnRzIG5vIHRpbWUgYXZlcmFnaW5nIHdpdGggdGhlIGxhc3QgYW5hbHlzaXMgZnJhbWUuXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2Vyc1swXS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQ7XG4gICAgfVxuICAgIHNldCBzbW9vdGhpbmcodmFsKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKGEgPT4gYS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSB2YWwpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2Vycy5mb3JFYWNoKGEgPT4gYS5kaXNjb25uZWN0KCkpO1xuICAgICAgICB0aGlzLl9zcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2dhaW4uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1BbmFseXNlci5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IEFuYWx5c2VyIH0gZnJvbSBcIi4vQW5hbHlzZXJcIjtcbi8qKlxuICogVGhlIGJhc2UgY2xhc3MgZm9yIE1ldGVyaW5nIGNsYXNzZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRlckJhc2UgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXJCYXNlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1ldGVyQmFzZVwiO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBBbmFseXNlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzaXplOiAyNTYsXG4gICAgICAgICAgICB0eXBlOiBcIndhdmVmb3JtXCIsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0ZXJCYXNlLmpzLm1hcCIsImltcG9ydCB7IGdhaW5Ub0RiIH0gZnJvbSBcIi4uLy4uL2NvcmUvdHlwZS9Db252ZXJzaW9uc1wiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXRlckJhc2UgfSBmcm9tIFwiLi9NZXRlckJhc2VcIjtcbmltcG9ydCB7IHdhcm4gfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlYnVnXCI7XG5pbXBvcnQgeyBBbmFseXNlciB9IGZyb20gXCIuL0FuYWx5c2VyXCI7XG4vKipcbiAqIE1ldGVyIGdldHMgdGhlIFtSTVNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1Jvb3RfbWVhbl9zcXVhcmUpXG4gKiBvZiBhbiBpbnB1dCBzaWduYWwuIEl0IGNhbiBhbHNvIGdldCB0aGUgcmF3IHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IG1ldGVyID0gbmV3IFRvbmUuTWV0ZXIoKTtcbiAqIGNvbnN0IG1pYyA9IG5ldyBUb25lLlVzZXJNZWRpYSgpO1xuICogbWljLm9wZW4oKTtcbiAqIC8vIGNvbm5lY3QgbWljIHRvIHRoZSBtZXRlclxuICogbWljLmNvbm5lY3QobWV0ZXIpO1xuICogLy8gdGhlIGN1cnJlbnQgbGV2ZWwgb2YgdGhlIG1pY1xuICogc2V0SW50ZXJ2YWwoKCkgPT4gY29uc29sZS5sb2cobWV0ZXIuZ2V0VmFsdWUoKSksIDEwMCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNZXRlciBleHRlbmRzIE1ldGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKE1ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic21vb3RoaW5nXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiTWV0ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwcmV2aW91cyBmcmFtZSdzIHZhbHVlXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9ybXMgPSAwO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoTWV0ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzbW9vdGhpbmdcIl0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gdGhpcy5vdXRwdXQgPSB0aGlzLl9hbmFseXNlciA9IG5ldyBBbmFseXNlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBzaXplOiAyNTYsXG4gICAgICAgICAgICB0eXBlOiBcIndhdmVmb3JtXCIsXG4gICAgICAgICAgICBjaGFubmVsczogb3B0aW9ucy5jaGFubmVscyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc21vb3RoaW5nID0gb3B0aW9ucy5zbW9vdGhpbmcsXG4gICAgICAgICAgICB0aGlzLm5vcm1hbFJhbmdlID0gb3B0aW9ucy5ub3JtYWxSYW5nZTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihNZXRlckJhc2UuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgc21vb3RoaW5nOiAwLjgsXG4gICAgICAgICAgICBub3JtYWxSYW5nZTogZmFsc2UsXG4gICAgICAgICAgICBjaGFubmVsczogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVzZSBbW2dldFZhbHVlXV0gaW5zdGVhZC4gRm9yIHRoZSBwcmV2aW91cyBnZXRWYWx1ZSBiZWhhdmlvciwgdXNlIERDTWV0ZXIuXG4gICAgICogQGRlcHJlY2F0ZWRcbiAgICAgKi9cbiAgICBnZXRMZXZlbCgpIHtcbiAgICAgICAgd2FybihcIidnZXRMZXZlbCcgaGFzIGJlZW4gY2hhbmdlZCB0byAnZ2V0VmFsdWUnXCIpO1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRWYWx1ZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbC5cbiAgICAgKiBPdXRwdXQgaXMgaW4gZGVjaWJlbHMgd2hlbiBbW25vcm1hbFJhbmdlXV0gaXMgYGZhbHNlYC5cbiAgICAgKiBJZiBbW2NoYW5uZWxzXV0gPSAxLCB0aGVuIHRoZSBvdXRwdXQgaXMgYSBzaW5nbGUgbnVtYmVyXG4gICAgICogcmVwcmVzZW50aW5nIHRoZSB2YWx1ZSBvZiB0aGUgaW5wdXQgc2lnbmFsLiBXaGVuIFtbY2hhbm5lbHNdXSA+IDEsXG4gICAgICogdGhlbiBlYWNoIGNoYW5uZWwgaXMgcmV0dXJuZWQgYXMgYSB2YWx1ZSBpbiBhIG51bWJlciBhcnJheS5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgYVZhbHVlcyA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIGNvbnN0IGNoYW5uZWxWYWx1ZXMgPSB0aGlzLmNoYW5uZWxzID09PSAxID8gW2FWYWx1ZXNdIDogYVZhbHVlcztcbiAgICAgICAgY29uc3QgdmFscyA9IGNoYW5uZWxWYWx1ZXMubWFwKHZhbHVlcyA9PiB7XG4gICAgICAgICAgICBjb25zdCB0b3RhbFNxdWFyZWQgPSB2YWx1ZXMucmVkdWNlKCh0b3RhbCwgY3VycmVudCkgPT4gdG90YWwgKyBjdXJyZW50ICogY3VycmVudCwgMCk7XG4gICAgICAgICAgICBjb25zdCBybXMgPSBNYXRoLnNxcnQodG90YWxTcXVhcmVkIC8gdmFsdWVzLmxlbmd0aCk7XG4gICAgICAgICAgICAvLyB0aGUgcm1zIGNhbiBvbmx5IGZhbGwgYXQgdGhlIHJhdGUgb2YgdGhlIHNtb290aGluZ1xuICAgICAgICAgICAgLy8gYnV0IGNhbiBqdW1wIHVwIGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy5fcm1zID0gTWF0aC5tYXgocm1zLCB0aGlzLl9ybXMgKiB0aGlzLnNtb290aGluZyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ub3JtYWxSYW5nZSA/IHRoaXMuX3JtcyA6IGdhaW5Ub0RiKHRoaXMuX3Jtcyk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAodGhpcy5jaGFubmVscyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbHNbMF07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdmFscztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIG9mIGFuYWx5c2lzLlxuICAgICAqL1xuICAgIGdldCBjaGFubmVscygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2FuYWx5c2VyLmNoYW5uZWxzO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWV0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgZGJUb0dhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IE1ldGVyQmFzZSB9IGZyb20gXCIuL01ldGVyQmFzZVwiO1xuaW1wb3J0IHsgYXNzZXJ0IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWJ1Z1wiO1xuLyoqXG4gKiBHZXQgdGhlIGN1cnJlbnQgZnJlcXVlbmN5IGRhdGEgb2YgdGhlIGNvbm5lY3RlZCBhdWRpbyBzb3VyY2UgdXNpbmcgYSBmYXN0IEZvdXJpZXIgdHJhbnNmb3JtLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgRkZUIGV4dGVuZHMgTWV0ZXJCYXNlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoRkZULmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkZGVFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoRkZULmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic2l6ZVwiXSk7XG4gICAgICAgIHRoaXMubm9ybWFsUmFuZ2UgPSBvcHRpb25zLm5vcm1hbFJhbmdlO1xuICAgICAgICB0aGlzLl9hbmFseXNlci50eXBlID0gXCJmZnRcIjtcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbm9ybWFsUmFuZ2U6IGZhbHNlLFxuICAgICAgICAgICAgc2l6ZTogMTAyNCxcbiAgICAgICAgICAgIHNtb290aGluZzogMC44LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgY3VycmVudCBmcmVxdWVuY3kgZGF0YSBmcm9tIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuICAgICAqIFJldHVybnMgdGhlIGZyZXF1ZW5jeSBkYXRhIG9mIGxlbmd0aCBbW3NpemVdXSBhcyBhIEZsb2F0MzJBcnJheSBvZiBkZWNpYmVsIHZhbHVlcy5cbiAgICAgKi9cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlcy5tYXAodiA9PiB0aGlzLm5vcm1hbFJhbmdlID8gZGJUb0dhaW4odikgOiB2KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgW1tnZXRWYWx1ZV1dIChpLmUuIHRoZSBudW1iZXIgb2ZcbiAgICAgKiBmcmVxdWVuY3kgYmlucykuIExhcmdlIEZGVCBzaXplcyBtYXkgYmUgY29zdGx5IHRvIGNvbXB1dGUuXG4gICAgICovXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9hbmFseXNlci5zaXplO1xuICAgIH1cbiAgICBzZXQgc2l6ZShzaXplKSB7XG4gICAgICAgIHRoaXMuX2FuYWx5c2VyLnNpemUgPSBzaXplO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiAwIHJlcHJlc2VudHMgbm8gdGltZSBhdmVyYWdpbmcgd2l0aCB0aGUgbGFzdCBhbmFseXNpcyBmcmFtZS5cbiAgICAgKi9cbiAgICBnZXQgc21vb3RoaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc21vb3RoaW5nO1xuICAgIH1cbiAgICBzZXQgc21vb3RoaW5nKHZhbCkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zbW9vdGhpbmcgPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZyZXF1ZW5jeSB2YWx1ZSBpbiBoZXJ0eiBvZiBlYWNoIG9mIHRoZSBpbmRpY2VzIG9mIHRoZSBGRlQncyBbW2dldFZhbHVlXV0gcmVzcG9uc2UuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBjb25zdCBmZnQgPSBuZXcgVG9uZS5GRlQoMzIpO1xuICAgICAqIGNvbnNvbGUubG9nKFswLCAxLCAyLCAzLCA0XS5tYXAoaW5kZXggPT4gZmZ0LmdldEZyZXF1ZW5jeU9mSW5kZXgoaW5kZXgpKSk7XG4gICAgICovXG4gICAgZ2V0RnJlcXVlbmN5T2ZJbmRleChpbmRleCkge1xuICAgICAgICBhc3NlcnQoMCA8PSBpbmRleCAmJiBpbmRleCA8IHRoaXMuc2l6ZSwgYGluZGV4IG11c3QgYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIDAgYW5kIGxlc3MgdGhhbiAke3RoaXMuc2l6ZX1gKTtcbiAgICAgICAgcmV0dXJuIGluZGV4ICogdGhpcy5jb250ZXh0LnNhbXBsZVJhdGUgLyAodGhpcy5zaXplICogMik7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RkZULmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG4vKipcbiAqIERDTWV0ZXIgZ2V0cyB0aGUgcmF3IHZhbHVlIG9mIHRoZSBpbnB1dCBzaWduYWwgYXQgdGhlIGN1cnJlbnQgdGltZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbWV0ZXIgPSBuZXcgVG9uZS5EQ01ldGVyKCk7XG4gKiBjb25zdCBtaWMgPSBuZXcgVG9uZS5Vc2VyTWVkaWEoKTtcbiAqIG1pYy5vcGVuKCk7XG4gKiAvLyBjb25uZWN0IG1pYyB0byB0aGUgbWV0ZXJcbiAqIG1pYy5jb25uZWN0KG1ldGVyKTtcbiAqIC8vIHRoZSBjdXJyZW50IGxldmVsIG9mIHRoZSBtaWNcbiAqIGNvbnN0IGxldmVsID0gbWV0ZXIuZ2V0VmFsdWUoKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIERDTWV0ZXIgZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhEQ01ldGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkRDTWV0ZXJcIjtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwid2F2ZWZvcm1cIjtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIuc2l6ZSA9IDI1NjtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBzaWduYWwgdmFsdWUgb2YgdGhlIGluY29taW5nIHNpZ25hbFxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX2FuYWx5c2VyLmdldFZhbHVlKCk7XG4gICAgICAgIHJldHVybiB2YWx1ZVswXTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1EQ01ldGVyLmpzLm1hcCIsImltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWV0ZXJCYXNlIH0gZnJvbSBcIi4vTWV0ZXJCYXNlXCI7XG4vKipcbiAqIEdldCB0aGUgY3VycmVudCB3YXZlZm9ybSBkYXRhIG9mIHRoZSBjb25uZWN0ZWQgYXVkaW8gc291cmNlLlxuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgV2F2ZWZvcm0gZXh0ZW5kcyBNZXRlckJhc2Uge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhXYXZlZm9ybS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNpemVcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJXYXZlZm9ybVwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoV2F2ZWZvcm0uZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJzaXplXCJdKTtcbiAgICAgICAgdGhpcy5fYW5hbHlzZXIudHlwZSA9IFwid2F2ZWZvcm1cIjtcbiAgICAgICAgdGhpcy5zaXplID0gb3B0aW9ucy5zaXplO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE1ldGVyQmFzZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBzaXplOiAxMDI0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJuIHRoZSB3YXZlZm9ybSBmb3IgdGhlIGN1cnJlbnQgdGltZSBhcyBhIEZsb2F0MzJBcnJheSB3aGVyZSBlYWNoIHZhbHVlIGluIHRoZSBhcnJheVxuICAgICAqIHJlcHJlc2VudHMgYSBzYW1wbGUgaW4gdGhlIHdhdmVmb3JtLlxuICAgICAqL1xuICAgIGdldFZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuZ2V0VmFsdWUoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHNpemUgb2YgYW5hbHlzaXMuIFRoaXMgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBpbiB0aGUgcmFuZ2UgMTYgdG8gMTYzODQuXG4gICAgICogRGV0ZXJtaW5lcyB0aGUgc2l6ZSBvZiB0aGUgYXJyYXkgcmV0dXJuZWQgYnkgW1tnZXRWYWx1ZV1dLlxuICAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fYW5hbHlzZXIuc2l6ZTtcbiAgICB9XG4gICAgc2V0IHNpemUoc2l6ZSkge1xuICAgICAgICB0aGlzLl9hbmFseXNlci5zaXplID0gc2l6ZTtcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1XYXZlZm9ybS5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogU29sbyBsZXRzIHlvdSBpc29sYXRlIGEgc3BlY2lmaWMgYXVkaW8gc3RyZWFtLiBXaGVuIGFuIGluc3RhbmNlIGlzIHNldCB0byBgc29sbz10cnVlYCxcbiAqIGl0IHdpbGwgbXV0ZSBhbGwgb3RoZXIgaW5zdGFuY2VzIG9mIFNvbG8uXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgc29sb0EgPSBuZXcgVG9uZS5Tb2xvKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjQSA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJDNFwiLCBcInNhd3Rvb3RoXCIpLmNvbm5lY3Qoc29sb0EpO1xuICogY29uc3Qgc29sb0IgPSBuZXcgVG9uZS5Tb2xvKCkudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3Qgb3NjQiA9IG5ldyBUb25lLk9zY2lsbGF0b3IoXCJFNFwiLCBcInNxdWFyZVwiKS5jb25uZWN0KHNvbG9CKTtcbiAqIHNvbG9BLnNvbG8gPSB0cnVlO1xuICogLy8gbm8gYXVkaW8gd2lsbCBwYXNzIHRocm91Z2ggc29sb0JcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFNvbG8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoU29sby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInNvbG9cIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJTb2xvXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhTb2xvLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wic29sb1wiXSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghU29sby5fYWxsU29sb3MuaGFzKHRoaXMuY29udGV4dCkpIHtcbiAgICAgICAgICAgIFNvbG8uX2FsbFNvbG9zLnNldCh0aGlzLmNvbnRleHQsIG5ldyBTZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgU29sby5fYWxsU29sb3MuZ2V0KHRoaXMuY29udGV4dCkuYWRkKHRoaXMpO1xuICAgICAgICAvLyBzZXQgaW5pdGlhbGx5XG4gICAgICAgIHRoaXMuc29sbyA9IG9wdGlvbnMuc29sbztcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNvbG86IGZhbHNlLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogSXNvbGF0ZXMgdGhpcyBpbnN0YW5jZSBhbmQgbXV0ZXMgYWxsIG90aGVyIGluc3RhbmNlcyBvZiBTb2xvLlxuICAgICAqIE9ubHkgb25lIGluc3RhbmNlIGNhbiBiZSBzb2xvZWQgYXQgYSB0aW1lLiBBIHNvbG9lZFxuICAgICAqIGluc3RhbmNlIHdpbGwgcmVwb3J0IGBzb2xvPWZhbHNlYCB3aGVuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkLlxuICAgICAqL1xuICAgIGdldCBzb2xvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNTb2xvZWQoKTtcbiAgICB9XG4gICAgc2V0IHNvbG8oc29sbykge1xuICAgICAgICBpZiAoc29sbykge1xuICAgICAgICAgICAgdGhpcy5fYWRkU29sbygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuICAgICAgICB9XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmZvckVhY2goaW5zdGFuY2UgPT4gaW5zdGFuY2UuX3VwZGF0ZVNvbG8oKSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIHRoZSBjdXJyZW50IGluc3RhbmNlIGlzIG11dGVkLCBpLmUuIGFub3RoZXIgaW5zdGFuY2UgaXMgc29sb2VkXG4gICAgICovXG4gICAgZ2V0IG11dGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnB1dC5nYWluLnZhbHVlID09PSAwO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBZGQgdGhpcyB0byB0aGUgc29sb2VkIGFycmF5XG4gICAgICovXG4gICAgX2FkZFNvbG8oKSB7XG4gICAgICAgIGlmICghU29sby5fc29sb2VkLmhhcyh0aGlzLmNvbnRleHQpKSB7XG4gICAgICAgICAgICBTb2xvLl9zb2xvZWQuc2V0KHRoaXMuY29udGV4dCwgbmV3IFNldCgpKTtcbiAgICAgICAgfVxuICAgICAgICBTb2xvLl9zb2xvZWQuZ2V0KHRoaXMuY29udGV4dCkuYWRkKHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhpcyBmcm9tIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfcmVtb3ZlU29sbygpIHtcbiAgICAgICAgaWYgKFNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSkge1xuICAgICAgICAgICAgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmRlbGV0ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBJcyB0aGlzIG9uIHRoZSBzb2xvZWQgYXJyYXlcbiAgICAgKi9cbiAgICBfaXNTb2xvZWQoKSB7XG4gICAgICAgIHJldHVybiBTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgJiYgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLmhhcyh0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIG5vIG9uZSBpcyBzb2xvZWRcbiAgICAgKi9cbiAgICBfbm9Tb2xvcygpIHtcbiAgICAgICAgLy8gZWl0aGVyIGRvZXMgbm90IGhhdmUgYW55IHNvbG9lZCBhZGRlZFxuICAgICAgICByZXR1cm4gIVNvbG8uX3NvbG9lZC5oYXModGhpcy5jb250ZXh0KSB8fFxuICAgICAgICAgICAgLy8gb3IgaGFzIGEgc29sbyBzZXQgYnV0IGRvZXNuJ3QgaW5jbHVkZSBhbnkgaXRlbXNcbiAgICAgICAgICAgIChTb2xvLl9zb2xvZWQuaGFzKHRoaXMuY29udGV4dCkgJiYgU29sby5fc29sb2VkLmdldCh0aGlzLmNvbnRleHQpLnNpemUgPT09IDApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTb2xvIHRoZSBjdXJyZW50IGluc3RhbmNlIGFuZCB1bnNvbG8gYWxsIG90aGVyIGluc3RhbmNlcy5cbiAgICAgKi9cbiAgICBfdXBkYXRlU29sbygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lzU29sb2VkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuZ2Fpbi52YWx1ZSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5fbm9Tb2xvcygpKSB7XG4gICAgICAgICAgICAvLyBubyBvbmUgaXMgc29sb2VkXG4gICAgICAgICAgICB0aGlzLmlucHV0LmdhaW4udmFsdWUgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbnB1dC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIFNvbG8uX2FsbFNvbG9zLmdldCh0aGlzLmNvbnRleHQpLmRlbGV0ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5fcmVtb3ZlU29sbygpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIEhvbGQgYWxsIG9mIHRoZSBzb2xvJ2VkIHRyYWNrcyBiZWxvbmdpbmcgdG8gYSBzcGVjaWZpYyBjb250ZXh0XG4gKi9cblNvbG8uX2FsbFNvbG9zID0gbmV3IE1hcCgpO1xuLyoqXG4gKiBIb2xkIHRoZSBjdXJyZW50bHkgc29sbydlZCBpbnN0YW5jZShzKVxuICovXG5Tb2xvLl9zb2xvZWQgPSBuZXcgTWFwKCk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Tb2xvLmpzLm1hcCIsImltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgUGFubmVyIH0gZnJvbSBcIi4vUGFubmVyXCI7XG5pbXBvcnQgeyBWb2x1bWUgfSBmcm9tIFwiLi9Wb2x1bWVcIjtcbi8qKlxuICogUGFuVm9sIGlzIGEgVG9uZS5QYW5uZXIgYW5kIFRvbmUuVm9sdW1lIGluIG9uZS5cbiAqIEBleGFtcGxlXG4gKiAvLyBwYW4gdGhlIGluY29taW5nIHNpZ25hbCBsZWZ0IGFuZCBkcm9wIHRoZSB2b2x1bWVcbiAqIGNvbnN0IHBhblZvbCA9IG5ldyBUb25lLlBhblZvbCgtMC4yNSwgLTEyKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2MgPSBuZXcgVG9uZS5Pc2NpbGxhdG9yKCkuY29ubmVjdChwYW5Wb2wpLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBQYW5Wb2wgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUGFuVm9sLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicGFuXCIsIFwidm9sdW1lXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFuVm9sXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhQYW5Wb2wuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgICAgICB0aGlzLl9wYW5uZXIgPSB0aGlzLmlucHV0ID0gbmV3IFBhbm5lcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYW46IG9wdGlvbnMucGFuLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucGFuID0gdGhpcy5fcGFubmVyLnBhbjtcbiAgICAgICAgdGhpcy5fdm9sdW1lID0gdGhpcy5vdXRwdXQgPSBuZXcgVm9sdW1lKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZvbHVtZTogb3B0aW9ucy52b2x1bWUsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3ZvbHVtZS52b2x1bWU7XG4gICAgICAgIC8vIGNvbm5lY3Rpb25zXG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25uZWN0KHRoaXMuX3ZvbHVtZSk7XG4gICAgICAgIHRoaXMubXV0ZSA9IG9wdGlvbnMubXV0ZTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wicGFuXCIsIFwidm9sdW1lXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG11dGU6IGZhbHNlLFxuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiAxLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTXV0ZS91bm11dGUgdGhlIHZvbHVtZVxuICAgICAqL1xuICAgIGdldCBtdXRlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fdm9sdW1lLm11dGU7XG4gICAgfVxuICAgIHNldCBtdXRlKG11dGUpIHtcbiAgICAgICAgdGhpcy5fdm9sdW1lLm11dGUgPSBtdXRlO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucGFuLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fdm9sdW1lLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy52b2x1bWUuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5Wb2wuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBTb2xvIH0gZnJvbSBcIi4vU29sb1wiO1xuaW1wb3J0IHsgUGFuVm9sIH0gZnJvbSBcIi4vUGFuVm9sXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG4vKipcbiAqIENoYW5uZWwgcHJvdmlkZXMgYSBjaGFubmVsIHN0cmlwIGludGVyZmFjZSB3aXRoIHZvbHVtZSwgcGFuLCBzb2xvIGFuZCBtdXRlIGNvbnRyb2xzLlxuICogU2VlIFtbUGFuVm9sXV0gYW5kIFtbU29sb11dXG4gKiBAZXhhbXBsZVxuICogLy8gcGFuIHRoZSBpbmNvbWluZyBzaWduYWwgbGVmdCBhbmQgZHJvcCB0aGUgdm9sdW1lIDEyZGJcbiAqIGNvbnN0IGNoYW5uZWwgPSBuZXcgVG9uZS5DaGFubmVsKC0wLjI1LCAtMTIpO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgQ2hhbm5lbCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDaGFubmVsLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widm9sdW1lXCIsIFwicGFuXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiQ2hhbm5lbFwiO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ2hhbm5lbC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInZvbHVtZVwiLCBcInBhblwiXSk7XG4gICAgICAgIHRoaXMuX3NvbG8gPSB0aGlzLmlucHV0ID0gbmV3IFNvbG8oe1xuICAgICAgICAgICAgc29sbzogb3B0aW9ucy5zb2xvLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fcGFuVm9sID0gdGhpcy5vdXRwdXQgPSBuZXcgUGFuVm9sKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhbjogb3B0aW9ucy5wYW4sXG4gICAgICAgICAgICB2b2x1bWU6IG9wdGlvbnMudm9sdW1lLFxuICAgICAgICAgICAgbXV0ZTogb3B0aW9ucy5tdXRlLFxuICAgICAgICAgICAgY2hhbm5lbENvdW50OiBvcHRpb25zLmNoYW5uZWxDb3VudFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wYW4gPSB0aGlzLl9wYW5Wb2wucGFuO1xuICAgICAgICB0aGlzLnZvbHVtZSA9IHRoaXMuX3BhblZvbC52b2x1bWU7XG4gICAgICAgIHRoaXMuX3NvbG8uY29ubmVjdCh0aGlzLl9wYW5Wb2wpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJwYW5cIiwgXCJ2b2x1bWVcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgcGFuOiAwLFxuICAgICAgICAgICAgdm9sdW1lOiAwLFxuICAgICAgICAgICAgbXV0ZTogZmFsc2UsXG4gICAgICAgICAgICBzb2xvOiBmYWxzZSxcbiAgICAgICAgICAgIGNoYW5uZWxDb3VudDogMSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNvbG8vdW5zb2xvIHRoZSBjaGFubmVsLiBTb2xvaW5nIGlzIG9ubHkgcmVsYXRpdmUgdG8gb3RoZXIgW1tDaGFubmVsc11dIGFuZCBbW1NvbG9dXSBpbnN0YW5jZXNcbiAgICAgKi9cbiAgICBnZXQgc29sbygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvbG8uc29sbztcbiAgICB9XG4gICAgc2V0IHNvbG8oc29sbykge1xuICAgICAgICB0aGlzLl9zb2xvLnNvbG8gPSBzb2xvO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB0aGUgY3VycmVudCBpbnN0YW5jZSBpcyBtdXRlZCwgaS5lLiBhbm90aGVyIGluc3RhbmNlIGlzIHNvbG9lZCxcbiAgICAgKiBvciB0aGUgY2hhbm5lbCBpcyBtdXRlZFxuICAgICAqL1xuICAgIGdldCBtdXRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NvbG8ubXV0ZWQgfHwgdGhpcy5tdXRlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBNdXRlL3VubXV0ZSB0aGUgdm9sdW1lXG4gICAgICovXG4gICAgZ2V0IG11dGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5Wb2wubXV0ZTtcbiAgICB9XG4gICAgc2V0IG11dGUobXV0ZSkge1xuICAgICAgICB0aGlzLl9wYW5Wb2wubXV0ZSA9IG11dGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgZ2FpbiBub2RlIGJlbG9uZ2luZyB0byB0aGUgYnVzIG5hbWUuIENyZWF0ZSBpdCBpZlxuICAgICAqIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYnVzIG5hbWVcbiAgICAgKi9cbiAgICBfZ2V0QnVzKG5hbWUpIHtcbiAgICAgICAgaWYgKCFDaGFubmVsLmJ1c2VzLmhhcyhuYW1lKSkge1xuICAgICAgICAgICAgQ2hhbm5lbC5idXNlcy5zZXQobmFtZSwgbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBDaGFubmVsLmJ1c2VzLmdldChuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU2VuZCBhdWRpbyB0byBhbm90aGVyIGNoYW5uZWwgdXNpbmcgYSBzdHJpbmcuIGBzZW5kYCBpcyBhIGxvdCBsaWtlXG4gICAgICogW1tjb25uZWN0XV0sIGV4Y2VwdCBpdCB1c2VzIGEgc3RyaW5nIGluc3RlYWQgb2YgYW4gb2JqZWN0LiBUaGlzIGNhblxuICAgICAqIGJlIHVzZWZ1bCBpbiBsYXJnZSBhcHBsaWNhdGlvbnMgdG8gZGVjb3VwbGUgc2VjdGlvbnMgc2luY2UgW1tzZW5kXV1cbiAgICAgKiBhbmQgW1tyZWNlaXZlXV0gY2FuIGJlIGludm9rZWQgc2VwYXJhdGVseSBpbiBvcmRlciB0byBjb25uZWN0IGFuIG9iamVjdFxuICAgICAqIEBwYXJhbSBuYW1lIFRoZSBjaGFubmVsIG5hbWUgdG8gc2VuZCB0aGUgYXVkaW9cbiAgICAgKiBAcGFyYW0gdm9sdW1lIFRoZSBhbW91bnQgb2YgdGhlIHNpZ25hbCB0byBzZW5kLlxuICAgICAqIFx0RGVmYXVsdHMgdG8gMGRiLCBpLmUuIHNlbmQgdGhlIGVudGlyZSBzaWduYWxcbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIHRoZSBnYWluIG5vZGUgb2YgdGhpcyBjb25uZWN0aW9uLlxuICAgICAqL1xuICAgIHNlbmQobmFtZSwgdm9sdW1lID0gMCkge1xuICAgICAgICBjb25zdCBidXMgPSB0aGlzLl9nZXRCdXMobmFtZSk7XG4gICAgICAgIGNvbnN0IHNlbmRLbm9iID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgICAgIGdhaW46IHZvbHVtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY29ubmVjdChzZW5kS25vYik7XG4gICAgICAgIHNlbmRLbm9iLmNvbm5lY3QoYnVzKTtcbiAgICAgICAgcmV0dXJuIHNlbmRLbm9iO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWNlaXZlIGF1ZGlvIGZyb20gYSBjaGFubmVsIHdoaWNoIHdhcyBjb25uZWN0ZWQgd2l0aCBbW3NlbmRdXS5cbiAgICAgKiBAcGFyYW0gbmFtZSBUaGUgY2hhbm5lbCBuYW1lIHRvIHJlY2VpdmUgYXVkaW8gZnJvbS5cbiAgICAgKi9cbiAgICByZWNlaXZlKG5hbWUpIHtcbiAgICAgICAgY29uc3QgYnVzID0gdGhpcy5fZ2V0QnVzKG5hbWUpO1xuICAgICAgICBidXMuY29ubmVjdCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fcGFuVm9sLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wYW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnZvbHVtZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3NvbG8uZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vKipcbiAqIFN0b3JlIHRoZSBzZW5kL3JlY2VpdmUgY2hhbm5lbHMgYnkgbmFtZS5cbiAqL1xuQ2hhbm5lbC5idXNlcyA9IG5ldyBNYXAoKTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNoYW5uZWwuanMubWFwIiwiaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBNZXJnZSB9IGZyb20gXCIuL01lcmdlXCI7XG4vKipcbiAqIE1vbm8gY29lcmNlcyB0aGUgaW5jb21pbmcgbW9ubyBvciBzdGVyZW8gc2lnbmFsIGludG8gYSBtb25vIHNpZ25hbFxuICogd2hlcmUgYm90aCBsZWZ0IGFuZCByaWdodCBjaGFubmVscyBoYXZlIHRoZSBzYW1lIHZhbHVlLiBUaGlzIGNhbiBiZSB1c2VmdWxcbiAqIGZvciBbc3RlcmVvIGltYWdpbmddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N0ZXJlb19pbWFnaW5nKS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1vbm8gZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoTW9uby5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNb25vXCI7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWVyZ2UgPSB0aGlzLm91dHB1dCA9IG5ldyBNZXJnZSh7XG4gICAgICAgICAgICBjaGFubmVsczogMixcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9tZXJnZSwgMCwgMSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWVyZ2UuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmlucHV0LmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TW9uby5qcy5tYXAiLCJpbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IHJlYWRPbmx5LCB3cml0YWJsZSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiLi4vLi4vc2lnbmFsL1NpZ25hbFwiO1xuaW1wb3J0IHsgRmlsdGVyIH0gZnJvbSBcIi4uL2ZpbHRlci9GaWx0ZXJcIjtcbi8qKlxuICogU3BsaXQgdGhlIGluY29taW5nIHNpZ25hbCBpbnRvIHRocmVlIGJhbmRzIChsb3csIG1pZCwgaGlnaClcbiAqIHdpdGggdHdvIGNyb3Nzb3ZlciBmcmVxdWVuY3kgY29udHJvbHMuXG4gKiBgYGBcbiAqICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiAgICAgICAgICArLT4gaW5wdXQgPCBsb3dGcmVxdWVuY3kgKy0tLS0tLS0tLS0tLS0tLS0tLT4gbG93XG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgfFxuICogICAgICAgICAgfCArLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rXG4gKiBpbnB1dCAtLS0rLT4gbG93RnJlcXVlbmN5IDwgaW5wdXQgPCBoaWdoRnJlcXVlbmN5ICstLT4gbWlkXG4gKiAgICAgICAgICB8ICstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLStcbiAqICAgICAgICAgIHxcbiAqICAgICAgICAgIHwgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgKy0+IGhpZ2hGcmVxdWVuY3kgPCBpbnB1dCArLS0tLS0tLS0tLS0tLS0tLS0+IGhpZ2hcbiAqICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tK1xuICogYGBgXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBNdWx0aWJhbmRTcGxpdCBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRTcGxpdC5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aWJhbmRTcGxpdFwiO1xuICAgICAgICAvKipcbiAgICAgICAgICogdGhlIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBubyBvdXRwdXQgbm9kZSwgdXNlIGVpdGhlciBsb3csIG1pZCBvciBoaWdoIG91dHB1dHNcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMub3V0cHV0ID0gdW5kZWZpbmVkO1xuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIGxvdyBiYW5kLlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sb3cgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBsb3dlciBmaWx0ZXIgb2YgdGhlIG1pZCBiYW5kXG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwiaGlnaHBhc3NcIixcbiAgICAgICAgfSk7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWlkIGJhbmQgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5taWQgPSBuZXcgRmlsdGVyKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGZyZXF1ZW5jeTogMCxcbiAgICAgICAgICAgIHR5cGU6IFwibG93cGFzc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBoaWdoIGJhbmQgb3V0cHV0LlxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5oaWdoID0gbmV3IEZpbHRlcih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBmcmVxdWVuY3k6IDAsXG4gICAgICAgICAgICB0eXBlOiBcImhpZ2hwYXNzXCIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW3RoaXMubG93LCB0aGlzLm1pZCwgdGhpcy5oaWdoXTtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKE11bHRpYmFuZFNwbGl0LmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5ID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJmcmVxdWVuY3lcIixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmxvd0ZyZXF1ZW5jeSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IG5ldyBTaWduYWwoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgdW5pdHM6IFwiZnJlcXVlbmN5XCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5LFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5RID0gbmV3IFNpZ25hbCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICB1bml0czogXCJwb3NpdGl2ZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMuUSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQuZmFuKHRoaXMubG93LCB0aGlzLmhpZ2gpO1xuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2xvd01pZEZpbHRlciwgdGhpcy5taWQpO1xuICAgICAgICAvLyB0aGUgZnJlcXVlbmN5IGNvbnRyb2wgc2lnbmFsXG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmZhbih0aGlzLmxvdy5mcmVxdWVuY3ksIHRoaXMuX2xvd01pZEZpbHRlci5mcmVxdWVuY3kpO1xuICAgICAgICB0aGlzLmhpZ2hGcmVxdWVuY3kuZmFuKHRoaXMubWlkLmZyZXF1ZW5jeSwgdGhpcy5oaWdoLmZyZXF1ZW5jeSk7XG4gICAgICAgIC8vIHRoZSBRIHZhbHVlXG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMubG93LlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLl9sb3dNaWRGaWx0ZXIuUSk7XG4gICAgICAgIHRoaXMuUS5jb25uZWN0KHRoaXMubWlkLlEpO1xuICAgICAgICB0aGlzLlEuY29ubmVjdCh0aGlzLmhpZ2guUSk7XG4gICAgICAgIHJlYWRPbmx5KHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIFE6IDEsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyNTAwLFxuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiA0MDAsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDbGVhbiB1cC5cbiAgICAgKi9cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHdyaXRhYmxlKHRoaXMsIFtcImhpZ2hcIiwgXCJtaWRcIiwgXCJsb3dcIiwgXCJoaWdoRnJlcXVlbmN5XCIsIFwibG93RnJlcXVlbmN5XCJdKTtcbiAgICAgICAgdGhpcy5sb3cuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9sb3dNaWRGaWx0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLm1pZC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuaGlnaC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5RLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TXVsdGliYW5kU3BsaXQuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuL1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4vUGFyYW1cIjtcbmltcG9ydCB7IG9uQ29udGV4dENsb3NlLCBvbkNvbnRleHRJbml0IH0gZnJvbSBcIi4vQ29udGV4dEluaXRpYWxpemF0aW9uXCI7XG4vKipcbiAqIFRvbmUuTGlzdGVuZXIgaXMgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBBdWRpb0xpc3RlbmVyLiBMaXN0ZW5lciBjb21iaW5lZFxuICogd2l0aCBbW1Bhbm5lcjNEXV0gbWFrZXMgdXAgdGhlIFdlYiBBdWRpbyBBUEkncyAzRCBwYW5uaW5nIHN5c3RlbS4gUGFubmVyM0QgYWxsb3dzIHlvdVxuICogdG8gcGxhY2Ugc291bmRzIGluIDNEIGFuZCBMaXN0ZW5lciBhbGxvd3MgeW91IHRvIG5hdmlnYXRlIHRoZSAzRCBzb3VuZCBlbnZpcm9ubWVudCBmcm9tXG4gKiBhIGZpcnN0LXBlcnNvbiBwZXJzcGVjdGl2ZS4gVGhlcmUgaXMgb25seSBvbmUgbGlzdGVuZXIgcGVyIGF1ZGlvIGNvbnRleHQuXG4gKi9cbmV4cG9ydCBjbGFzcyBMaXN0ZW5lciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkxpc3RlbmVyXCI7XG4gICAgICAgIHRoaXMucG9zaXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5wb3NpdGlvblgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIucG9zaXRpb25ZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnBvc2l0aW9uWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFggPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLmZvcndhcmRYLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIuZm9yd2FyZFksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmZvcndhcmRaID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci5mb3J3YXJkWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBYID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLmNvbnRleHQucmF3Q29udGV4dC5saXN0ZW5lci51cFgsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnVwWSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5jb250ZXh0LnJhd0NvbnRleHQubGlzdGVuZXIudXBZLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cFogPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuY29udGV4dC5yYXdDb250ZXh0Lmxpc3RlbmVyLnVwWixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBwb3NpdGlvblg6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblk6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblo6IDAsXG4gICAgICAgICAgICBmb3J3YXJkWDogMCxcbiAgICAgICAgICAgIGZvcndhcmRZOiAwLFxuICAgICAgICAgICAgZm9yd2FyZFo6IC0xLFxuICAgICAgICAgICAgdXBYOiAwLFxuICAgICAgICAgICAgdXBZOiAxLFxuICAgICAgICAgICAgdXBaOiAwLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmZvcndhcmRYLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5mb3J3YXJkWS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuZm9yd2FyZFouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnVwWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudXBZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy51cFouZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFx0SU5JVElBTElaQVRJT05cbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxub25Db250ZXh0SW5pdChjb250ZXh0ID0+IHtcbiAgICBjb250ZXh0Lmxpc3RlbmVyID0gbmV3IExpc3RlbmVyKHsgY29udGV4dCB9KTtcbn0pO1xub25Db250ZXh0Q2xvc2UoY29udGV4dCA9PiB7XG4gICAgY29udGV4dC5saXN0ZW5lci5kaXNwb3NlKCk7XG59KTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxpc3RlbmVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgXCIuLi8uLi9jb3JlL2NvbnRleHQvTGlzdGVuZXJcIjtcbi8qKlxuICogQSBzcGF0aWFsaXplZCBwYW5uZXIgbm9kZSB3aGljaCBzdXBwb3J0cyBlcXVhbHBvd2VyIG9yIEhSVEYgcGFubmluZy5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFBhbm5lcjNEIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lcjNELmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicG9zaXRpb25YXCIsIFwicG9zaXRpb25ZXCIsIFwicG9zaXRpb25aXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUGFubmVyM0RcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFBhbm5lcjNELmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1wicG9zaXRpb25YXCIsIFwicG9zaXRpb25ZXCIsIFwicG9zaXRpb25aXCJdKTtcbiAgICAgICAgdGhpcy5fcGFubmVyID0gdGhpcy5pbnB1dCA9IHRoaXMub3V0cHV0ID0gdGhpcy5jb250ZXh0LmNyZWF0ZVBhbm5lcigpO1xuICAgICAgICAvLyBzZXQgc29tZSB2YWx1ZXNcbiAgICAgICAgdGhpcy5wYW5uaW5nTW9kZWwgPSBvcHRpb25zLnBhbm5pbmdNb2RlbDtcbiAgICAgICAgdGhpcy5tYXhEaXN0YW5jZSA9IG9wdGlvbnMubWF4RGlzdGFuY2U7XG4gICAgICAgIHRoaXMuZGlzdGFuY2VNb2RlbCA9IG9wdGlvbnMuZGlzdGFuY2VNb2RlbDtcbiAgICAgICAgdGhpcy5jb25lT3V0ZXJHYWluID0gb3B0aW9ucy5jb25lT3V0ZXJHYWluO1xuICAgICAgICB0aGlzLmNvbmVPdXRlckFuZ2xlID0gb3B0aW9ucy5jb25lT3V0ZXJBbmdsZTtcbiAgICAgICAgdGhpcy5jb25lSW5uZXJBbmdsZSA9IG9wdGlvbnMuY29uZUlubmVyQW5nbGU7XG4gICAgICAgIHRoaXMucmVmRGlzdGFuY2UgPSBvcHRpb25zLnJlZkRpc3RhbmNlO1xuICAgICAgICB0aGlzLnJvbGxvZmZGYWN0b3IgPSBvcHRpb25zLnJvbGxvZmZGYWN0b3I7XG4gICAgICAgIHRoaXMucG9zaXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIucG9zaXRpb25YLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucG9zaXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5wb3NpdGlvblksXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5wb3NpdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLnBvc2l0aW9uWixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLnBvc2l0aW9uWixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25YID0gbmV3IFBhcmFtKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9wYW5uZXIub3JpZW50YXRpb25YLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMub3JpZW50YXRpb25YLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblkgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX3Bhbm5lci5vcmllbnRhdGlvblksXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5vcmllbnRhdGlvblksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWiA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fcGFubmVyLm9yaWVudGF0aW9uWixcbiAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLm9yaWVudGF0aW9uWixcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBjb25lSW5uZXJBbmdsZTogMzYwLFxuICAgICAgICAgICAgY29uZU91dGVyQW5nbGU6IDM2MCxcbiAgICAgICAgICAgIGNvbmVPdXRlckdhaW46IDAsXG4gICAgICAgICAgICBkaXN0YW5jZU1vZGVsOiBcImludmVyc2VcIixcbiAgICAgICAgICAgIG1heERpc3RhbmNlOiAxMDAwMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWDogMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWTogMCxcbiAgICAgICAgICAgIG9yaWVudGF0aW9uWjogMCxcbiAgICAgICAgICAgIHBhbm5pbmdNb2RlbDogXCJlcXVhbHBvd2VyXCIsXG4gICAgICAgICAgICBwb3NpdGlvblg6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblk6IDAsXG4gICAgICAgICAgICBwb3NpdGlvblo6IDAsXG4gICAgICAgICAgICByZWZEaXN0YW5jZTogMSxcbiAgICAgICAgICAgIHJvbGxvZmZGYWN0b3I6IDEsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc291cmNlIGluIDNkIHNwYWNlLlxuICAgICAqL1xuICAgIHNldFBvc2l0aW9uKHgsIHksIHopIHtcbiAgICAgICAgdGhpcy5wb3NpdGlvblgudmFsdWUgPSB4O1xuICAgICAgICB0aGlzLnBvc2l0aW9uWS52YWx1ZSA9IHk7XG4gICAgICAgIHRoaXMucG9zaXRpb25aLnZhbHVlID0gejtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNldHMgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBzb3VyY2UgaW4gM2Qgc3BhY2UuXG4gICAgICovXG4gICAgc2V0T3JpZW50YXRpb24oeCwgeSwgeikge1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWC52YWx1ZSA9IHg7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZLnZhbHVlID0geTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvbloudmFsdWUgPSB6O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIHBhbm5pbmcgbW9kZWwuIEVpdGhlciBcImVxdWFscG93ZXJcIiBvciBcIkhSVEZcIi5cbiAgICAgKi9cbiAgICBnZXQgcGFubmluZ01vZGVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbDtcbiAgICB9XG4gICAgc2V0IHBhbm5pbmdNb2RlbCh2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLnBhbm5pbmdNb2RlbCA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWZlcmVuY2UgZGlzdGFuY2UgZm9yIHJlZHVjaW5nIHZvbHVtZSBhcyBzb3VyY2UgbW92ZSBmdXJ0aGVyIGZyb20gdGhlIGxpc3RlbmVyXG4gICAgICovXG4gICAgZ2V0IHJlZkRpc3RhbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnJlZkRpc3RhbmNlO1xuICAgIH1cbiAgICBzZXQgcmVmRGlzdGFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5yZWZEaXN0YW5jZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVzY3JpYmVzIGhvdyBxdWlja2x5IHRoZSB2b2x1bWUgaXMgcmVkdWNlZCBhcyBzb3VyY2UgbW92ZXMgYXdheSBmcm9tIGxpc3RlbmVyLlxuICAgICAqL1xuICAgIGdldCByb2xsb2ZmRmFjdG9yKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLnJvbGxvZmZGYWN0b3I7XG4gICAgfVxuICAgIHNldCByb2xsb2ZmRmFjdG9yKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIucm9sbG9mZkZhY3RvciA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGRpc3RhbmNlIG1vZGVsIHVzZWQgYnksICBcImxpbmVhclwiLCBcImludmVyc2VcIiwgb3IgXCJleHBvbmVudGlhbFwiLlxuICAgICAqL1xuICAgIGdldCBkaXN0YW5jZU1vZGVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmRpc3RhbmNlTW9kZWw7XG4gICAgfVxuICAgIHNldCBkaXN0YW5jZU1vZGVsKHZhbCkge1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzdGFuY2VNb2RlbCA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuZ2xlLCBpbiBkZWdyZWVzLCBpbnNpZGUgb2Ygd2hpY2ggdGhlcmUgd2lsbCBiZSBubyB2b2x1bWUgcmVkdWN0aW9uXG4gICAgICovXG4gICAgZ2V0IGNvbmVJbm5lckFuZ2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVJbm5lckFuZ2xlO1xuICAgIH1cbiAgICBzZXQgY29uZUlubmVyQW5nbGUodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lSW5uZXJBbmdsZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGFuZ2xlLCBpbiBkZWdyZWVzLCBvdXRzaWRlIG9mIHdoaWNoIHRoZSB2b2x1bWUgd2lsbCBiZSByZWR1Y2VkXG4gICAgICogdG8gYSBjb25zdGFudCB2YWx1ZSBvZiBjb25lT3V0ZXJHYWluXG4gICAgICovXG4gICAgZ2V0IGNvbmVPdXRlckFuZ2xlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLmNvbmVPdXRlckFuZ2xlO1xuICAgIH1cbiAgICBzZXQgY29uZU91dGVyQW5nbGUodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJBbmdsZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVGhlIGdhaW4gb3V0c2lkZSBvZiB0aGUgY29uZU91dGVyQW5nbGVcbiAgICAgKi9cbiAgICBnZXQgY29uZU91dGVyR2FpbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bhbm5lci5jb25lT3V0ZXJHYWluO1xuICAgIH1cbiAgICBzZXQgY29uZU91dGVyR2Fpbih2YWwpIHtcbiAgICAgICAgdGhpcy5fcGFubmVyLmNvbmVPdXRlckdhaW4gPSB2YWw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtYXhpbXVtIGRpc3RhbmNlIGJldHdlZW4gc291cmNlIGFuZCBsaXN0ZW5lcixcbiAgICAgKiBhZnRlciB3aGljaCB0aGUgdm9sdW1lIHdpbGwgbm90IGJlIHJlZHVjZWQgYW55IGZ1cnRoZXIuXG4gICAgICovXG4gICAgZ2V0IG1heERpc3RhbmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFubmVyLm1heERpc3RhbmNlO1xuICAgIH1cbiAgICBzZXQgbWF4RGlzdGFuY2UodmFsKSB7XG4gICAgICAgIHRoaXMuX3Bhbm5lci5tYXhEaXN0YW5jZSA9IHZhbDtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9wYW5uZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLm9yaWVudGF0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMub3JpZW50YXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vcmllbnRhdGlvblouZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnBvc2l0aW9uWC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucG9zaXRpb25ZLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5wb3NpdGlvblouZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1QYW5uZXIzRC5qcy5tYXAiLCJpbXBvcnQgeyBfX2F3YWl0ZXIgfSBmcm9tIFwidHNsaWJcIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IGFzc2VydCB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVidWdcIjtcbmltcG9ydCB7IHRoZVdpbmRvdyB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvQXVkaW9Db250ZXh0XCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbi8qKlxuICogQSB3cmFwcGVyIGFyb3VuZCB0aGUgTWVkaWFSZWNvcmRlciBBUEkuIFVubGlrZSB0aGUgcmVzdCBvZiBUb25lLmpzLCB0aGlzIG1vZHVsZSBkb2VzIG5vdCBvZmZlclxuICogYW55IHNhbXBsZS1hY2N1cmF0ZSBzY2hlZHVsaW5nIGJlY2F1c2UgaXQgaXMgbm90IGEgZmVhdHVyZSBvZiB0aGUgTWVkaWFSZWNvcmRlciBBUEkuXG4gKiBUaGlzIGlzIG9ubHkgbmF0aXZlbHkgc3VwcG9ydGVkIGluIENocm9tZSBhbmQgRmlyZWZveC5cbiAqIEZvciBhIGNyb3NzLWJyb3dzZXIgc2hpbSwgaW5zdGFsbCAoYXVkaW8tcmVjb3JkZXItcG9seWZpbGwpW2h0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2F1ZGlvLXJlY29yZGVyLXBvbHlmaWxsXS5cbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZWNvcmRlciA9IG5ldyBUb25lLlJlY29yZGVyKCk7XG4gKiBjb25zdCBzeW50aCA9IG5ldyBUb25lLlN5bnRoKCkuY29ubmVjdChyZWNvcmRlcik7XG4gKiAvLyBzdGFydCByZWNvcmRpbmdcbiAqIHJlY29yZGVyLnN0YXJ0KCk7XG4gKiAvLyBnZW5lcmF0ZSBhIGZldyBub3Rlc1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDM1wiLCAwLjUpO1xuICogc3ludGgudHJpZ2dlckF0dGFja1JlbGVhc2UoXCJDNFwiLCAwLjUsIFwiKzFcIik7XG4gKiBzeW50aC50cmlnZ2VyQXR0YWNrUmVsZWFzZShcIkM1XCIsIDAuNSwgXCIrMlwiKTtcbiAqIC8vIHdhaXQgZm9yIHRoZSBub3RlcyB0byBlbmQgYW5kIHN0b3AgdGhlIHJlY29yZGluZ1xuICogc2V0VGltZW91dChhc3luYyAoKSA9PiB7XG4gKiBcdC8vIHRoZSByZWNvcmRlZCBhdWRpbyBpcyByZXR1cm5lZCBhcyBhIGJsb2JcbiAqIFx0Y29uc3QgcmVjb3JkaW5nID0gYXdhaXQgcmVjb3JkZXIuc3RvcCgpO1xuICogXHQvLyBkb3dubG9hZCB0aGUgcmVjb3JkaW5nIGJ5IGNyZWF0aW5nIGFuIGFuY2hvciBlbGVtZW50IGFuZCBibG9iIHVybFxuICogXHRjb25zdCB1cmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKHJlY29yZGluZyk7XG4gKiBcdGNvbnN0IGFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJhXCIpO1xuICogXHRhbmNob3IuZG93bmxvYWQgPSBcInJlY29yZGluZy53ZWJtXCI7XG4gKiBcdGFuY2hvci5ocmVmID0gdXJsO1xuICogXHRhbmNob3IuY2xpY2soKTtcbiAqIH0sIDQwMDApO1xuICogQGNhdGVnb3J5IENvbXBvbmVudFxuICovXG5leHBvcnQgY2xhc3MgUmVjb3JkZXIgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIob3B0aW9uc0Zyb21Bcmd1bWVudHMoUmVjb3JkZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiUmVjb3JkZXJcIjtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IG9wdGlvbnNGcm9tQXJndW1lbnRzKFJlY29yZGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHRcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydChSZWNvcmRlci5zdXBwb3J0ZWQsIFwiTWVkaWEgUmVjb3JkZXIgQVBJIGlzIG5vdCBhdmFpbGFibGVcIik7XG4gICAgICAgIHRoaXMuX3N0cmVhbSA9IHRoaXMuY29udGV4dC5jcmVhdGVNZWRpYVN0cmVhbURlc3RpbmF0aW9uKCk7XG4gICAgICAgIHRoaXMuaW5wdXQuY29ubmVjdCh0aGlzLl9zdHJlYW0pO1xuICAgICAgICB0aGlzLl9yZWNvcmRlciA9IG5ldyBNZWRpYVJlY29yZGVyKHRoaXMuX3N0cmVhbS5zdHJlYW0sIHtcbiAgICAgICAgICAgIG1pbWVUeXBlOiBvcHRpb25zLm1pbWVUeXBlXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBtaW1lIHR5cGUgaXMgdGhlIGZvcm1hdCB0aGF0IHRoZSBhdWRpbyBpcyBlbmNvZGVkIGluLiBGb3IgQ2hyb21lXG4gICAgICogdGhhdCBpcyB0eXBpY2FsbHkgd2VibSBlbmNvZGVkIGFzIFwidm9yYmlzXCIuXG4gICAgICovXG4gICAgZ2V0IG1pbWVUeXBlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcmVjb3JkZXIubWltZVR5cGU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRlc3QgaWYgeW91ciBwbGF0Zm9ybSBzdXBwb3J0cyB0aGUgTWVkaWEgUmVjb3JkZXIgQVBJLiBJZiBpdCdzIG5vdCBhdmFpbGFibGUsXG4gICAgICogdHJ5IGluc3RhbGxpbmcgdGhpcyAocG9seWZpbGwpW2h0dHBzOi8vd3d3Lm5wbWpzLmNvbS9wYWNrYWdlL2F1ZGlvLXJlY29yZGVyLXBvbHlmaWxsXS5cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0IHN1cHBvcnRlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoZVdpbmRvdyAhPT0gbnVsbCAmJiBSZWZsZWN0Lmhhcyh0aGVXaW5kb3csIFwiTWVkaWFSZWNvcmRlclwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBwbGF5YmFjayBzdGF0ZSBvZiB0aGUgUmVjb3JkZXIsIGVpdGhlciBcInN0YXJ0ZWRcIiwgXCJzdG9wcGVkXCIgb3IgXCJwYXVzZWRcIlxuICAgICAqL1xuICAgIGdldCBzdGF0ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3JlY29yZGVyLnN0YXRlID09PSBcImluYWN0aXZlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBcInN0b3BwZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLl9yZWNvcmRlci5zdGF0ZSA9PT0gXCJwYXVzZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIFwicGF1c2VkXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gXCJzdGFydGVkXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhcnQgdGhlIFJlY29yZGVyLiBSZXR1cm5zIGEgcHJvbWlzZSB3aGljaCByZXNvbHZlc1xuICAgICAqIHdoZW4gdGhlIHJlY29yZGVyIGhhcyBzdGFydGVkLlxuICAgICAqL1xuICAgIHN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkge1xuICAgICAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgIT09IFwic3RhcnRlZFwiLCBcIlJlY29yZGVyIGlzIGFscmVhZHkgc3RhcnRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0UHJvbWlzZSA9IG5ldyBQcm9taXNlKGRvbmUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZVN0YXJ0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5yZW1vdmVFdmVudExpc3RlbmVyKFwic3RhcnRcIiwgaGFuZGxlU3RhcnQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuYWRkRXZlbnRMaXN0ZW5lcihcInN0YXJ0XCIsIGhhbmRsZVN0YXJ0LCBmYWxzZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnN0YXJ0KCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgc3RhcnRQcm9taXNlO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RvcCB0aGUgcmVjb3JkZXIuIFJldHVybnMgYSBwcm9taXNlIHdpdGggdGhlIHJlY29yZGVkIGNvbnRlbnQgdW50aWwgdGhpcyBwb2ludFxuICAgICAqIGVuY29kZWQgYXMgW1ttaW1lVHlwZV1dXG4gICAgICovXG4gICAgc3RvcCgpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGFzc2VydCh0aGlzLnN0YXRlICE9PSBcInN0b3BwZWRcIiwgXCJSZWNvcmRlciBpcyBub3Qgc3RhcnRlZFwiKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFQcm9taXNlID0gbmV3IFByb21pc2UoZG9uZSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlRGF0YSA9IChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3JlY29yZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJkYXRhYXZhaWxhYmxlXCIsIGhhbmRsZURhdGEsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgZG9uZShlLmRhdGEpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgdGhpcy5fcmVjb3JkZXIuYWRkRXZlbnRMaXN0ZW5lcihcImRhdGFhdmFpbGFibGVcIiwgaGFuZGxlRGF0YSwgZmFsc2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLl9yZWNvcmRlci5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4geWllbGQgZGF0YVByb21pc2U7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBQYXVzZSB0aGUgcmVjb3JkZXJcbiAgICAgKi9cbiAgICBwYXVzZSgpIHtcbiAgICAgICAgYXNzZXJ0KHRoaXMuc3RhdGUgPT09IFwic3RhcnRlZFwiLCBcIlJlY29yZGVyIG11c3QgYmUgc3RhcnRlZFwiKTtcbiAgICAgICAgdGhpcy5fcmVjb3JkZXIucGF1c2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX3N0cmVhbS5kaXNjb25uZWN0KCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVJlY29yZGVyLmpzLm1hcCIsImltcG9ydCB7IFBhcmFtIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9QYXJhbVwiO1xuaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG4vKipcbiAqIENvbXByZXNzb3IgaXMgYSB0aGluIHdyYXBwZXIgYXJvdW5kIHRoZSBXZWIgQXVkaW9cbiAqIFtEeW5hbWljc0NvbXByZXNzb3JOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1keW5hbWljc2NvbXByZXNzb3Jub2RlLWludGVyZmFjZSkuXG4gKiBDb21wcmVzc2lvbiByZWR1Y2VzIHRoZSB2b2x1bWUgb2YgbG91ZCBzb3VuZHMgb3IgYW1wbGlmaWVzIHF1aWV0IHNvdW5kc1xuICogYnkgbmFycm93aW5nIG9yIFwiY29tcHJlc3NpbmdcIiBhbiBhdWRpbyBzaWduYWwncyBkeW5hbWljIHJhbmdlLlxuICogUmVhZCBtb3JlIG9uIFtXaWtpcGVkaWFdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0R5bmFtaWNfcmFuZ2VfY29tcHJlc3Npb24pLlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGNvbXAgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKG9wdGlvbnNGcm9tQXJndW1lbnRzKENvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ0aHJlc2hvbGRcIiwgXCJyYXRpb1wiXSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbXByZXNzb3JcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIHRoZSBjb21wcmVzc29yIG5vZGVcbiAgICAgICAgICovXG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IgPSB0aGlzLmNvbnRleHQuY3JlYXRlRHluYW1pY3NDb21wcmVzc29yKCk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSB0aGlzLl9jb21wcmVzc29yO1xuICAgICAgICB0aGlzLm91dHB1dCA9IHRoaXMuX2NvbXByZXNzb3I7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwicmF0aW9cIl0pO1xuICAgICAgICB0aGlzLnRocmVzaG9sZCA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQubWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci50aHJlc2hvbGQubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBjb252ZXJ0OiBmYWxzZSxcbiAgICAgICAgICAgIHBhcmFtOiB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZCxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy50aHJlc2hvbGQsXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmF0dGFjayA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2subWluVmFsdWUsXG4gICAgICAgICAgICBtYXhWYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2subWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5hdHRhY2ssXG4gICAgICAgICAgICB1bml0czogXCJ0aW1lXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5hdHRhY2ssXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnJlbGVhc2UgPSBuZXcgUGFyYW0oe1xuICAgICAgICAgICAgbWluVmFsdWU6IHRoaXMuX2NvbXByZXNzb3IucmVsZWFzZS5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJlbGVhc2UubWF4VmFsdWUsXG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5yZWxlYXNlLFxuICAgICAgICAgICAgdW5pdHM6IFwidGltZVwiLFxuICAgICAgICAgICAgdmFsdWU6IG9wdGlvbnMucmVsZWFzZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMua25lZSA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5rbmVlLm1pblZhbHVlLFxuICAgICAgICAgICAgbWF4VmFsdWU6IHRoaXMuX2NvbXByZXNzb3Iua25lZS5tYXhWYWx1ZSxcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGNvbnZlcnQ6IGZhbHNlLFxuICAgICAgICAgICAgcGFyYW06IHRoaXMuX2NvbXByZXNzb3Iua25lZSxcbiAgICAgICAgICAgIHVuaXRzOiBcImRlY2liZWxzXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5rbmVlLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5yYXRpbyA9IG5ldyBQYXJhbSh7XG4gICAgICAgICAgICBtaW5WYWx1ZTogdGhpcy5fY29tcHJlc3Nvci5yYXRpby5taW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiB0aGlzLl9jb21wcmVzc29yLnJhdGlvLm1heFZhbHVlLFxuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgY29udmVydDogZmFsc2UsXG4gICAgICAgICAgICBwYXJhbTogdGhpcy5fY29tcHJlc3Nvci5yYXRpbyxcbiAgICAgICAgICAgIHVuaXRzOiBcInBvc2l0aXZlXCIsXG4gICAgICAgICAgICB2YWx1ZTogb3B0aW9ucy5yYXRpbyxcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIHNldCB0aGUgZGVmYXVsdHNcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wia25lZVwiLCBcInJlbGVhc2VcIiwgXCJhdHRhY2tcIiwgXCJyYXRpb1wiLCBcInRocmVzaG9sZFwiXSk7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICBhdHRhY2s6IDAuMDAzLFxuICAgICAgICAgICAga25lZTogMzAsXG4gICAgICAgICAgICByYXRpbzogMTIsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjI1LFxuICAgICAgICAgICAgdGhyZXNob2xkOiAtMjQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBIHJlYWQtb25seSBkZWNpYmVsIHZhbHVlIGZvciBtZXRlcmluZyBwdXJwb3NlcywgcmVwcmVzZW50aW5nIHRoZSBjdXJyZW50IGFtb3VudCBvZiBnYWluXG4gICAgICogcmVkdWN0aW9uIHRoYXQgdGhlIGNvbXByZXNzb3IgaXMgYXBwbHlpbmcgdG8gdGhlIHNpZ25hbC4gSWYgZmVkIG5vIHNpZ25hbCB0aGUgdmFsdWUgd2lsbCBiZSAwIChubyBnYWluIHJlZHVjdGlvbikuXG4gICAgICovXG4gICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXByZXNzb3IucmVkdWN0aW9uO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzY29ubmVjdCgpO1xuICAgICAgICB0aGlzLmF0dGFjay5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMucmVsZWFzZS5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMudGhyZXNob2xkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5yYXRpby5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMua25lZS5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUNvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgR3JlYXRlclRoYW4gfSBmcm9tIFwiLi4vLi4vc2lnbmFsL0dyZWF0ZXJUaGFuXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBGb2xsb3dlciB9IGZyb20gXCIuLi9hbmFseXNpcy9Gb2xsb3dlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBkYlRvR2FpbiwgZ2FpblRvRGIgfSBmcm9tIFwiLi4vLi4vY29yZS90eXBlL0NvbnZlcnNpb25zXCI7XG4vKipcbiAqIEdhdGUgb25seSBwYXNzZXMgYSBzaWduYWwgdGhyb3VnaCB3aGVuIHRoZSBpbmNvbWluZ1xuICogc2lnbmFsIGV4Y2VlZHMgYSBzcGVjaWZpZWQgdGhyZXNob2xkLiBJdCB1c2VzIFtbRm9sbG93ZXJdXSB0byBmb2xsb3cgdGhlIGFtcGx0aXVkZVxuICogb2YgdGhlIGluY29taW5nIHNpZ25hbCBhbmQgY29tcGFyZXMgaXQgdG8gdGhlIFtbdGhyZXNob2xkXV0gdmFsdWUgdXNpbmcgW1tHcmVhdGVyVGhhbl1dLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBnYXRlID0gbmV3IFRvbmUuR2F0ZSgtMzAsIDAuMikudG9EZXN0aW5hdGlvbigpO1xuICogY29uc3QgbWljID0gbmV3IFRvbmUuVXNlck1lZGlhKCkuY29ubmVjdChnYXRlKTtcbiAqIC8vIHRoZSBnYXRlIHdpbGwgb25seSBwYXNzIHRocm91Z2ggdGhlIGluY29taW5nXG4gKiAvLyBzaWduYWwgd2hlbiBpdCdzIGxvdWRlciB0aGFuIC0zMGRiXG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBHYXRlIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoR2F0ZS5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiLCBcInNtb290aGluZ1wiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJHYXRlXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhHYXRlLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCIsIFwic21vb3RoaW5nXCJdKTtcbiAgICAgICAgdGhpcy5fZm9sbG93ZXIgPSBuZXcgRm9sbG93ZXIoe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgc21vb3RoaW5nOiBvcHRpb25zLnNtb290aGluZyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2d0ID0gbmV3IEdyZWF0ZXJUaGFuKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHZhbHVlOiBkYlRvR2FpbihvcHRpb25zLnRocmVzaG9sZCksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IEdhaW4oeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSk7XG4gICAgICAgIHRoaXMuX2dhdGUgPSB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgICB0aGlzLmlucHV0LmNvbm5lY3QodGhpcy5fZ2F0ZSk7XG4gICAgICAgIC8vIHRoZSBjb250cm9sIHNpZ25hbFxuICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2ZvbGxvd2VyLCB0aGlzLl9ndCwgdGhpcy5fZ2F0ZS5nYWluKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIHNtb290aGluZzogMC4xLFxuICAgICAgICAgICAgdGhyZXNob2xkOiAtNDBcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSB0aHJlc2hvbGQgb2YgdGhlIGdhdGUgaW4gZGVjaWJlbHNcbiAgICAgKi9cbiAgICBnZXQgdGhyZXNob2xkKCkge1xuICAgICAgICByZXR1cm4gZ2FpblRvRGIodGhpcy5fZ3QudmFsdWUpO1xuICAgIH1cbiAgICBzZXQgdGhyZXNob2xkKHRocmVzaCkge1xuICAgICAgICB0aGlzLl9ndC52YWx1ZSA9IGRiVG9HYWluKHRocmVzaCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBhdHRhY2svZGVjYXkgc3BlZWQgb2YgdGhlIGdhdGUuIFNlZSBbW0ZvbGxvd2VyLnNtb290aGluZ11dXG4gICAgICovXG4gICAgZ2V0IHNtb290aGluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZztcbiAgICB9XG4gICAgc2V0IHNtb290aGluZyhzbW9vdGhpbmdUaW1lKSB7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLnNtb290aGluZyA9IHNtb290aGluZ1RpbWU7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5pbnB1dC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2ZvbGxvd2VyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fZ3QuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9nYXRlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2F0ZS5qcy5tYXAiLCJpbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBvcHRpb25zRnJvbUFyZ3VtZW50cyB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvRGVmYXVsdHNcIjtcbmltcG9ydCB7IENvbXByZXNzb3IgfSBmcm9tIFwiLi9Db21wcmVzc29yXCI7XG5pbXBvcnQgeyByZWFkT25seSB9IGZyb20gXCIuLi8uLi9jb3JlL3V0aWwvSW50ZXJmYWNlXCI7XG47XG4vKipcbiAqIExpbWl0ZXIgd2lsbCBsaW1pdCB0aGUgbG91ZG5lc3Mgb2YgYW4gaW5jb21pbmcgc2lnbmFsLlxuICogVW5kZXIgdGhlIGhvb2QgaXQncyBjb21wb3NlZCBvZiBhIFtbQ29tcHJlc3Nvcl1dIHdpdGggYSBmYXN0IGF0dGFja1xuICogYW5kIHJlbGVhc2UgYW5kIG1heCBjb21wcmVzc2lvbiByYXRpby5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbGltaXRlciA9IG5ldyBUb25lLkxpbWl0ZXIoLTIwKS50b0Rlc3RpbmF0aW9uKCk7XG4gKiBjb25zdCBvc2NpbGxhdG9yID0gbmV3IFRvbmUuT3NjaWxsYXRvcigpLmNvbm5lY3QobGltaXRlcik7XG4gKiBvc2NpbGxhdG9yLnN0YXJ0KCk7XG4gKiBAY2F0ZWdvcnkgQ29tcG9uZW50XG4gKi9cbmV4cG9ydCBjbGFzcyBMaW1pdGVyIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTGltaXRlci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMsIFtcInRocmVzaG9sZFwiXSkpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJMaW1pdGVyXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhMaW1pdGVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widGhyZXNob2xkXCJdKTtcbiAgICAgICAgdGhpcy5fY29tcHJlc3NvciA9IHRoaXMuaW5wdXQgPSB0aGlzLm91dHB1dCA9IG5ldyBDb21wcmVzc29yKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIHJhdGlvOiAyMCxcbiAgICAgICAgICAgIGF0dGFjazogMC4wMDMsXG4gICAgICAgICAgICByZWxlYXNlOiAwLjAxLFxuICAgICAgICAgICAgdGhyZXNob2xkOiBvcHRpb25zLnRocmVzaG9sZFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy50aHJlc2hvbGQgPSB0aGlzLl9jb21wcmVzc29yLnRocmVzaG9sZDtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgXCJ0aHJlc2hvbGRcIik7XG4gICAgfVxuICAgIHN0YXRpYyBnZXREZWZhdWx0cygpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oVG9uZUF1ZGlvTm9kZS5nZXREZWZhdWx0cygpLCB7XG4gICAgICAgICAgICB0aHJlc2hvbGQ6IC0xMlxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQSByZWFkLW9ubHkgZGVjaWJlbCB2YWx1ZSBmb3IgbWV0ZXJpbmcgcHVycG9zZXMsIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBhbW91bnQgb2YgZ2FpblxuICAgICAqIHJlZHVjdGlvbiB0aGF0IHRoZSBjb21wcmVzc29yIGlzIGFwcGx5aW5nIHRvIHRoZSBzaWduYWwuXG4gICAgICovXG4gICAgZ2V0IHJlZHVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXByZXNzb3IucmVkdWN0aW9uO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX2NvbXByZXNzb3IuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLnRocmVzaG9sZC5kaXNwb3NlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cbi8vIyBzb3VyY2VNYXBwaW5nVVJMPUxpbWl0ZXIuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgTWlkU2lkZVNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5pbXBvcnQgeyBNaWRTaWRlTWVyZ2UgfSBmcm9tIFwiLi4vY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbmltcG9ydCB7IHJlYWRPbmx5IH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogTWlkU2lkZUNvbXByZXNzb3IgYXBwbGllcyB0d28gZGlmZmVyZW50IGNvbXByZXNzb3JzIHRvIHRoZSBbW21pZF1dXG4gKiBhbmQgW1tzaWRlXV0gc2lnbmFsIGNvbXBvbmVudHMgb2YgdGhlIGlucHV0LiBTZWUgW1tNaWRTaWRlU3BsaXRdXSBhbmQgW1tNaWRTaWRlTWVyZ2VdXS5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE1pZFNpZGVDb21wcmVzc29yIGV4dGVuZHMgVG9uZUF1ZGlvTm9kZSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKE9iamVjdC5hc3NpZ24ob3B0aW9uc0Zyb21Bcmd1bWVudHMoTWlkU2lkZUNvbXByZXNzb3IuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzKSkpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIk1pZFNpZGVDb21wcmVzc29yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNaWRTaWRlQ29tcHJlc3Nvci5nZXREZWZhdWx0cygpLCBhcmd1bWVudHMpO1xuICAgICAgICB0aGlzLl9taWRTaWRlU3BsaXQgPSB0aGlzLmlucHV0ID0gbmV3IE1pZFNpZGVTcGxpdCh7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlID0gdGhpcy5vdXRwdXQgPSBuZXcgTWlkU2lkZU1lcmdlKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLm1pZCA9IG5ldyBDb21wcmVzc29yKE9iamVjdC5hc3NpZ24ob3B0aW9ucy5taWQsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5zaWRlID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLnNpZGUsIHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0Lm1pZC5jaGFpbih0aGlzLm1pZCwgdGhpcy5fbWlkU2lkZU1lcmdlLm1pZCk7XG4gICAgICAgIHRoaXMuX21pZFNpZGVTcGxpdC5zaWRlLmNoYWluKHRoaXMuc2lkZSwgdGhpcy5fbWlkU2lkZU1lcmdlLnNpZGUpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJtaWRcIiwgXCJzaWRlXCJdKTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG1pZDoge1xuICAgICAgICAgICAgICAgIHJhdGlvOiAzLFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTI0LFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMDMsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAyLFxuICAgICAgICAgICAgICAgIGtuZWU6IDE2XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc2lkZToge1xuICAgICAgICAgICAgICAgIHJhdGlvOiA2LFxuICAgICAgICAgICAgICAgIHRocmVzaG9sZDogLTMwLFxuICAgICAgICAgICAgICAgIHJlbGVhc2U6IDAuMjUsXG4gICAgICAgICAgICAgICAgYXR0YWNrOiAwLjAzLFxuICAgICAgICAgICAgICAgIGtuZWU6IDEwXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkaXNwb3NlKCkge1xuICAgICAgICBzdXBlci5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5zaWRlLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZVNwbGl0LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbWlkU2lkZU1lcmdlLmRpc3Bvc2UoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9TWlkU2lkZUNvbXByZXNzb3IuanMubWFwIiwiaW1wb3J0IHsgVG9uZUF1ZGlvTm9kZSB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvVG9uZUF1ZGlvTm9kZVwiO1xuaW1wb3J0IHsgQ29tcHJlc3NvciB9IGZyb20gXCIuL0NvbXByZXNzb3JcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHkgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0ludGVyZmFjZVwiO1xuaW1wb3J0IHsgTXVsdGliYW5kU3BsaXQgfSBmcm9tIFwiLi4vY2hhbm5lbC9NdWx0aWJhbmRTcGxpdFwiO1xuaW1wb3J0IHsgR2FpbiB9IGZyb20gXCIuLi8uLi9jb3JlL2NvbnRleHQvR2FpblwiO1xuLyoqXG4gKiBBIGNvbXByZXNzb3Igd2l0aCBzZXBhcmF0ZSBjb250cm9scyBvdmVyIGxvdy9taWQvaGlnaCBkeW5hbWljcy4gU2VlIFtbQ29tcHJlc3Nvcl1dIGFuZCBbW011bHRpYmFuZFNwbGl0XV1cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgbXVsdGliYW5kID0gbmV3IFRvbmUuTXVsdGliYW5kQ29tcHJlc3Nvcih7XG4gKiBcdGxvd0ZyZXF1ZW5jeTogMjAwLFxuICogXHRoaWdoRnJlcXVlbmN5OiAxMzAwLFxuICogXHRsb3c6IHtcbiAqIFx0XHR0aHJlc2hvbGQ6IC0xMlxuICogXHR9XG4gKiB9KTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIE11bHRpYmFuZENvbXByZXNzb3IgZXh0ZW5kcyBUb25lQXVkaW9Ob2RlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoT2JqZWN0LmFzc2lnbihvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cykpKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJNdWx0aWJhbmRDb21wcmVzc29yXCI7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhNdWx0aWJhbmRDb21wcmVzc29yLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuX3NwbGl0dGVyID0gdGhpcy5pbnB1dCA9IG5ldyBNdWx0aWJhbmRTcGxpdCh7XG4gICAgICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IG9wdGlvbnMubG93RnJlcXVlbmN5LFxuICAgICAgICAgICAgaGlnaEZyZXF1ZW5jeTogb3B0aW9ucy5oaWdoRnJlcXVlbmN5XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmxvd0ZyZXF1ZW5jeSA9IHRoaXMuX3NwbGl0dGVyLmxvd0ZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5ID0gdGhpcy5fc3BsaXR0ZXIuaGlnaEZyZXF1ZW5jeTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5sb3cgPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMubG93LCB7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KSk7XG4gICAgICAgIHRoaXMubWlkID0gbmV3IENvbXByZXNzb3IoT2JqZWN0LmFzc2lnbihvcHRpb25zLm1pZCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB0aGlzLmhpZ2ggPSBuZXcgQ29tcHJlc3NvcihPYmplY3QuYXNzaWduKG9wdGlvbnMuaGlnaCwgeyBjb250ZXh0OiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICAvLyBjb25uZWN0IHRoZSBjb21wcmVzc29yXG4gICAgICAgIHRoaXMuX3NwbGl0dGVyLmxvdy5jaGFpbih0aGlzLmxvdywgdGhpcy5vdXRwdXQpO1xuICAgICAgICB0aGlzLl9zcGxpdHRlci5taWQuY2hhaW4odGhpcy5taWQsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuaGlnaC5jaGFpbih0aGlzLmhpZ2gsIHRoaXMub3V0cHV0KTtcbiAgICAgICAgcmVhZE9ubHkodGhpcywgW1wiaGlnaFwiLCBcIm1pZFwiLCBcImxvd1wiLCBcImhpZ2hGcmVxdWVuY3lcIiwgXCJsb3dGcmVxdWVuY3lcIl0pO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgbG93RnJlcXVlbmN5OiAyNTAsXG4gICAgICAgICAgICBoaWdoRnJlcXVlbmN5OiAyMDAwLFxuICAgICAgICAgICAgbG93OiB7XG4gICAgICAgICAgICAgICAgcmF0aW86IDYsXG4gICAgICAgICAgICAgICAgdGhyZXNob2xkOiAtMzAsXG4gICAgICAgICAgICAgICAgcmVsZWFzZTogMC4yNSxcbiAgICAgICAgICAgICAgICBhdHRhY2s6IDAuMDMsXG4gICAgICAgICAgICAgICAga25lZTogMTBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBtaWQ6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhpZ2g6IHtcbiAgICAgICAgICAgICAgICByYXRpbzogMyxcbiAgICAgICAgICAgICAgICB0aHJlc2hvbGQ6IC0yNCxcbiAgICAgICAgICAgICAgICByZWxlYXNlOiAwLjAzLFxuICAgICAgICAgICAgICAgIGF0dGFjazogMC4wMixcbiAgICAgICAgICAgICAgICBrbmVlOiAxNlxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fc3BsaXR0ZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmxvdy5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubWlkLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoLmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5vdXRwdXQuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1NdWx0aWJhbmRDb21wcmVzc29yLmpzLm1hcCIsImltcG9ydCB7IEdhaW4gfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L0dhaW5cIjtcbmltcG9ydCB7IFRvbmVBdWRpb05vZGUgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb05vZGVcIjtcbmltcG9ydCB7IG9wdGlvbnNGcm9tQXJndW1lbnRzIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9EZWZhdWx0c1wiO1xuaW1wb3J0IHsgcmVhZE9ubHksIHdyaXRhYmxlIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbmltcG9ydCB7IE11bHRpYmFuZFNwbGl0IH0gZnJvbSBcIi4uL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbi8qKlxuICogRVEzIHByb3ZpZGVzIDMgZXF1YWxpemVyIGJpbnM6IExvdy9NaWQvSGlnaC5cbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIEVRMyBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhFUTMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCJdKSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiRVEzXCI7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiB0aGUgb3V0cHV0XG4gICAgICAgICAqL1xuICAgICAgICB0aGlzLm91dHB1dCA9IG5ldyBHYWluKHsgY29udGV4dDogdGhpcy5jb250ZXh0IH0pO1xuICAgICAgICB0aGlzLl9pbnRlcm5hbENoYW5uZWxzID0gW107XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBvcHRpb25zRnJvbUFyZ3VtZW50cyhFUTMuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCJdKTtcbiAgICAgICAgdGhpcy5pbnB1dCA9IHRoaXMuX211bHRpYmFuZFNwbGl0ID0gbmV3IE11bHRpYmFuZFNwbGl0KHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IG9wdGlvbnMuaGlnaEZyZXF1ZW5jeSxcbiAgICAgICAgICAgIGxvd0ZyZXF1ZW5jeTogb3B0aW9ucy5sb3dGcmVxdWVuY3ksXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLl9sb3dHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5sb3csXG4gICAgICAgICAgICB1bml0czogXCJkZWNpYmVsc1wiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fbWlkR2FpbiA9IG5ldyBHYWluKHtcbiAgICAgICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCxcbiAgICAgICAgICAgIGdhaW46IG9wdGlvbnMubWlkLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuX2hpZ2hHYWluID0gbmV3IEdhaW4oe1xuICAgICAgICAgICAgY29udGV4dDogdGhpcy5jb250ZXh0LFxuICAgICAgICAgICAgZ2Fpbjogb3B0aW9ucy5oaWdoLFxuICAgICAgICAgICAgdW5pdHM6IFwiZGVjaWJlbHNcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubG93ID0gdGhpcy5fbG93R2Fpbi5nYWluO1xuICAgICAgICB0aGlzLm1pZCA9IHRoaXMuX21pZEdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5oaWdoID0gdGhpcy5faGlnaEdhaW4uZ2FpbjtcbiAgICAgICAgdGhpcy5RID0gdGhpcy5fbXVsdGliYW5kU3BsaXQuUTtcbiAgICAgICAgdGhpcy5sb3dGcmVxdWVuY3kgPSB0aGlzLl9tdWx0aWJhbmRTcGxpdC5sb3dGcmVxdWVuY3k7XG4gICAgICAgIHRoaXMuaGlnaEZyZXF1ZW5jeSA9IHRoaXMuX211bHRpYmFuZFNwbGl0LmhpZ2hGcmVxdWVuY3k7XG4gICAgICAgIC8vIHRoZSBmcmVxdWVuY3kgYmFuZHNcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQubG93LmNoYWluKHRoaXMuX2xvd0dhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQubWlkLmNoYWluKHRoaXMuX21pZEdhaW4sIHRoaXMub3V0cHV0KTtcbiAgICAgICAgdGhpcy5fbXVsdGliYW5kU3BsaXQuaGlnaC5jaGFpbih0aGlzLl9oaWdoR2FpbiwgdGhpcy5vdXRwdXQpO1xuICAgICAgICByZWFkT25seSh0aGlzLCBbXCJsb3dcIiwgXCJtaWRcIiwgXCJoaWdoXCIsIFwibG93RnJlcXVlbmN5XCIsIFwiaGlnaEZyZXF1ZW5jeVwiXSk7XG4gICAgICAgIHRoaXMuX2ludGVybmFsQ2hhbm5lbHMgPSBbdGhpcy5fbXVsdGliYW5kU3BsaXRdO1xuICAgIH1cbiAgICBzdGF0aWMgZ2V0RGVmYXVsdHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKFRvbmVBdWRpb05vZGUuZ2V0RGVmYXVsdHMoKSwge1xuICAgICAgICAgICAgaGlnaDogMCxcbiAgICAgICAgICAgIGhpZ2hGcmVxdWVuY3k6IDI1MDAsXG4gICAgICAgICAgICBsb3c6IDAsXG4gICAgICAgICAgICBsb3dGcmVxdWVuY3k6IDQwMCxcbiAgICAgICAgICAgIG1pZDogMCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENsZWFuIHVwLlxuICAgICAqL1xuICAgIGRpc3Bvc2UoKSB7XG4gICAgICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgICAgICAgd3JpdGFibGUodGhpcywgW1wibG93XCIsIFwibWlkXCIsIFwiaGlnaFwiLCBcImxvd0ZyZXF1ZW5jeVwiLCBcImhpZ2hGcmVxdWVuY3lcIl0pO1xuICAgICAgICB0aGlzLl9tdWx0aWJhbmRTcGxpdC5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93RnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5oaWdoRnJlcXVlbmN5LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5fbG93R2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMuX21pZEdhaW4uZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9oaWdoR2Fpbi5kaXNwb3NlKCk7XG4gICAgICAgIHRoaXMubG93LmRpc3Bvc2UoKTtcbiAgICAgICAgdGhpcy5taWQuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLmhpZ2guZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLlEuZGlzcG9zZSgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FUTMuanMubWFwIiwiaW1wb3J0IHsgX19hd2FpdGVyIH0gZnJvbSBcInRzbGliXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9Ob2RlIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9Ub25lQXVkaW9Ob2RlXCI7XG5pbXBvcnQgeyBUb25lQXVkaW9CdWZmZXIgfSBmcm9tIFwiLi4vLi4vY29yZS9jb250ZXh0L1RvbmVBdWRpb0J1ZmZlclwiO1xuaW1wb3J0IHsgb3B0aW9uc0Zyb21Bcmd1bWVudHMgfSBmcm9tIFwiLi4vLi4vY29yZS91dGlsL0RlZmF1bHRzXCI7XG5pbXBvcnQgeyBHYWluIH0gZnJvbSBcIi4uLy4uL2NvcmUvY29udGV4dC9HYWluXCI7XG5pbXBvcnQgeyBub09wIH0gZnJvbSBcIi4uLy4uL2NvcmUvdXRpbC9JbnRlcmZhY2VcIjtcbi8qKlxuICogQ29udm9sdmVyIGlzIGEgd3JhcHBlciBhcm91bmQgdGhlIE5hdGl2ZSBXZWIgQXVkaW9cbiAqIFtDb252b2x2ZXJOb2RlXShodHRwOi8vd2ViYXVkaW8uZ2l0aHViLmlvL3dlYi1hdWRpby1hcGkvI3RoZS1jb252b2x2ZXJub2RlLWludGVyZmFjZSkuXG4gKiBDb252b2x1dGlvbiBpcyB1c2VmdWwgZm9yIHJldmVyYiBhbmQgZmlsdGVyIGVtdWxhdGlvbi4gUmVhZCBtb3JlIGFib3V0IGNvbnZvbHV0aW9uIHJldmVyYiBvblxuICogW1dpa2lwZWRpYV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29udm9sdXRpb25fcmV2ZXJiKS5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gaW5pdGlhbGl6aW5nIHRoZSBjb252b2x2ZXIgd2l0aCBhbiBpbXB1bHNlIHJlc3BvbnNlXG4gKiBjb25zdCBjb252b2x2ZXIgPSBuZXcgVG9uZS5Db252b2x2ZXIoXCIuL3BhdGgvdG8vaXIud2F2XCIpLnRvRGVzdGluYXRpb24oKTtcbiAqIEBjYXRlZ29yeSBDb21wb25lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnZvbHZlciBleHRlbmRzIFRvbmVBdWRpb05vZGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlcihvcHRpb25zRnJvbUFyZ3VtZW50cyhDb252b2x2ZXIuZ2V0RGVmYXVsdHMoKSwgYXJndW1lbnRzLCBbXCJ1cmxcIiwgXCJvbmxvYWRcIl0pKTtcbiAgICAgICAgdGhpcy5uYW1lID0gXCJDb252b2x2ZXJcIjtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBuYXRpdmUgQ29udm9sdmVyTm9kZVxuICAgICAgICAgKi9cbiAgICAgICAgdGhpcy5fY29udm9sdmVyID0gdGhpcy5jb250ZXh0LmNyZWF0ZUNvbnZvbHZlcigpO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0Zyb21Bcmd1bWVudHMoQ29udm9sdmVyLmdldERlZmF1bHRzKCksIGFyZ3VtZW50cywgW1widXJsXCIsIFwib25sb2FkXCJdKTtcbiAgICAgICAgdGhpcy5fYnVmZmVyID0gbmV3IFRvbmVBdWRpb0J1ZmZlcihvcHRpb25zLnVybCwgYnVmZmVyID0+IHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xuICAgICAgICAgICAgb3B0aW9ucy5vbmxvYWQoKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgdGhpcy5vdXRwdXQgPSBuZXcgR2Fpbih7IGNvbnRleHQ6IHRoaXMuY29udGV4dCB9KTtcbiAgICAgICAgLy8gc2V0IGlmIGl0J3MgYWxyZWFkeSBsb2FkZWQsIHNldCBpdCBpbW1lZGlhdGVseVxuICAgICAgICBpZiAodGhpcy5fYnVmZmVyLmxvYWRlZCkge1xuICAgICAgICAgICAgdGhpcy5idWZmZXIgPSB0aGlzLl9idWZmZXI7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaW5pdGlhbGx5IHNldCBub3JtYWxpemF0aW9uXG4gICAgICAgIHRoaXMubm9ybWFsaXplID0gb3B0aW9ucy5ub3JtYWxpemU7XG4gICAgICAgIC8vIGNvbm5lY3QgaXQgdXBcbiAgICAgICAgdGhpcy5pbnB1dC5jaGFpbih0aGlzLl9jb252b2x2ZXIsIHRoaXMub3V0cHV0KTtcbiAgICB9XG4gICAgc3RhdGljIGdldERlZmF1bHRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihUb25lQXVkaW9Ob2RlLmdldERlZmF1bHRzKCksIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZTogdHJ1ZSxcbiAgICAgICAgICAgIG9ubG9hZDogbm9PcCxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWQgYW4gaW1wdWxzZSByZXNwb25zZSB1cmwgYXMgYW4gYXVkaW8gYnVmZmVyLlxuICAgICAqIERlY29kZXMgdGhlIGF1ZGlvIGFzeW5jaHJvbm91c2x5IGFuZCBpbnZva2VzXG4gICAgICogdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGF1ZGlvIGJ1ZmZlciBsb2Fkcy5cbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgb2YgdGhlIGJ1ZmZlciB0byBsb2FkLiBmaWxldHlwZSBzdXBwb3J0IGRlcGVuZHMgb24gdGhlIGJyb3dzZXIuXG4gICAgICovXG4gICAgbG9hZCh1cmwpIHtcbiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIHRoaXMuYnVmZmVyID0geWllbGQgdGhpcy5fYnVmZmVyLmxvYWQodXJsKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBjb252b2x2ZXIncyBidWZmZXJcbiAgICAgKi9cbiAgICBnZXQgYnVmZmVyKCkge1xuICAgICAgICBpZiAodGhpcy5fYnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2J1ZmZlcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldCBidWZmZXIoYnVmZmVyKSB7XG4gICAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2J1ZmZlci5zZXQoYnVmZmVyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiBpdCdzIGFscmVhZHkgZ290IGEgYnVmZmVyLCBjcmVhdGUgYSBuZXcgb25lXG4gICAgICAgIGlmICh0aGlzLl9jb252b2x2ZXIuYnVmZmVyKSB7XG4gICAgICAgICAgICAvLyBkaXNjb25uZWN0IHRoZSBvbGQgb25lXG4gICAgICAgICAgICB0aGlzLmlucHV0LmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICAgIHRoaXMuX2NvbnZvbHZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYW5kIGNvbm5lY3QgYSBuZXcgb25lXG4gICAgICAgICAgICB0aGlzLl9jb252b2x2ZXIgPSB0aGlzLmNvbnRleHQuY3JlYXRlQ29udm9sdmVyKCk7XG4gICAgICAgICAgICB0aGlzLmlucHV0LmNoYWluKHRoaXMuX2NvbnZvbHZlciwgdGhpcy5vdXRwdXQpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmYgPSB0aGlzLl9idWZmZXIuZ2V0KCk7XG4gICAgICAgIHRoaXMuX2NvbnZvbHZlci5idWZmZXIgPSBidWZmID8gYnVmZiA6IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRoZSBub3JtYWxpemUgcHJvcGVydHkgb2YgdGhlIENvbnZvbHZlck5vZGUgaW50ZXJmYWNlIGlzIGEgYm9vbGVhbiB0aGF0XG4gICAgICogY29udHJvbHMgd2hldGhlciB0aGUgaW1wdWxzZSByZXNwb25zZSBmcm9tIHRoZSBidWZmZXIgd2lsbCBiZSBzY2FsZWQgYnlcbiAgICAgKiBhbiBlcXVhbC1wb3dlciBub3JtYWxpemF0aW9uIHdoZW4gdGhlIGJ1ZmZlciBhdHRyaWJ1dGUgaXMgc2V0LCBvciBub3QuXG4gICAgICovXG4gICAgZ2V0IG5vcm1hbGl6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnZvbHZlci5ub3JtYWxpemU7XG4gICAgfVxuICAgIHNldCBub3JtYWxpemUobm9ybSkge1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIubm9ybWFsaXplID0gbm9ybTtcbiAgICB9XG4gICAgZGlzcG9zZSgpIHtcbiAgICAgICAgc3VwZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9idWZmZXIuZGlzcG9zZSgpO1xuICAgICAgICB0aGlzLl9jb252b2x2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG4vLyMgc291cmNlTWFwcGluZ1VSTD1Db252b2x2ZXIuanMubWFwIiwiZXhwb3J0ICogZnJvbSBcIi4vYW5hbHlzaXMvQW5hbHlzZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL01ldGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9GRlRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL0RDTWV0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2FuYWx5c2lzL1dhdmVmb3JtXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9hbmFseXNpcy9Gb2xsb3dlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9DaGFubmVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL0Nyb3NzRmFkZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NZXJnZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9NaWRTaWRlTWVyZ2VcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTWlkU2lkZVNwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL01vbm9cIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvTXVsdGliYW5kU3BsaXRcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2NoYW5uZWwvUGFubmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1Bhbm5lcjNEXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1BhblZvbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9SZWNvcmRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vY2hhbm5lbC9Tb2xvXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1NwbGl0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jaGFubmVsL1ZvbHVtZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvQ29tcHJlc3NvclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvR2F0ZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTGltaXRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZHluYW1pY3MvTWlkU2lkZUNvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2R5bmFtaWNzL011bHRpYmFuZENvbXByZXNzb3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2VudmVsb3BlL0FtcGxpdHVkZUVudmVsb3BlXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9lbnZlbG9wZS9FbnZlbG9wZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZW52ZWxvcGUvRnJlcXVlbmN5RW52ZWxvcGVcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9FUTNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9GaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9PbmVQb2xlRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvRmVlZGJhY2tDb21iRmlsdGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maWx0ZXIvTG93cGFzc0NvbWJGaWx0ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9Db252b2x2ZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpbHRlci9CaXF1YWRGaWx0ZXJcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImV4cG9ydCAqIGZyb20gXCIuL2NvcmUvaW5kZXhcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3NvdXJjZS9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vc2lnbmFsL2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9pbnN0cnVtZW50L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ldmVudC9pbmRleFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZWZmZWN0L2luZGV4XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb21wb25lbnQvaW5kZXhcIjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNsYXNzZXMuanMubWFwIiwiZXhwb3J0IHsgZ2V0Q29udGV4dCwgc2V0Q29udGV4dCB9IGZyb20gXCIuL2NvcmUvR2xvYmFsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jbGFzc2VzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92ZXJzaW9uXCI7XG5pbXBvcnQgeyBnZXRDb250ZXh0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmltcG9ydCB7IFRvbmVBdWRpb0J1ZmZlciB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJcIjtcbmV4cG9ydCB7IHN0YXJ0IH0gZnJvbSBcIi4vY29yZS9HbG9iYWxcIjtcbmV4cG9ydCB7IHN1cHBvcnRlZCB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9BdWRpb0NvbnRleHRcIjtcbi8qKlxuICogVGhlIGN1cnJlbnQgYXVkaW8gY29udGV4dCB0aW1lIG9mIHRoZSBnbG9iYWwgW1tDb250ZXh0XV0uXG4gKiBTZWUgW1tDb250ZXh0Lm5vd11dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbm93KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkubm93KCk7XG59XG4vKipcbiAqIFRoZSBjdXJyZW50IGF1ZGlvIGNvbnRleHQgdGltZSBvZiB0aGUgZ2xvYmFsIFtbQ29udGV4dF1dIHdpdGhvdXQgdGhlIFtbQ29udGV4dC5sb29rQWhlYWRdXVxuICogU2VlIFtbQ29udGV4dC5pbW1lZGlhdGVdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGltbWVkaWF0ZSgpIHtcbiAgICByZXR1cm4gZ2V0Q29udGV4dCgpLmltbWVkaWF0ZSgpO1xufVxuLyoqXG4gKiBUaGUgVHJhbnNwb3J0IG9iamVjdCBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tUcmFuc3BvcnRdXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IFRyYW5zcG9ydCA9IGdldENvbnRleHQoKS50cmFuc3BvcnQ7XG4vKipcbiAqIFRoZSBUcmFuc3BvcnQgb2JqZWN0IGJlbG9uZ2luZyB0byB0aGUgZ2xvYmFsIFRvbmUuanMgQ29udGV4dC5cbiAqIFNlZSBbW1RyYW5zcG9ydF1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNwb3J0KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkudHJhbnNwb3J0O1xufVxuLyoqXG4gKiBUaGUgRGVzdGluYXRpb24gKG91dHB1dCkgYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogU2VlIFtbRGVzdGluYXRpb25dXVxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGNvbnN0IERlc3RpbmF0aW9uID0gZ2V0Q29udGV4dCgpLmRlc3RpbmF0aW9uO1xuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgW1tEZXN0aW5hdGlvbl1dXG4gKi9cbmV4cG9ydCBjb25zdCBNYXN0ZXIgPSBnZXRDb250ZXh0KCkuZGVzdGluYXRpb247XG4vKipcbiAqIFRoZSBEZXN0aW5hdGlvbiAob3V0cHV0KSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBTZWUgW1tEZXN0aW5hdGlvbl1dXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVzdGluYXRpb24oKSB7XG4gICAgcmV0dXJuIGdldENvbnRleHQoKS5kZXN0aW5hdGlvbjtcbn1cbi8qKlxuICogVGhlIFtbTGlzdGVuZXJdXSBiZWxvbmdpbmcgdG8gdGhlIGdsb2JhbCBUb25lLmpzIENvbnRleHQuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgY29uc3QgTGlzdGVuZXIgPSBnZXRDb250ZXh0KCkubGlzdGVuZXI7XG4vKipcbiAqIFRoZSBbW0xpc3RlbmVyXV0gYmVsb25naW5nIHRvIHRoZSBnbG9iYWwgVG9uZS5qcyBDb250ZXh0LlxuICogQGNhdGVnb3J5IENvcmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExpc3RlbmVyKCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkubGlzdGVuZXI7XG59XG4vKipcbiAqIERyYXcgaXMgdXNlZCB0byBzeW5jaHJvbml6ZSB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUcmFuc3BvcnQncyBjYWxsYmFja3MuXG4gKiBTZWUgW1tEcmF3XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBjb25zdCBEcmF3ID0gZ2V0Q29udGV4dCgpLmRyYXc7XG4vKipcbiAqIEdldCB0aGUgc2luZ2xldG9uIGF0dGFjaGVkIHRvIHRoZSBnbG9iYWwgY29udGV4dC5cbiAqIERyYXcgaXMgdXNlZCB0byBzeW5jaHJvbml6ZSB0aGUgZHJhdyBmcmFtZSB3aXRoIHRoZSBUcmFuc3BvcnQncyBjYWxsYmFja3MuXG4gKiBTZWUgW1tEcmF3XV1cbiAqIEBjYXRlZ29yeSBDb3JlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREcmF3KCkge1xuICAgIHJldHVybiBnZXRDb250ZXh0KCkuZHJhdztcbn1cbi8qKlxuICogQSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBjb250ZXh0XG4gKiBTZWUgW1tDb250ZXh0XV1cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnRleHQgPSBnZXRDb250ZXh0KCk7XG4vKipcbiAqIFByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiBhbGwgb2YgdGhlIGxvYWRpbmcgcHJvbWlzZXMgYXJlIHJlc29sdmVkLlxuICogQWxpYXMgZm9yIHN0YXRpYyBbW1RvbmVBdWRpb0J1ZmZlci5sb2FkZWRdXSBtZXRob2QuXG4gKiBAY2F0ZWdvcnkgQ29yZVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZGVkKCkge1xuICAgIHJldHVybiBUb25lQXVkaW9CdWZmZXIubG9hZGVkKCk7XG59XG4vLyB0aGlzIGZpbGxzIGluIG5hbWUgY2hhbmdlcyBmcm9tIDEzLnggdG8gMTQueFxuaW1wb3J0IHsgVG9uZUF1ZGlvQnVmZmVycyB9IGZyb20gXCIuL2NvcmUvY29udGV4dC9Ub25lQXVkaW9CdWZmZXJzXCI7XG5pbXBvcnQgeyBUb25lQnVmZmVyU291cmNlIH0gZnJvbSBcIi4vc291cmNlL2J1ZmZlci9Ub25lQnVmZmVyU291cmNlXCI7XG5leHBvcnQgY29uc3QgQnVmZmVyID0gVG9uZUF1ZGlvQnVmZmVyO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlcnMgPSBUb25lQXVkaW9CdWZmZXJzO1xuZXhwb3J0IGNvbnN0IEJ1ZmZlclNvdXJjZSA9IFRvbmVCdWZmZXJTb3VyY2U7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgU3RhcnRBdWRpb0NvbnRleHQgZnJvbSBcIi4vc3RhcnRBdWRpb0NvbnRleHRcIjtcblxuY29uc3QgaXNJcGhvbmUgPVxuICBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgfHwgbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvaVBvZC9pKTtcbmNvbnN0IGlzSXBhZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL2lQYWQvaSk7XG5jb25zdCBpc0FuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BbmRyb2lkL2kpO1xuY29uc3QgaXNNb2JpbGUgPSBpc0lwaG9uZSB8fCBpc0lwYWQgfHwgaXNBbmRyb2lkO1xuY29uc3QgaXNEZXNrdG9wID0gIWlzTW9iaWxlO1xuXG5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoaXNNb2JpbGUgPyBcIm1vYmlsZVwiIDogXCJkZXNrdG9wXCIpO1xuXG5leHBvcnQgY29uc3QgYnJvd3NlciA9IHsgaXNJcGhvbmUsIGlzSXBhZCwgaXNNb2JpbGUsIGlzRGVza3RvcCB9O1xuZXhwb3J0IGNvbnN0IGNob2ljZSA9IChhKSA9PiBhW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGEubGVuZ3RoKV07XG5leHBvcnQgY29uc3QgbW9kID0gKG4sIG0pID0+IG4gLSBtICogTWF0aC5mbG9vcihuIC8gbSk7XG5leHBvcnQgY29uc3QgcmFuZG9tID0gKCkgPT4gTWF0aC5yYW5kb20oKTtcbmV4cG9ydCBjb25zdCByYW5kID0gKG4pID0+IE1hdGgucmFuZG9tKCkgKiBuO1xuZXhwb3J0IGNvbnN0IHJhbmRpbnQgPSAobikgPT4gcmFuZChuKSB8IDA7XG5leHBvcnQgY29uc3QgcmFuZHJhbmdlID0gKGEsIGIpID0+IGEgKyByYW5kKGIgLSBhKTtcbmV4cG9ydCBjb25zdCByYW5kc2lnbiA9ICgpID0+IChyYW5kb20oKSA+PSAwLjUgPyAtMSA6IDEpO1xuZXhwb3J0IGNvbnN0IHJhbmRudWxsc2lnbiA9ICgpID0+IHtcbiAgdmFyIHIgPSByYW5kb20oKTtcbiAgcmV0dXJuIHIgPCAwLjMzMyA/IC0xIDogciA8IDAuNjY2ID8gMCA6IDE7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gcmVxdWVzdEF1ZGlvQ29udGV4dChmbikge1xuICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBidXR0b24uaW5uZXJIVE1MID0gXCJUYXAgdG8gc3RhcnQgLSBwbGVhc2UgdW5tdXRlIHlvdXIgcGhvbmVcIjtcbiAgT2JqZWN0LmFzc2lnbihjb250YWluZXIuc3R5bGUsIHtcbiAgICBkaXNwbGF5OiBcImJsb2NrXCIsXG4gICAgcG9zaXRpb246IFwiYWJzb2x1dGVcIixcbiAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgaGVpZ2h0OiBcIjEwMCVcIixcbiAgICB6SW5kZXg6IFwiMTAwMDBcIixcbiAgICB0b3A6IFwiMHB4XCIsXG4gICAgbGVmdDogXCIwcHhcIixcbiAgICBiYWNrZ3JvdW5kQ29sb3I6IFwicmdiYSgwLCAwLCAwLCAwLjgpXCIsXG4gIH0pO1xuICBPYmplY3QuYXNzaWduKGJ1dHRvbi5zdHlsZSwge1xuICAgIGRpc3BsYXk6IFwiYmxvY2tcIixcbiAgICBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLFxuICAgIGxlZnQ6IFwiNTAlXCIsXG4gICAgdG9wOiBcIjUwJVwiLFxuICAgIHBhZGRpbmc6IFwiMjBweFwiLFxuICAgIGJhY2tncm91bmRDb2xvcjogXCIjN0YzM0VEXCIsXG4gICAgY29sb3I6IFwid2hpdGVcIixcbiAgICBmb250RmFtaWx5OiBcIm1vbm9zcGFjZVwiLFxuICAgIGJvcmRlclJhZGl1czogXCIzcHhcIixcbiAgICB0cmFuc2Zvcm06IFwidHJhbnNsYXRlM0QoLTUwJSwtNTAlLDApXCIsXG4gICAgdGV4dEFsaWduOiBcImNlbnRlclwiLFxuICAgIGxpbmVIZWlnaHQ6IFwiMS41XCIsXG4gICAgd2lkdGg6IFwiMTUwcHhcIixcbiAgfSk7XG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChidXR0b24pO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gIFN0YXJ0QXVkaW9Db250ZXh0LnNldENvbnRleHQoVG9uZS5jb250ZXh0KTtcbiAgU3RhcnRBdWRpb0NvbnRleHQub24oYnV0dG9uKTtcbiAgU3RhcnRBdWRpb0NvbnRleHQub25TdGFydGVkKChfKSA9PiB7XG4gICAgY29udGFpbmVyLnJlbW92ZSgpO1xuICAgIGZuKCk7XG4gIH0pO1xufVxuIiwiLyoqXG4gKiBSZWxhYmkgd2F2ZWZvcm0gZGlzcGxheVxuICogQG1vZHVsZSBzcmMvcmVsYWJpL2NhbnZhcy5qcztcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZWxhYmlDYW52YXMge1xuICAvKipcbiAgICogSW5pdGlhbGl6ZSByZWxhYmkgd2F2ZSByZW5kZXJlclxuICAgKi9cbiAgY29uc3RydWN0b3IoeyByZWxhYmksIHBhcmVudCB9KSB7XG4gICAgdGhpcy5yZWxhYmkgPSByZWxhYmk7XG4gICAgdGhpcy5oZWlnaHQgPSA0MDA7XG4gICAgdGhpcy5sYXN0RnJhbWUgPSAwO1xuICAgIHRoaXMubGFzdEFwcGVuZFRpbWUgPSAwO1xuICAgIHRoaXMubGFzdEFwcGVuZEZyYW1lID0gMDtcblxuICAgIC8vIFNwZWVkIG9mIHRoZSB3YXZlIGluIHBpeGVscyBwZXIgc2Vjb25kXG4gICAgdGhpcy5zcGVlZCA9IDEgLyA1O1xuXG4gICAgLy8gUG9zaXRpb24gb2YgY3VycmVudCB0aW1lIG9uIHRoZSBzY3JlZW4sIGZyb20gdGhlIGxlZnRcbiAgICB0aGlzLnRaZXJvT2Zmc2V0ID0gMjA7XG5cbiAgICAvLyBBdHRhY2ggdG8gdGhlIERPTVxuICAgIHRoaXMuYXBwZW5kQ2FudmFzKHBhcmVudCk7XG4gICAgLy8gSW5pdGlhbGl6ZSBhcnJheVxuICAgIHRoaXMudmFsdWVzID0gbmV3IEFycmF5KHdpbmRvdy5pbm5lcldpZHRoKS5maWxsKDApO1xuICAgIHRoaXMubm90ZXMgPSBbXTtcbiAgICB0aGlzLmFwcGVuZChbXSk7XG5cbiAgICAvLyBDbGVhciB0aGUgY2FudmFzXG4gICAgdGhpcy5yZXNpemUoKTtcblxuICAgIC8vIFN0YXJ0IGRyYXdpbmdcbiAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZSgwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmQgdGhlIGNhbnZhc1xuICAgKi9cbiAgYXBwZW5kQ2FudmFzKHBhcmVudCkge1xuICAgIHRoaXMucGFyZW50ID0gcGFyZW50IHx8IGRvY3VtZW50LmJvZHk7XG4gICAgdGhpcy5jYW52YXMgPSB0aGlzLmNhbnZhcyB8fCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiY2FudmFzXCIpO1xuICAgIHRoaXMuY3R4ID0gdGhpcy5jdHggfHwgdGhpcy5jYW52YXMuZ2V0Q29udGV4dChcIjJkXCIpO1xuICAgIHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuY2FudmFzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSBuZXh0IGZyYW1lXG4gICAqL1xuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnJhbWUpIHtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKGZyYW1lKSA9PiB7XG4gICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb25GcmFtZShmcmFtZSk7XG4gICAgfSk7XG4gICAgdGhpcy5wYWludChmcmFtZSk7XG4gICAgdGhpcy5sYXN0RnJhbWUgPSBmcmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgd2luZG93IHJlc2l6ZVxuICAgKi9cbiAgcmVzaXplKCkge1xuICAgIHRoaXMuY2FudmFzLndpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gdGhpcy5oZWlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXIgdGhlIGNhbnZhc1xuICAgKi9cbiAgY2xlYXIoKSB7XG4gICAgdGhpcy5jdHguY2xlYXJSZWN0KDAsIDAsIHRoaXMuY2FudmFzLndpZHRoLCB0aGlzLmNhbnZhcy5oZWlnaHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZCB2YWx1ZXNcbiAgICovXG4gIGFwcGVuZCh0aW1lLCB2YWx1ZXMsIG5vdGVzKSB7XG4gICAgdGhpcy5sYXN0QXBwZW5kVGltZSA9IHRpbWU7XG4gICAgdGhpcy5sYXN0QXBwZW5kRnJhbWUgPSB0aGlzLmxhc3RGcmFtZTtcbiAgICB0aGlzLnZhbHVlcyA9IHRoaXMudmFsdWVzXG4gICAgICAuY29uY2F0KHZhbHVlcylcbiAgICAgIC5zbGljZSgtdGhpcy5jYW52YXMud2lkdGgpXG4gICAgICAuc29ydCgoYSwgYikgPT4gYVswXSAtIGJbMF0pO1xuXG4gICAgaWYgKG5vdGVzPy5sZW5ndGgpIHtcbiAgICAgIHRoaXMubm90ZXMgPSB0aGlzLm5vdGVzXG4gICAgICAgIC5jb25jYXQobm90ZXMpXG4gICAgICAgIC5zbGljZSgtNTApXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhWzBdIC0gYlswXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhaW50IHRoZSBjYW52YXNcbiAgICovXG4gIHBhaW50KGZyYW1lKSB7XG4gICAgdGhpcy5jbGVhcigpO1xuICAgIHRoaXMuZHJhd1JlbGFiaVdhdmUoZnJhbWUpO1xuICAgIHRoaXMuZHJhd0JvdW5kcygpO1xuICAgIHRoaXMuZHJhd05vdGVzKGZyYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEcmF3IHRoZSBib3VuZHNcbiAgICovXG4gIGRyYXdCb3VuZHMoKSB7XG4gICAgY29uc3QgeyBjYW52YXMsIGN0eCB9ID0gdGhpcztcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGNhbnZhcztcblxuICAgIC8vIERyYXcgZGFzaGVkIGxpbmVzIGZvciBhbGwgYm91bmRzXG4gICAgZm9yIChjb25zdCBib3VuZCBvZiB0aGlzLnJlbGFiaS5ib3VuZHMpIHtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KGJvdW5kLmxldmVsLCBoZWlnaHQpO1xuXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XG4gICAgICBjdHguc2V0TGluZURhc2goWzQsIDRdKTtcbiAgICAgIGN0eC5saW5lV2lkdGggPSAxO1xuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gYm91bmQuY29sb3IgfHwgXCIjODg4XCI7XG4gICAgICBjdHgubW92ZVRvKDAsIHkpO1xuICAgICAgY3R4LmxpbmVUbyh3aWR0aCwgeSk7XG4gICAgICBjdHguc3Ryb2tlKCk7XG4gICAgfVxuXG4gICAgLy8gRHJhdyB0aGUgemVybyBwb3NpdGlvblxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHguc2V0TGluZURhc2goWzEsIDFdKTtcbiAgICBjdHgubGluZVdpZHRoID0gMjtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBcIiM2NjZcIjtcbiAgICBjdHgubW92ZVRvKHdpZHRoIC0gdGhpcy50WmVyb09mZnNldCwgMCk7XG4gICAgY3R4LmxpbmVUbyh3aWR0aCAtIHRoaXMudFplcm9PZmZzZXQsIGhlaWdodCk7XG4gICAgY3R4LnN0cm9rZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERyYXcgdGhlIHJlbGFiaSB3YXZlXG4gICAqL1xuICBkcmF3UmVsYWJpV2F2ZShmcmFtZSkge1xuICAgIGNvbnN0IHsgY2FudmFzLCBjdHggfSA9IHRoaXM7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBjYW52YXM7XG5cbiAgICBjb25zdCBwb2ludENvdW50ID0gdGhpcy52YWx1ZXMubGVuZ3RoO1xuICAgIGxldCBpbmRleCA9IDA7XG5cbiAgICAvLyBTdGFydCB0aGUgcGF0aFxuICAgIGN0eC5iZWdpblBhdGgoKTtcbiAgICBjdHguc3Ryb2tlU3R5bGUgPSBcIiNkZmZcIjtcbiAgICBjdHgubGluZVdpZHRoID0gMC43NTtcbiAgICBjdHguc2V0TGluZURhc2goW10pO1xuXG4gICAgLy8gVGhpcyBpcyB0aGUgb2Zmc2V0IGluIHNlY29uZHMgZnJvbSB0aGUgbGFzdCBmcmFtZSB3ZSBjb21wdXRlZFxuICAgIGNvbnN0IGZyYW1lT2Zmc2V0ID0gKGZyYW1lIC0gdGhpcy5sYXN0QXBwZW5kRnJhbWUpIC8gMTAwMDtcblxuICAgIC8vIE1ha2UgYSBwYXRoIGNvbm5lY3RpbmcgYWxsIHZhbHVlc1xuICAgIGZvciAoY29uc3QgcG9pbnQgb2YgdGhpcy52YWx1ZXMpIHtcbiAgICAgIGlmICghcG9pbnQpIHtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFt0aW1lLCB2YWx1ZV0gPSBwb2ludDtcblxuICAgICAgLy8gVGhpcyBpcyB0aGUgb2Zmc2V0IG9mIHRoaXMgdGltZSBmcm9tIGN1cnJlbnQgdGltZVxuICAgICAgLy8gSWYgdGhpcyBpcyBpbiB0aGUgZnV0dXJlLCBpdCB3aWxsIGJlIHBvc2l0aXZlLlxuICAgICAgLy8gU3VidHJhY3RpbmcgdGhlIGZyYW1lIG9mZnNldCBwdWxscyBpdCBuZWdhdGl2ZS5cbiAgICAgIGNvbnN0IHRpbWVPZmZzZXQgPSB0aGlzLmxhc3RBcHBlbmRUaW1lICsgZnJhbWVPZmZzZXQgLSB0aW1lO1xuXG4gICAgICBjb25zdCB4ID0gd2lkdGggLSB0aW1lT2Zmc2V0ICogdGhpcy5zcGVlZCAqIHdpZHRoIC0gdGhpcy50WmVyb09mZnNldDtcbiAgICAgIGNvbnN0IHkgPSBnZXRXYXZlSGVpZ2h0KHZhbHVlLCBoZWlnaHQpO1xuXG4gICAgICBpZiAoeCA8IDApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgICBjdHgubW92ZVRvKHgsIHkpO1xuICAgICAgfVxuICAgICAgY3R4LmxpbmVUbyh4LCB5KTtcbiAgICAgIGluZGV4ICs9IDE7XG4gICAgfVxuXG4gICAgLy8gUGFpbnQgdGhlIGxpbmVcbiAgICBjdHguc3Ryb2tlKCk7XG4gIH1cblxuICAvKipcbiAgICogRHJhdyB0aGUgbm90ZXNcbiAgICovXG4gIGRyYXdOb3RlcyhmcmFtZSkge1xuICAgIGNvbnN0IHsgY2FudmFzLCBjdHggfSA9IHRoaXM7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBjYW52YXM7XG5cbiAgICAvLyBUaGlzIGlzIHRoZSBvZmZzZXQgaW4gc2Vjb25kcyBmcm9tIHRoZSBsYXN0IGZyYW1lIHdlIGNvbXB1dGVkXG4gICAgY29uc3QgZnJhbWVPZmZzZXQgPSAoZnJhbWUgLSB0aGlzLmxhc3RBcHBlbmRGcmFtZSkgLyAxMDAwO1xuXG4gICAgLy8gTWFrZSBhIHBhdGggY29ubmVjdGluZyBhbGwgdmFsdWVzXG4gICAgZm9yIChjb25zdCBub3RlIG9mIHRoaXMubm90ZXMpIHtcbiAgICAgIGNvbnN0IFt0aW1lLCB2YWx1ZSwgZGlyZWN0aW9uXSA9IG5vdGU7XG4gICAgICBjb25zdCB0aW1lT2Zmc2V0ID0gdGhpcy5sYXN0QXBwZW5kVGltZSArIGZyYW1lT2Zmc2V0IC0gdGltZTtcbiAgICAgIGNvbnN0IHggPSB3aWR0aCAtIHRpbWVPZmZzZXQgKiB0aGlzLnNwZWVkICogd2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0O1xuICAgICAgY29uc3QgeSA9IGdldFdhdmVIZWlnaHQodmFsdWUsIGhlaWdodCk7XG5cbiAgICAgIC8vIERvbid0IGRyYXcgbm90ZXMgdGhhdCBoYXZlbid0IHBsYXllZCB5ZXRcbiAgICAgIGlmICh4ID4gd2lkdGggLSB0aGlzLnRaZXJvT2Zmc2V0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBEcmF3IG5vdGVzIGFzIGEgZG90IHRoYXQgZmFkZXMgb3V0XG4gICAgICBjb25zdCBvcGFjaXR5ID0gMSAtICh0aW1lT2Zmc2V0ICogdGhpcy5zcGVlZCAqIHdpZHRoKSAvIDEwMDA7XG4gICAgICBpZiAob3BhY2l0eSA8IDAuMDAxKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuICAgICAgY3R4LmFyYyh4IC0gMi41LCB5LCA1LCAwLCAyICogTWF0aC5QSSk7XG4gICAgICBjdHguZmlsbFN0eWxlID0gZGlyZWN0aW9uXG4gICAgICAgID8gYHJnYmEoMjU1LDEyOCwxOTIsJHtvcGFjaXR5fSlgXG4gICAgICAgIDogYHJnYmEoMTkyLDI1NSwxMjgsJHtvcGFjaXR5fSlgO1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgdGhlIGhlaWdodCBvZiB0aGUgd2F2ZSBhdCBhIGdpdmVuIHZhbHVlXG4gKi9cbmNvbnN0IGdldFdhdmVIZWlnaHQgPSAodmFsdWUsIGhlaWdodCkgPT4gKCh2YWx1ZSArIDEpIC8gMikgKiBoZWlnaHQ7XG4iLCIvKipcbiAqIFJlbGFiaSBldmVudCBnZW5lcmF0b3JcbiAqL1xuXG5pbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgUmVsYWJpQ2FudmFzIGZyb20gXCIuL2NhbnZhc1wiO1xuXG5jb25zdCBUV09fUEkgPSAyICogTWF0aC5QSTtcblxuLyoqXG4gKiBXYXZlIGZ1bmN0aW9uc1xuICovXG5jb25zdCBXQVZFX0ZVTkNUSU9OUyA9IHtcbiAgc2luZTogTWF0aC5jb3MsXG4gIHRyaWFuZ2xlOiAodGltZSkgPT5cbiAgICAoNCAvIFRXT19QSSkgKlxuICAgICAgTWF0aC5hYnMoXG4gICAgICAgICgoKCh0aW1lIC0gVFdPX1BJIC8gNCkgJSBUV09fUEkpICsgVFdPX1BJKSAlIFRXT19QSSkgLSBUV09fUEkgLyAyXG4gICAgICApIC1cbiAgICAxLFxuICBzcXVhcmU6ICh0aW1lKSA9PiAodGltZSAlIFRXT19QSSA8IE1hdGguUEkgPyAxIDogLTEpLFxuICBzYXc6ICh0aW1lKSA9PiAoKHRpbWUgJSBUV09fUEkpIC0gTWF0aC5QSSkgLyBNYXRoLlBJLFxufTtcblxuLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlbGFiaSB7XG4gIC8qKlxuICAgKiBJbml0aWFsaXplIGdlbmVyYXRvclxuICAgKi9cbiAgY29uc3RydWN0b3IoeyB3YXZlcywgYm91bmRzLCBwYXJlbnQgfSkge1xuICAgIHRoaXMudXBkYXRlVGltZSA9IDE7XG4gICAgdGhpcy5zdGVwcyA9IDUwO1xuICAgIHRoaXMud2F2ZXMgPSB3YXZlcyB8fCBbXG4gICAgICB7IHR5cGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC41LCAxLjUpIH0sXG4gICAgICB7IHR5cGU6IFwidHJpYW5nbGVcIiwgZnJlcXVlbmN5OiByYW5kcmFuZ2UoMC43NSwgMi4yNSkgfSxcbiAgICAgIHsgdHlwZTogXCJ0cmlhbmdsZVwiLCBmcmVxdWVuY3k6IHJhbmRyYW5nZSgxLCAzKSB9LFxuICAgICAgeyB0eXBlOiBcInRyaWFuZ2xlXCIsIGZyZXF1ZW5jeTogcmFuZHJhbmdlKDIsIDQpIH0sXG4gICAgXTtcbiAgICB0aGlzLmJvdW5kcyA9IGJvdW5kcztcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBudWxsO1xuICAgIHRoaXMuY2FudmFzID0gbmV3IFJlbGFiaUNhbnZhcyh7IHJlbGFiaTogdGhpcywgcGFyZW50IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBnZW5lcmF0b3JcbiAgICovXG4gIHN0YXJ0KCkge1xuICAgIGNvbnNvbGUubG9nKFwiU3RhcnQgUmVsYWJpXCIpO1xuICAgIHRoaXMuc3RvcCgpO1xuICAgIHRoaXMuY2xvY2sgPSBuZXcgVG9uZS5DbG9jaygodGltZSkgPT4ge1xuICAgICAgY29uc3QgdmFsdWVzID0gdGhpcy5nZW5lcmF0ZSh0aW1lKTtcbiAgICAgIGNvbnN0IG5vdGVzID0gdGhpcy5wbGF5KHZhbHVlcyk7XG4gICAgICB0aGlzLmNhbnZhcy5hcHBlbmQodGltZSwgdmFsdWVzLCBub3Rlcyk7XG4gICAgfSwgdGhpcy51cGRhdGVUaW1lKTtcbiAgICB0aGlzLmNsb2NrLnN0YXJ0KCk7XG4gIH1cblxuICAvKipcbiAgICogU3RvcCB0aGUgZ2VuZXJhdG9yIGFuZCByZXNldCBpdFxuICAgKi9cbiAgc3RvcCgpIHtcbiAgICBpZiAodGhpcy5jbG9jaykge1xuICAgICAgdGhpcy5jbG9jay5zdG9wKCk7XG4gICAgICB0aGlzLmNsb2NrLmRpc3Bvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGUgcmVsYWJpIGV2ZW50c1xuICAgKi9cbiAgZ2VuZXJhdGUodGltZSkge1xuICAgIGNvbnN0IHdhdmVDb3VudCA9IHRoaXMud2F2ZXMubGVuZ3RoO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgdmFsdWU7XG4gICAgbGV0IHZhbHVlcyA9IFtdO1xuXG4gICAgLy8gT3ZlcnNob290IHRoZSBsaW5lIHNsaWdodGx5IGVhY2ggdGltZVxuICAgIGxldCBzdGVwQ291bnQgPSB0aGlzLnN0ZXBzICsgMjA7XG5cbiAgICAvLyBHZW5lcmF0ZSBzZXZlcmFsIGV2ZW50cyBwZXIgc2Vjb25kXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHN0ZXBDb3VudDsgc3RlcCArPSAxKSB7XG4gICAgICAvLyBUaW1lIG9mZnNldCBmb3IgdGhpcyBldmVudFxuICAgICAgY29uc3QgdGltZU9mZnNldCA9IHRpbWUgKyAoc3RlcCAqIHRoaXMudXBkYXRlVGltZSkgLyB0aGlzLnN0ZXBzO1xuXG4gICAgICAvLyBJbml0aWFsaXplIHZhbHVlXG4gICAgICB2YWx1ZSA9IDA7XG5cbiAgICAgIC8vIENvbXB1dGUgdGhlIHdhdmUgZnVuY3Rpb25zIGZvciB0aGlzIGV2ZW50XG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCB3YXZlQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICAgICAgY29uc3Qgd2F2ZSA9IHRoaXMud2F2ZXNbaW5kZXhdO1xuICAgICAgICB2YWx1ZSArPSBXQVZFX0ZVTkNUSU9OU1t3YXZlLnR5cGVdKHRpbWVPZmZzZXQgKiB3YXZlLmZyZXF1ZW5jeSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNjYWxlIHRvIFstMSwgMV1cbiAgICAgIHZhbHVlIC89IHdhdmVDb3VudDtcblxuICAgICAgdmFsdWVzLnB1c2goW3RpbWVPZmZzZXQsIHZhbHVlXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTY2hlZHVsZSByZWxhYmkgZXZlbnRzXG4gICAqL1xuICBwbGF5KHZhbHVlcykge1xuICAgIGNvbnN0IGJvdW5kc0NvdW50ID0gdGhpcy5ib3VuZHMubGVuZ3RoO1xuICAgIGxldCBwcmV2aW91c1ZhbHVlID0gdGhpcy5wcmV2aW91c1ZhbHVlO1xuICAgIGxldCBpbmRleDtcbiAgICBsZXQgc3RlcDtcbiAgICBsZXQgbm90ZUNvdW50ID0gMDtcbiAgICBjb25zdCBub3RlcyA9IFtdO1xuXG4gICAgZm9yIChzdGVwID0gMDsgc3RlcCA8IHRoaXMuc3RlcHM7IHN0ZXAgKz0gMSkge1xuICAgICAgLy8gR2V0IHRoZSBuZXh0IHZhbHVlXG4gICAgICBjb25zdCBbdGltZSwgdmFsdWVdID0gdmFsdWVzW3N0ZXBdO1xuXG4gICAgICAvLyBDb21wdXRlIHdoZXRoZXIgd2UgY3Jvc3NlZCBhIGJvdW5kYXJ5LCBhbmQgd2hpY2ggZGlyZWN0aW9uXG4gICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBib3VuZHNDb3VudDsgaW5kZXggKz0gMSkge1xuICAgICAgICBjb25zdCBib3VuZCA9IHRoaXMuYm91bmRzW2luZGV4XTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHZhbHVlIDwgYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA8IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIGRvd25cbiAgICAgICAgICB0aGlzLnRyaWdnZXIodGltZSwgYm91bmQuc291bmRzWzBdKTtcbiAgICAgICAgICBub3Rlcy5wdXNoKFt0aW1lLCBib3VuZC5sZXZlbCwgdHJ1ZV0pO1xuICAgICAgICAgIG5vdGVDb3VudCArPSAxO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIHZhbHVlID4gYm91bmQubGV2ZWwgJiZcbiAgICAgICAgICBib3VuZC5sZXZlbCA+IHByZXZpb3VzVmFsdWUgJiZcbiAgICAgICAgICBwcmV2aW91c1ZhbHVlICE9PSBudWxsXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEdvaW5nIHVwXG4gICAgICAgICAgdGhpcy50cmlnZ2VyKHRpbWUsIGJvdW5kLnNvdW5kc1sxXSk7XG4gICAgICAgICAgbm90ZXMucHVzaChbdGltZSwgYm91bmQubGV2ZWwsIGZhbHNlXSk7XG4gICAgICAgICAgbm90ZUNvdW50ICs9IDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIHRoZSBwcmV2aW91cyB2YWx1ZVxuICAgICAgcHJldmlvdXNWYWx1ZSA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFN0b3JlIHRoZSBsYXRlc3QgdmFsdWVcbiAgICB0aGlzLnByZXZpb3VzVmFsdWUgPSBwcmV2aW91c1ZhbHVlO1xuXG4gICAgLy8gUmV0dXJuIHRoZSBub3Rlc1xuICAgIHJldHVybiBub3RlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGV2ZW50XG4gICAqL1xuICB0cmlnZ2VyKHRpbWUsIHNvdW5kKSB7XG4gICAgLy8gY29uc29sZS5sb2coXCJ0cmlnZ2VyIGluZGV4XCIsIGluZGV4LCB0aW1lKTtcbiAgICBzb3VuZC5pbnN0cnVtZW50LnBsYXkodGltZSwgc291bmQpO1xuICB9XG59XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5cbmNvbnN0IGNvbXByZXNzb3IgPSBuZXcgVG9uZS5Db21wcmVzc29yKC0zMCwgMyk7XG5jb25zdCBnYWluID0gbmV3IFRvbmUuR2FpbigwLjMpO1xuY29tcHJlc3Nvci5jb25uZWN0KGdhaW4pO1xuZ2Fpbi50b0Rlc3RpbmF0aW9uKCk7XG5cbmV4cG9ydCBkZWZhdWx0IGNvbXByZXNzb3I7XG4iLCJpbXBvcnQgKiBhcyBUb25lIGZyb20gXCJ0b25lXCI7XG5pbXBvcnQgeyBjaG9pY2UsIHJhbmRyYW5nZSB9IGZyb20gXCIuL3V0aWxcIjtcbmltcG9ydCBvdXRwdXQgZnJvbSBcIi4vb3V0cHV0XCI7XG5cbmNvbnN0IFBMQVlFUl9DT1VOVCA9IDQ7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNhbXBsZXIge1xuICBjb25zdHJ1Y3Rvcih7IHNhbXBsZXMsIHRvbmFsIH0pIHtcbiAgICB0aGlzLnRvbmFsID0gdG9uYWw7XG4gICAgdGhpcy5zYW1wbGVzID0gc2FtcGxlcy5tYXAoKHsgLi4uc2FtcGxlIH0pID0+IHtcbiAgICAgIHNhbXBsZS5wbGF5ZXJzID0gW107XG4gICAgICBzYW1wbGUuaW5kZXggPSAtMTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgUExBWUVSX0NPVU5UOyBpKyspIHtcbiAgICAgICAgbGV0IGZuID0gc2FtcGxlLmZuO1xuICAgICAgICBpZiAod2luZG93LmxvY2F0aW9uLmhyZWYubWF0Y2goL2FzZGYudXMvKSkge1xuICAgICAgICAgIGZuID0gXCIvL2FzZGYudXMva2FsaW1iYS9cIiArIGZuO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwbGF5ZXIgPSBuZXcgVG9uZS5QbGF5ZXIoe1xuICAgICAgICAgIHVybDogZm4sXG4gICAgICAgICAgcmV0cmlnZ2VyOiB0cnVlLFxuICAgICAgICAgIHBsYXliYWNrUmF0ZTogMSxcbiAgICAgICAgfSk7XG4gICAgICAgIHBsYXllci5jb25uZWN0KG91dHB1dCk7XG4gICAgICAgIHNhbXBsZS5wbGF5ZXJzLnB1c2gocGxheWVyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW1wbGU7XG4gICAgfSk7XG4gIH1cblxuICBwbGF5KHRpbWUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBzb3VuZCA9IG9wdGlvbnMuaW5kZXhcbiAgICAgID8gdGhpcy5zYW1wbGVzW29wdGlvbnMuaW5kZXhdXG4gICAgICA6IGNob2ljZSh0aGlzLnNhbXBsZXMpO1xuXG4gICAgc291bmQuaW5kZXggPSAoc291bmQuaW5kZXggKyAxKSAlIFBMQVlFUl9DT1VOVDtcblxuICAgIGNvbnN0IHBsYXllciA9IHNvdW5kLnBsYXllcnNbc291bmQuaW5kZXhdO1xuXG4gICAgaWYgKHRoaXMudG9uYWwpIHtcbiAgICAgIHBsYXllci5wbGF5YmFja1JhdGUgPVxuICAgICAgICAob3B0aW9ucy5mcmVxdWVuY3kgKiBjaG9pY2UoWzAuNSwgMV0pICsgcmFuZHJhbmdlKDAsIDEwKSkgLyBzb3VuZC5yb290O1xuICAgIH1cblxuICAgIHBsYXllci5zdGFydCh0aW1lIHx8IDApO1xuICB9XG59XG4iLCJpbXBvcnQgU2FtcGxlciBmcm9tIFwiLi9zYW1wbGVyXCI7XG5cbmV4cG9ydCBjb25zdCBLYWxpbWJhID0gbmV3IFNhbXBsZXIoe1xuICB0b25hbDogdHJ1ZSxcbiAgc2FtcGxlczogW1xuICAgIHsgcm9vdDogMjI2LCBmbjogXCJzYW1wbGVzLzM4MDczN19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDEtYS1yYXcubXAzXCIgfSxcbiAgICB7IHJvb3Q6IDI2NywgZm46IFwic2FtcGxlcy8zODA3MzZfX2NhYmxlZC1tZXNzX19zYW5zdWxhLTAyLWMtcmF3Lm1wM1wiIH0sXG4gICAgeyByb290OiAzNDAsIGZuOiBcInNhbXBsZXMvMzgwNzM1X19jYWJsZWQtbWVzc19fc2Fuc3VsYS0wMy1lLXJhdy5tcDNcIiB9LFxuICAgIHsgcm9vdDogNDUyLCBmbjogXCJzYW1wbGVzLzM4MDczM19fY2FibGVkLW1lc3NfX3NhbnN1bGEtMDYtYS0wMi1yYXcubXAzXCIgfSxcbiAgXSxcbn0pO1xuXG5leHBvcnQgY29uc3QgRHJ1bXMgPSBuZXcgU2FtcGxlcih7XG4gIHRvbmFsOiBmYWxzZSxcbiAgc2FtcGxlczogW1xuICAgIHsgZm46IFwic2FtcGxlcy83MDdfYmQubXAzXCIgfSxcbiAgICB7IGZuOiBcInNhbXBsZXMvNzA3X2NsYXAubXAzXCIgfSxcbiAgICAvLyB7IGZuOiBcInNhbXBsZXMvNzA3X2Nvdy5tcDNcIiB9LFxuICAgIHsgZm46IFwic2FtcGxlcy83MDdfaGF0Lm1wM1wiIH0sXG4gICAgeyBmbjogXCJzYW1wbGVzLzcwN19yaW0ubXAzXCIgfSxcbiAgXSxcbn0pO1xuIiwiLyoqXG4gKiBSZWxhYmkgZ2VuZXJhdG9yIFVJXG4gKiBAbW9kdWxlIHNyYy91aS9BcHAuanM7XG4gKi9cblxuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyB1c2VTdGF0ZSwgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBSZWxhYmkgZnJvbSBcIi4uL3JlbGFiaVwiO1xuaW1wb3J0IHsgS2FsaW1iYSwgRHJ1bXMgfSBmcm9tIFwiLi4vbGliL2luc3RydW1lbnRzXCI7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFwcCgpIHtcbiAgY29uc3QgW3JlbGFiaSwgc2V0UmVsYWJpXSA9IHVzZVN0YXRlKCk7XG4gIGNvbnN0IHJlbGFiaVJlZiA9IHVzZVJlZigpO1xuXG4gIC8qKlxuICAgKiBJbnN0YW50aWF0ZSB0aGUgUmVsYWJpIGdlbmVyYXRvclxuICAgKi9cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoIXJlbGFiaSkge1xuICAgICAgY29uc3QgcmVsYWJpR2VuZXJhdG9yID0gbmV3IFJlbGFiaSh7XG4gICAgICAgIHdhdmVzOiBbXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAwLjc1IH0sXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAxLjAgfSxcbiAgICAgICAgICB7IHR5cGU6IFwic2luZVwiLCBmcmVxdWVuY3k6IDEuNjE3IH0sXG4gICAgICAgICAgeyB0eXBlOiBcInNpbmVcIiwgZnJlcXVlbmN5OiAzLjE0MSB9LFxuICAgICAgICBdLFxuICAgICAgICBib3VuZHM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogLTAuNzUsXG4gICAgICAgICAgICBjb2xvcjogXCIjZjMzXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDAgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBEcnVtcywgaW5kZXg6IDEgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsZXZlbDogMC43NSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiNmODNcIixcbiAgICAgICAgICAgIHNvdW5kczogW1xuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IERydW1zLCBpbmRleDogMiB9LFxuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IERydW1zLCBpbmRleDogMyB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGxldmVsOiAtMC4yNSxcbiAgICAgICAgICAgIGNvbG9yOiBcIiMzYjhcIixcbiAgICAgICAgICAgIHNvdW5kczogW1xuICAgICAgICAgICAgICB7IGluc3RydW1lbnQ6IEthbGltYmEsIGZyZXF1ZW5jeTogNDQwIH0sXG4gICAgICAgICAgICAgIHsgaW5zdHJ1bWVudDogS2FsaW1iYSwgZnJlcXVlbmN5OiAoNDQwICogMykgLyAyIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgbGV2ZWw6IDAuMjUsXG4gICAgICAgICAgICBjb2xvcjogXCIjMzZmXCIsXG4gICAgICAgICAgICBzb3VuZHM6IFtcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDUgfSxcbiAgICAgICAgICAgICAgeyBpbnN0cnVtZW50OiBLYWxpbWJhLCBmcmVxdWVuY3k6ICg0NDAgKiA2KSAvIDcgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgICAgcmVsYWJpR2VuZXJhdG9yLnN0YXJ0KCk7XG4gICAgICBzZXRSZWxhYmkocmVsYWJpR2VuZXJhdG9yKTtcbiAgICB9XG4gIH0sIFtyZWxhYmldKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChyZWxhYmkgJiYgcmVsYWJpUmVmLmN1cnJlbnQpIHtcbiAgICAgIHJlbGFiaS5jYW52YXMuYXBwZW5kQ2FudmFzKHJlbGFiaVJlZi5jdXJyZW50KTtcbiAgICB9XG4gIH0sIFtyZWxhYmksIHJlbGFiaVJlZi5jdXJyZW50XSk7XG5cbiAgLyoqXG4gICAqIFJlbmRlclxuICAgKi9cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBzdHlsZT17e1xuICAgICAgICBoZWlnaHQ6IFwiMTAwJVwiLFxuICAgICAgICB3aWR0aDogXCIxMDAlXCIsXG4gICAgICAgIHBhZGRpbmc6IDAsXG4gICAgICAgIG1hcmdpbjogMCxcbiAgICAgICAgZGlzcGxheTogXCJmbGV4XCIsXG4gICAgICAgIGZsZXhEaXJlY3Rpb246IFwiY29sdW1uXCIsXG4gICAgICAgIGp1c3RpZnlDb250ZW50OiBcImNlbnRlclwiLFxuICAgICAgfX1cbiAgICA+XG4gICAgICA8ZGl2IHJlZj17cmVsYWJpUmVmfSAvPlxuICAgIDwvZGl2PlxuICApO1xufVxuIiwiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBjcmVhdGVSb290IH0gZnJvbSBcInJlYWN0LWRvbS9jbGllbnRcIjtcbmltcG9ydCB7IHJlcXVlc3RBdWRpb0NvbnRleHQsIHJhbmRyYW5nZSB9IGZyb20gXCIuL2xpYi91dGlsXCI7XG5cbmltcG9ydCBBcHAgZnJvbSBcIi4vdWkvQXBwLmpzeFwiO1xuXG5kb2N1bWVudC5ib2R5LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiIzExMVwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5jb2xvciA9IFwiI2ZmZlwiO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5tYXJnaW4gPSAwO1xuZG9jdW1lbnQuYm9keS5zdHlsZS5wYWRkaW5nID0gMDtcbmRvY3VtZW50LmJvZHkuc3R5bGUuaGVpZ2h0ID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnN0eWxlLndpZHRoID0gXCIxMDAlXCI7XG5kb2N1bWVudC5ib2R5LnBhcmVudE5vZGUuc3R5bGUubWFyZ2luID0gMDtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5wYWRkaW5nID0gMDtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS5oZWlnaHQgPSBcIjEwMCVcIjtcbmRvY3VtZW50LmJvZHkucGFyZW50Tm9kZS5zdHlsZS53aWR0aCA9IFwiMTAwJVwiO1xuXG5yZXF1ZXN0QXVkaW9Db250ZXh0KCgpID0+IHtcbiAgY29uc3QgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgY29udGFpbmVyLnN0eWxlLmhlaWdodCA9IFwiMTAwJVwiO1xuICBjb250YWluZXIuc3R5bGUud2lkdGggPSBcIjEwMCVcIjtcbiAgZG9jdW1lbnQuYm9keS5pbm5lckhUTUwgPSBcIlwiO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gIGNvbnN0IHJvb3QgPSBjcmVhdGVSb290KGNvbnRhaW5lcik7XG4gIHJvb3QucmVuZGVyKDxBcHAgLz4pO1xufSk7XG4iXSwibmFtZXMiOlsiVG9uZSIsIlN0YXJ0QXVkaW9Db250ZXh0IiwiaXNJcGhvbmUiLCJuYXZpZ2F0b3IiLCJ1c2VyQWdlbnQiLCJtYXRjaCIsImlzSXBhZCIsImlzQW5kcm9pZCIsImlzTW9iaWxlIiwiaXNEZXNrdG9wIiwiZG9jdW1lbnQiLCJib2R5IiwiY2xhc3NMaXN0IiwiYWRkIiwiYnJvd3NlciIsImNob2ljZSIsImEiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJsZW5ndGgiLCJtb2QiLCJuIiwibSIsInJhbmQiLCJyYW5kaW50IiwicmFuZHJhbmdlIiwiYiIsInJhbmRzaWduIiwicmFuZG51bGxzaWduIiwiciIsInJlcXVlc3RBdWRpb0NvbnRleHQiLCJmbiIsImNvbnRhaW5lciIsImNyZWF0ZUVsZW1lbnQiLCJidXR0b24iLCJpbm5lckhUTUwiLCJPYmplY3QiLCJhc3NpZ24iLCJzdHlsZSIsImRpc3BsYXkiLCJwb3NpdGlvbiIsIndpZHRoIiwiaGVpZ2h0IiwiekluZGV4IiwidG9wIiwibGVmdCIsImJhY2tncm91bmRDb2xvciIsInBhZGRpbmciLCJjb2xvciIsImZvbnRGYW1pbHkiLCJib3JkZXJSYWRpdXMiLCJ0cmFuc2Zvcm0iLCJ0ZXh0QWxpZ24iLCJsaW5lSGVpZ2h0IiwiYXBwZW5kQ2hpbGQiLCJzZXRDb250ZXh0IiwiY29udGV4dCIsIm9uIiwib25TdGFydGVkIiwiXyIsInJlbW92ZSIsIlJlbGFiaUNhbnZhcyIsIl9yZWYiLCJyZWxhYmkiLCJwYXJlbnQiLCJfY2xhc3NDYWxsQ2hlY2siLCJsYXN0RnJhbWUiLCJsYXN0QXBwZW5kVGltZSIsImxhc3RBcHBlbmRGcmFtZSIsInNwZWVkIiwidFplcm9PZmZzZXQiLCJhcHBlbmRDYW52YXMiLCJ2YWx1ZXMiLCJBcnJheSIsIndpbmRvdyIsImlubmVyV2lkdGgiLCJmaWxsIiwibm90ZXMiLCJhcHBlbmQiLCJyZXNpemUiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJfY3JlYXRlQ2xhc3MiLCJrZXkiLCJ2YWx1ZSIsImNhbnZhcyIsImN0eCIsImdldENvbnRleHQiLCJfcmVxdWVzdEFuaW1hdGlvbkZyYW1lIiwiX3giLCJhcHBseSIsImFyZ3VtZW50cyIsInRvU3RyaW5nIiwiZnJhbWUiLCJfdGhpcyIsInBhaW50IiwiY2xlYXIiLCJjbGVhclJlY3QiLCJ0aW1lIiwiY29uY2F0Iiwic2xpY2UiLCJzb3J0IiwiZHJhd1JlbGFiaVdhdmUiLCJkcmF3Qm91bmRzIiwiZHJhd05vdGVzIiwiX2l0ZXJhdG9yIiwiX2NyZWF0ZUZvck9mSXRlcmF0b3JIZWxwZXIiLCJib3VuZHMiLCJfc3RlcCIsInMiLCJkb25lIiwiYm91bmQiLCJ5IiwiZ2V0V2F2ZUhlaWdodCIsImxldmVsIiwiYmVnaW5QYXRoIiwic2V0TGluZURhc2giLCJsaW5lV2lkdGgiLCJzdHJva2VTdHlsZSIsIm1vdmVUbyIsImxpbmVUbyIsInN0cm9rZSIsImVyciIsImUiLCJmIiwicG9pbnRDb3VudCIsImluZGV4IiwiZnJhbWVPZmZzZXQiLCJfaXRlcmF0b3IyIiwiX3N0ZXAyIiwicG9pbnQiLCJfcG9pbnQiLCJfc2xpY2VkVG9BcnJheSIsInRpbWVPZmZzZXQiLCJ4IiwiX2l0ZXJhdG9yMyIsIl9zdGVwMyIsIm5vdGUiLCJfbm90ZSIsImRpcmVjdGlvbiIsIm9wYWNpdHkiLCJhcmMiLCJQSSIsImZpbGxTdHlsZSIsImRlZmF1bHQiLCJUV09fUEkiLCJXQVZFX0ZVTkNUSU9OUyIsInNpbmUiLCJjb3MiLCJ0cmlhbmdsZSIsImFicyIsInNxdWFyZSIsInNhdyIsIlJlbGFiaSIsIndhdmVzIiwidXBkYXRlVGltZSIsInN0ZXBzIiwidHlwZSIsImZyZXF1ZW5jeSIsInByZXZpb3VzVmFsdWUiLCJzdGFydCIsImNvbnNvbGUiLCJsb2ciLCJzdG9wIiwiY2xvY2siLCJDbG9jayIsImdlbmVyYXRlIiwicGxheSIsImRpc3Bvc2UiLCJ3YXZlQ291bnQiLCJzdGVwIiwic3RlcENvdW50Iiwid2F2ZSIsInB1c2giLCJib3VuZHNDb3VudCIsIm5vdGVDb3VudCIsIl92YWx1ZXMkc3RlcCIsInRyaWdnZXIiLCJzb3VuZHMiLCJzb3VuZCIsImluc3RydW1lbnQiLCJjb21wcmVzc29yIiwiQ29tcHJlc3NvciIsImdhaW4iLCJHYWluIiwiY29ubmVjdCIsInRvRGVzdGluYXRpb24iLCJvdXRwdXQiLCJQTEFZRVJfQ09VTlQiLCJTYW1wbGVyIiwic2FtcGxlcyIsInRvbmFsIiwibWFwIiwiX3JlZjIiLCJzYW1wbGUiLCJfZXh0ZW5kcyIsIl9vYmplY3REZXN0cnVjdHVyaW5nRW1wdHkiLCJwbGF5ZXJzIiwiaSIsImxvY2F0aW9uIiwiaHJlZiIsInBsYXllciIsIlBsYXllciIsInVybCIsInJldHJpZ2dlciIsInBsYXliYWNrUmF0ZSIsIm9wdGlvbnMiLCJyb290IiwiS2FsaW1iYSIsIkRydW1zIiwiUmVhY3QiLCJ1c2VTdGF0ZSIsInVzZUVmZmVjdCIsInVzZVJlZiIsIkFwcCIsIl91c2VTdGF0ZSIsIl91c2VTdGF0ZTIiLCJzZXRSZWxhYmkiLCJyZWxhYmlSZWYiLCJyZWxhYmlHZW5lcmF0b3IiLCJjdXJyZW50IiwibWFyZ2luIiwiZmxleERpcmVjdGlvbiIsImp1c3RpZnlDb250ZW50IiwicmVmIiwiY3JlYXRlUm9vdCIsInBhcmVudE5vZGUiLCJyZW5kZXIiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///441\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\nwindow.__audio_context_started = false;\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" || window.__audio_context_started;\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 try {\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\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 window.__audio_context_started = true;\n } catch (error) {\n //\n }\n }\n return StartAudioContext;\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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LENBQUNFLGFBQWEsQ0FBQ1UsTUFBTSxFQUFFRCxDQUFDLEVBQUUsRUFBRTtVQUMvRFgsaUJBQWlCLENBQUNFLGFBQWEsQ0FBQ1MsQ0FBQyxDQUFDLENBQUN5QixPQUFPLENBQUMsQ0FBQztRQUM5QztRQUNBcEMsaUJBQWlCLENBQUNFLGFBQWEsR0FBRyxJQUFJO01BQ3hDOztNQUVBO01BQ0EsSUFBSUYsaUJBQWlCLENBQUNHLFVBQVUsRUFBRTtRQUNoQyxLQUFLLElBQUkrQyxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdsRCxpQkFBaUIsQ0FBQ0csVUFBVSxDQUFDUyxNQUFNLEVBQUVzQyxDQUFDLEVBQUUsRUFBRTtVQUM1RGxELGlCQUFpQixDQUFDRyxVQUFVLENBQUMrQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DO1FBQ0FsRCxpQkFBaUIsQ0FBQ0csVUFBVSxHQUFHLElBQUk7TUFDckM7TUFFQVosTUFBTSxDQUFDQyx1QkFBdUIsR0FBRyxJQUFJO0lBQ3ZDLENBQUMsQ0FBQyxPQUFPMkQsS0FBSyxFQUFFO01BQ2Q7SUFBQTtFQUVKO0VBRUEsT0FBT25ELGlCQUFpQjtBQUMxQixDQUFDLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZWxhYmkvLi9zcmMvbGliL3N0YXJ0QXVkaW9Db250ZXh0LmpzPzZlYmYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgU3RhcnRBdWRpb0NvbnRleHQuanNcbiAqICBAYXV0aG9yIFlvdGFtIE1hbm5cbiAqICBAbGljZW5zZSBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvTUlUIE1JVCBMaWNlbnNlXG4gKiAgQGNvcHlyaWdodCAyMDE2IFlvdGFtIE1hbm5cbiAqL1xuXG53aW5kb3cuX19hdWRpb19jb250ZXh0X3N0YXJ0ZWQgPSBmYWxzZTtcblxuKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkge1xuICAgIGRlZmluZShbXSwgZmFjdG9yeSk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiBtb2R1bGUuZXhwb3J0cykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpO1xuICB9IGVsc2Uge1xuICAgIHJvb3QuU3RhcnRBdWRpb0NvbnRleHQgPSBmYWN0b3J5KCk7XG4gIH1cbn0pKHRoaXMsIGZ1bmN0aW9uICgpIHtcbiAgLyoqXG4gICAqIFRoZSBTdGFydEF1ZGlvQ29udGV4dCBvYmplY3RcbiAgICovXG4gIHZhciBTdGFydEF1ZGlvQ29udGV4dCA9IHtcbiAgICAvKipcbiAgICAgKiBUaGUgYXVkaW8gY29udGV4dCBwYXNzZWQgaW4gYnkgdGhlIHVzZXJcbiAgICAgKiBAdHlwZSB7QXVkaW9Db250ZXh0fVxuICAgICAqL1xuICAgIGNvbnRleHQ6IG51bGwsXG4gICAgLyoqXG4gICAgICogVGhlIFRhcExpc3RlbmVycyBib3VuZCB0byB0aGUgZWxlbWVudHNcbiAgICAgKiBAdHlwZSB7QXJyYXl9XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdGFwTGlzdGVuZXJzOiBbXSxcbiAgICAvKipcbiAgICAgKiBDYWxsYmFja3MgdG8gaW52b2tlIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZFxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIF9vblN0YXJ0ZWQ6IFtdLFxuICB9O1xuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGNvbnRleHRcbiAgICogQHBhcmFtIHtBdWRpb0NvbnRleHR9IGN0eFxuICAgKiBAcmV0dXJucyB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5zZXRDb250ZXh0ID0gZnVuY3Rpb24gKGN0eCkge1xuICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQgPSBjdHg7XG4gICAgcmV0dXJuIFN0YXJ0QXVkaW9Db250ZXh0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSB0YXAgbGlzdGVuZXIgdG8gdGhlIGF1ZGlvIGNvbnRleHRcbiAgICogQHBhcmFtICB7QXJyYXl8RWxlbWVudHxTdHJpbmd8alF1ZXJ5fSBlbGVtZW50XG4gICAqIEByZXR1cm5zIHtTdGFydEF1ZGlvQ29udGV4dH1cbiAgICovXG4gIFN0YXJ0QXVkaW9Db250ZXh0Lm9uID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbGVtZW50KSB8fCAoTm9kZUxpc3QgJiYgZWxlbWVudCBpbnN0YW5jZW9mIE5vZGVMaXN0KSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGVsZW1lbnRbaV0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGVsZW1lbnQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Lm9uKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZWxlbWVudCkpO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudC5qcXVlcnkgJiYgdHlwZW9mIGVsZW1lbnQudG9BcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5vbihlbGVtZW50LnRvQXJyYXkoKSk7XG4gICAgfSBlbHNlIGlmIChFbGVtZW50ICYmIGVsZW1lbnQgaW5zdGFuY2VvZiBFbGVtZW50KSB7XG4gICAgICAvL2lmIGl0J3MgYW4gZWxlbWVudCwgY3JlYXRlIGEgVGFwTGlzdGVuZXJcbiAgICAgIHZhciB0YXAgPSBuZXcgVGFwTGlzdGVuZXIoZWxlbWVudCwgb25UYXApO1xuICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycy5wdXNoKHRhcCk7XG4gICAgfVxuICAgIHJldHVybiBTdGFydEF1ZGlvQ29udGV4dDtcbiAgfTtcblxuICAvKipcbiAgICogQmluZCBhIGNhbGxiYWNrIHRvIHdoZW4gdGhlIGF1ZGlvIGNvbnRleHQgaXMgc3RhcnRlZC5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2JcbiAgICogQHJldHVybiB7U3RhcnRBdWRpb0NvbnRleHR9XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5vblN0YXJ0ZWQgPSBmdW5jdGlvbiAoY2IpIHtcbiAgICAvL2lmIGl0J3MgYWxyZWFkeSBzdGFydGVkLCBpbnZva2UgdGhlIGNhbGxiYWNrXG4gICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0LmlzU3RhcnRlZCgpKSB7XG4gICAgICBjYigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkLnB1c2goY2IpO1xuICAgIH1cbiAgICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJldHVybnMgdHJ1ZSBpZiB0aGUgY29udGV4dCBpcyBzdGFydGVkXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBTdGFydEF1ZGlvQ29udGV4dC5pc1N0YXJ0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIChTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0ICE9PSBudWxsICYmXG4gICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuc3RhdGUgPT09IFwicnVubmluZ1wiKSB8fFxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkXG4gICAgKTtcbiAgfTtcblxuICAvKipcbiAgICogQGNsYXNzICBMaXN0ZW5zIGZvciBub24tZHJhZ2dpbmcgdGFwIGVuZHMgb24gdGhlIGdpdmVuIGVsZW1lbnRcbiAgICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgdmFyIFRhcExpc3RlbmVyID0gZnVuY3Rpb24gKGVsZW1lbnQpIHtcbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcblxuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSB0aGlzLl9tb3ZlZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IHRoaXMuX2VuZGVkLmJpbmQodGhpcyk7XG5cbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgdGhpcy5fYmluZGVkTW92ZSk7XG4gICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFwidG91Y2hlbmRcIiwgdGhpcy5fYmluZGVkRW5kKTtcbiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIGRyYWcgbW92ZSBldmVudFxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9tb3ZlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdGhpcy5fZHJhZ2dlZCA9IHRydWU7XG4gIH07XG5cbiAgLyoqXG4gICAqIHRhcCBlbmRlZCBsaXN0ZW5lclxuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLl9lbmRlZCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKCF0aGlzLl9kcmFnZ2VkKSB7XG4gICAgICBvblRhcCgpO1xuICAgIH1cbiAgICB0aGlzLl9kcmFnZ2VkID0gZmFsc2U7XG4gIH07XG5cbiAgLyoqXG4gICAqIHJlbW92ZSBhbGwgdGhlIGJvdW5kIGV2ZW50c1xuICAgKi9cbiAgVGFwTGlzdGVuZXIucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwidG91Y2htb3ZlXCIsIHRoaXMuX2JpbmRlZE1vdmUpO1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHRoaXMuX2JpbmRlZEVuZCk7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLl9iaW5kZWRFbmQpO1xuICAgIHRoaXMuX2JpbmRlZE1vdmUgPSBudWxsO1xuICAgIHRoaXMuX2JpbmRlZEVuZCA9IG51bGw7XG4gICAgdGhpcy5fZWxlbWVudCA9IG51bGw7XG4gIH07XG5cbiAgLyoqXG4gICAqIEludm9rZWQgdGhlIGZpcnN0IHRpbWUgb2YgdGhlIGVsZW1lbnRzIGlzIHRhcHBlZC5cbiAgICogQ3JlYXRlcyBhIHNpbGVudCBvc2NpbGxhdG9yIHdoZW4gYSBub24tZHJhZ2dpbmcgdG91Y2hlbmRcbiAgICogZXZlbnQgaGFzIGJlZW4gdHJpZ2dlcmVkLlxuICAgKi9cbiAgZnVuY3Rpb24gb25UYXAoKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vc3RhcnQgdGhlIGF1ZGlvIGNvbnRleHQgd2l0aCBhIHNpbGVudCBvc2NpbGxhdG9yXG4gICAgICBpZiAoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dCAmJiAhU3RhcnRBdWRpb0NvbnRleHQuaXNTdGFydGVkKCkpIHtcbiAgICAgICAgdmFyIG9zYyA9IFN0YXJ0QXVkaW9Db250ZXh0LmNvbnRleHQuY3JlYXRlT3NjaWxsYXRvcigpO1xuICAgICAgICB2YXIgc2lsZW50ID0gU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5jcmVhdGVHYWluKCk7XG4gICAgICAgIHNpbGVudC5nYWluLnZhbHVlID0gMDtcbiAgICAgICAgb3NjLmNvbm5lY3Qoc2lsZW50KTtcbiAgICAgICAgc2lsZW50LmNvbm5lY3QoU3RhcnRBdWRpb0NvbnRleHQuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgICAgIHZhciBub3cgPSBTdGFydEF1ZGlvQ29udGV4dC5jb250ZXh0LmN1cnJlbnRUaW1lO1xuICAgICAgICBvc2Muc3RhcnQobm93KTtcbiAgICAgICAgb3NjLnN0b3Aobm93ICsgMC41KTtcbiAgICAgIH1cblxuICAgICAgLy9kaXNwb3NlIGFsbCB0aGUgdGFwIGxpc3RlbmVyc1xuICAgICAgaWYgKFN0YXJ0QXVkaW9Db250ZXh0Ll90YXBMaXN0ZW5lcnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBTdGFydEF1ZGlvQ29udGV4dC5fdGFwTGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVyc1tpXS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgU3RhcnRBdWRpb0NvbnRleHQuX3RhcExpc3RlbmVycyA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIC8vdGhlIG9uc3RhcnRlZCBjYWxsYmFja3NcbiAgICAgIGlmIChTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkKSB7XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgU3RhcnRBdWRpb0NvbnRleHQuX29uU3RhcnRlZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgIFN0YXJ0QXVkaW9Db250ZXh0Ll9vblN0YXJ0ZWRbal0oKTtcbiAgICAgICAgfVxuICAgICAgICBTdGFydEF1ZGlvQ29udGV4dC5fb25TdGFydGVkID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgd2luZG93Ll9fYXVkaW9fY29udGV4dF9zdGFydGVkID0gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy9cbiAgICB9XG4gIH1cblxuICByZXR1cm4gU3RhcnRBdWRpb0NvbnRleHQ7XG59KTtcbiJdLCJuYW1lcyI6WyJ3aW5kb3ciLCJfX2F1ZGlvX2NvbnRleHRfc3RhcnRlZCIsInJvb3QiLCJmYWN0b3J5IiwiZGVmaW5lIiwiYW1kIiwibW9kdWxlIiwiX3R5cGVvZiIsImV4cG9ydHMiLCJTdGFydEF1ZGlvQ29udGV4dCIsImNvbnRleHQiLCJfdGFwTGlzdGVuZXJzIiwiX29uU3RhcnRlZCIsInNldENvbnRleHQiLCJjdHgiLCJvbiIsImVsZW1lbnQiLCJBcnJheSIsImlzQXJyYXkiLCJOb2RlTGlzdCIsImkiLCJsZW5ndGgiLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJqcXVlcnkiLCJ0b0FycmF5IiwiRWxlbWVudCIsInRhcCIsIlRhcExpc3RlbmVyIiwib25UYXAiLCJwdXNoIiwib25TdGFydGVkIiwiY2IiLCJpc1N0YXJ0ZWQiLCJzdGF0ZSIsIl9kcmFnZ2VkIiwiX2VsZW1lbnQiLCJfYmluZGVkTW92ZSIsIl9tb3ZlZCIsImJpbmQiLCJfYmluZGVkRW5kIiwiX2VuZGVkIiwiYWRkRXZlbnRMaXN0ZW5lciIsInByb3RvdHlwZSIsImUiLCJkaXNwb3NlIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIm9zYyIsImNyZWF0ZU9zY2lsbGF0b3IiLCJzaWxlbnQiLCJjcmVhdGVHYWluIiwiZ2FpbiIsInZhbHVlIiwiY29ubmVjdCIsImRlc3RpbmF0aW9uIiwibm93IiwiY3VycmVudFRpbWUiLCJzdGFydCIsInN0b3AiLCJqIiwiZXJyb3IiXSwic291cmNlUm9vdCI6IiJ9\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__(441)})();
\ No newline at end of file |
